From 440ff9500bc74cc278e0b66f528cfdf624547240 Mon Sep 17 00:00:00 2001 From: Dmitry Gamza Date: Mon, 12 May 2014 09:59:24 +0400 Subject: qeditor: on Windows it’s not impossible to create a file with AUX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic7ef01328eccbed4afddb0a09d2afbb6c1f6a28f Reviewed-on: http://gerrit.rockbox.org/811 Reviewed-by: Amaury Pouly --- utils/regtools/qeditor/aux.cpp | 800 ------------------------------- utils/regtools/qeditor/aux.h | 277 ----------- utils/regtools/qeditor/qeditor.pro | 4 +- utils/regtools/qeditor/regdisplaypanel.h | 2 +- utils/regtools/qeditor/regedit.h | 2 +- utils/regtools/qeditor/utils.cpp | 800 +++++++++++++++++++++++++++++++ utils/regtools/qeditor/utils.h | 277 +++++++++++ 7 files changed, 1081 insertions(+), 1081 deletions(-) delete mode 100644 utils/regtools/qeditor/aux.cpp delete mode 100644 utils/regtools/qeditor/aux.h create mode 100644 utils/regtools/qeditor/utils.cpp create mode 100644 utils/regtools/qeditor/utils.h diff --git a/utils/regtools/qeditor/aux.cpp b/utils/regtools/qeditor/aux.cpp deleted file mode 100644 index de45f6c438..0000000000 --- a/utils/regtools/qeditor/aux.cpp +++ /dev/null @@ -1,800 +0,0 @@ -#include "aux.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * SocBitRangeValidator - */ -SocBitRangeValidator::SocBitRangeValidator(QObject *parent) - :QValidator(parent) -{ -} - -void SocBitRangeValidator::fixup(QString& input) const -{ - input = input.trimmed(); -} - -QValidator::State SocBitRangeValidator::validate(QString& input, int& pos) const -{ - Q_UNUSED(pos); - int first, last; - State state = parse(input, last, first); - return state; -} - -QValidator::State SocBitRangeValidator::parse(const QString& input, int& last, int& first) const -{ - // the empty string is always intermediate - if(input.size() == 0) - return Intermediate; - // check if there is ':' - int pos = input.indexOf(':'); - if(pos == -1) - pos = input.size(); - // if field start with ':', the last bit is implicit and is 31 - if(pos > 0) - { - // parse last bit and check it's between 0 and 31 - bool ok = false; - last = input.left(pos).toInt(&ok); - if(!ok || last < 0 || last >= 32) - return Invalid; - } - else - last = 31; - // parse first bit - if(pos < input.size() - 1) - { - bool ok = false; - first = input.mid(pos + 1).toInt(&ok); - if(!ok || first < 0 || first > last) - return Invalid; - } - // if input ends with ':', first bit is implicit and is 0 - else if(pos == input.size() - 1) - first = 0; - // if there no ':', first=last - else - first = last; - return Acceptable; -} - -/** - * SocFieldValidator - */ - -SocFieldValidator::SocFieldValidator(QObject *parent) - :QValidator(parent) -{ - m_field.first_bit = 0; - m_field.last_bit = 31; -} - -SocFieldValidator::SocFieldValidator(const soc_reg_field_t& field, QObject *parent) - :QValidator(parent), m_field(field) -{ -} - -void SocFieldValidator::fixup(QString& input) const -{ - input = input.trimmed(); -} - -QValidator::State SocFieldValidator::validate(QString& input, int& pos) const -{ - Q_UNUSED(pos); - soc_word_t val; - State state = parse(input, val); - return state; -} - -QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val) const -{ - // the empty string is always intermediate - if(input.size() == 0) - return Intermediate; - // first check named values - State state = Invalid; - foreach(const soc_reg_field_value_t& value, m_field.value) - { - QString name = QString::fromLocal8Bit(value.name.c_str()); - // cannot be a substring if too long or empty - if(input.size() > name.size()) - continue; - // check equal string - if(input == name) - { - state = Acceptable; - val = value.value; - break; - } - // check substring - if(name.startsWith(input)) - state = Intermediate; - } - // early return for exact match - if(state == Acceptable) - return state; - // do a few special cases for convenience - if(input.compare("0x", Qt::CaseInsensitive) == 0 || - input.compare("0b", Qt::CaseInsensitive) == 0) - return Intermediate; - // try by parsing - unsigned basis, pos; - if(input.size() >= 2 && input.startsWith("0x", Qt::CaseInsensitive)) - { - basis = 16; - pos = 2; - } - else if(input.size() >= 2 && input.startsWith("0b", Qt::CaseInsensitive)) - { - basis = 2; - pos = 2; - } - else if(input.size() >= 2 && input.startsWith("0")) - { - basis = 8; - pos = 1; - } - else - { - basis = 10; - pos = 0; - } - bool ok = false; - unsigned long v = input.mid(pos).toULong(&ok, basis); - // if not ok, return result of name parsing - if(!ok) - return state; - // if ok, check if it fits in the number of bits - unsigned nr_bits = m_field.last_bit - m_field.first_bit + 1; - unsigned long max = nr_bits == 32 ? 0xffffffff : (1 << nr_bits) - 1; - if(v <= max) - { - val = v; - return Acceptable; - } - - return state; -} - -/** - * RegLineEdit - */ -RegLineEdit::RegLineEdit(QWidget *parent) - :QWidget(parent) -{ - m_layout = new QHBoxLayout(this); - m_button = new QToolButton(this); - m_button->setCursor(Qt::ArrowCursor); - m_button->setStyleSheet("QToolButton { font-weight: bold; color: white; background: black; }"); - m_button->setPopupMode(QToolButton::InstantPopup); - m_edit = new QLineEdit(this); - m_layout->addWidget(m_button); - m_layout->addWidget(m_edit); - m_menu = new QMenu(this); - connect(m_menu->addAction("Write"), SIGNAL(triggered()), this, SLOT(OnWriteAct())); - connect(m_menu->addAction("Set"), SIGNAL(triggered()), this, SLOT(OnSetAct())); - connect(m_menu->addAction("Clear"), SIGNAL(triggered()), this, SLOT(OnClearAct())); - connect(m_menu->addAction("Toggle"), SIGNAL(triggered()), this, SLOT(OnToggleAct())); - EnableSCT(false); - SetReadOnly(false); - ShowMode(true); - SetMode(Write); -} - -void RegLineEdit::SetReadOnly(bool ro) -{ - m_edit->setReadOnly(ro); - m_readonly = ro; - ShowMode(!ro); -} - -void RegLineEdit::EnableSCT(bool en) -{ - m_has_sct = en; - if(!m_has_sct) - { - m_button->setMenu(0); - SetMode(Write); - } - else - m_button->setMenu(m_menu); -} - -RegLineEdit::~RegLineEdit() -{ -} - -QLineEdit *RegLineEdit::GetLineEdit() -{ - return m_edit; -} - -void RegLineEdit::ShowMode(bool show) -{ - if(show) - m_button->show(); - else - m_button->hide(); -} - -void RegLineEdit::OnWriteAct() -{ - SetMode(Write); -} - -void RegLineEdit::OnSetAct() -{ - SetMode(Set); -} - -void RegLineEdit::OnClearAct() -{ - SetMode(Clear); -} - -void RegLineEdit::OnToggleAct() -{ - SetMode(Toggle); -} - -void RegLineEdit::SetMode(EditMode mode) -{ - m_mode = mode; - switch(m_mode) - { - case Write: m_button->setText("WR"); break; - case Set: m_button->setText("SET"); break; - case Clear: m_button->setText("CLR"); break; - case Toggle: m_button->setText("TOG"); break; - default: break; - } -} - -RegLineEdit::EditMode RegLineEdit::GetMode() -{ - return m_mode; -} - -void RegLineEdit::setText(const QString& text) -{ - m_edit->setText(text); -} - -QString RegLineEdit::text() const -{ - return m_edit->text(); -} - -/** - * SocFieldItemDelegate - */ - -QString SocFieldItemDelegate::displayText(const QVariant& value, const QLocale& locale) const -{ - if(value.type() == QVariant::UInt) - return QString("0x%1").arg(value.toUInt(), (m_bitcount + 3) / 4, 16, QChar('0')); - else - return QStyledItemDelegate::displayText(value, locale); -} - -/** - * SocFieldEditor - */ -SocFieldEditor::SocFieldEditor(const soc_reg_field_t& field, QWidget *parent) - :QLineEdit(parent), m_reg_field(field) -{ - m_validator = new SocFieldValidator(field); - setValidator(m_validator); -} - -SocFieldEditor::~SocFieldEditor() -{ - delete m_validator; -} - -uint SocFieldEditor::field() const -{ - soc_word_t v; - /* in case validator fails to parse, return old value */ - if(m_validator->parse(text(), v) == QValidator::Acceptable) - return v; - else - return m_field; -} - -void SocFieldEditor::setField(uint field) -{ - m_field = field; - int digits = (m_reg_field.last_bit - m_reg_field.first_bit + 4) / 4; - setText(QString("0x%1").arg(field, digits, 16, QChar('0'))); -} - -/** - * SocFieldCachedItemDelegate - */ - -QString SocFieldCachedItemDelegate::displayText(const QVariant& value, const QLocale& locale) const -{ - // FIXME see QTBUG-30392 - if(value.type() == QVariant::UserType && value.userType() == qMetaTypeId< SocFieldCachedValue >()) - { - const SocFieldCachedValue& v = value.value< SocFieldCachedValue >(); - int bitcount = v.field().last_bit - v.field().first_bit; - return QString("0x%1").arg(v.value(), (bitcount + 3) / 4, 16, QChar('0')); - } - else - return QStyledItemDelegate::displayText(value, locale); -} - -/** - * SocFieldCachedEditor - */ -SocFieldCachedEditor::SocFieldCachedEditor(QWidget *parent) - :SocFieldEditor(soc_reg_field_t(), parent) -{ -} - -SocFieldCachedEditor::~SocFieldCachedEditor() -{ -} - -SocFieldCachedValue SocFieldCachedEditor::value() const -{ - return SocFieldCachedValue(m_value.field(), field()); -} - -void SocFieldCachedEditor::setValue(SocFieldCachedValue val) -{ - m_value = val; - SetRegField(m_value.field()); - setField(m_value.value()); -} - -/** - * SocFieldEditorCreator - */ -QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const -{ - return new SocFieldEditor(m_field, parent); -} - -QByteArray SocFieldEditorCreator::valuePropertyName() const -{ - return QByteArray("field"); -} - -/** - * SocFieldCachedEditorCreator - */ -QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const -{ - return new SocFieldCachedEditor(parent); -} - -QByteArray SocFieldCachedEditorCreator::valuePropertyName() const -{ - return QByteArray("value"); -} - -/** - * RegSexyDisplay - */ -RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent) - :QWidget(parent), m_reg(reg) -{ - m_size = QSize(); -} - -int RegSexyDisplay::separatorSize() const -{ - return 1; -} - -int RegSexyDisplay::marginSize() const -{ - return fontMetrics().height() / 3; -} - -int RegSexyDisplay::textSep() const -{ - return marginSize() / 2; -} - -int RegSexyDisplay::headerHeight() const -{ - return 2 * marginSize() + textSep() + 2 * fontMetrics().height(); -} - -int RegSexyDisplay::columnWidth() const -{ - return 2 * marginSize() + fontMetrics().height(); -} - -int RegSexyDisplay::maxContentHeight() const -{ - int max = 0; - QFontMetrics metrics = fontMetrics(); - for(size_t i = 0; i < m_reg.GetReg().field.size(); i++) - { - QString s = QString::fromStdString(m_reg.GetReg().field[i].name); - // add extra spaces arounds - s = " " + s + " "; - max = qMax(max, metrics.boundingRect(s).width()); - } - return 2 * marginSize() + max; -} - -int RegSexyDisplay::gapHeight() const -{ - return marginSize() / 2; -} - -QSize RegSexyDisplay::minimumSizeHint() const -{ - /* cache computation because it's expensive */ - if(m_size.isValid()) - return m_size; - /* width: display 32 columns + 33 vertical separators */ - m_size.setWidth(32 * columnWidth() + 33 * separatorSize()); - /* height: one separator + two digits + one separator + margin + separator - * + names + separator */ - m_size.setHeight(4 * separatorSize() + headerHeight() + gapHeight() + maxContentHeight()); - return m_size; -} - -QSize RegSexyDisplay::sizeHint() const -{ - return minimumSizeHint(); -} - -void RegSexyDisplay::paintEvent(QPaintEvent *event) -{ - // FIXME could be optimised with QStaticText - Q_UNUSED(event); - int txt_h = fontMetrics().height(); - int sep_sz = separatorSize(); - int w = width(); - int h = height() - 1; - int col_w = (w - 33 * sep_sz) / 32; - int hdr_h = headerHeight(); - int gap_h = gapHeight(); - int tot_w = 33 * sep_sz + 32 * col_w; - int margin = marginSize(); - int txt_sep = textSep(); - int tot_hdr_sz = 2 * sep_sz + hdr_h; - // computer xshift - int x_shift = (w - tot_w) / 2; -#define ith_col_x(i) (x_shift + (i) * (sep_sz + col_w)) - - QPainter painter(this); - QBrush back_brush = palette().base(); - QBrush line_brush = palette().dark(); - - // fill interesting zone with base - painter.fillRect(x_shift, 0, tot_w, h, back_brush); - - // draw top and bottom lines - painter.setPen(QPen(palette().dark(), sep_sz)); - painter.fillRect(x_shift, 0, tot_w, sep_sz, line_brush); - painter.fillRect(x_shift, h - sep_sz, tot_w, sep_sz, line_brush); - // draw intemediate lines - for(int i = 0; i <= 32; i++) - painter.fillRect(ith_col_x(i), 0, sep_sz, 2 * sep_sz + hdr_h, line_brush); - // draw bottom header lines - painter.fillRect(ith_col_x(0), sep_sz + hdr_h, tot_w, sep_sz, line_brush); - painter.fillRect(ith_col_x(0), tot_hdr_sz + gap_h, tot_w, sep_sz, line_brush); - // redraw some lines but wider - for(int i = 4; i < 32; i += 4) - painter.fillRect(ith_col_x(i) - sep_sz, 0, 3 * sep_sz, tot_hdr_sz, line_brush); - // draw numbers in the header - painter.setPen(palette().brush(QPalette::ButtonText).color()); - for(int i = 0; i < 32; i++) - { - QRect r(ith_col_x(i), sep_sz + margin, col_w, txt_h); - painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) / 10)); - r.translate(0, txt_h + txt_sep); - painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) % 10)); - } - // display content - for(size_t i = 0; i < m_reg.GetReg().field.size(); i++) - { - const soc_reg_field_t& field = m_reg.GetReg().field[i]; - QRect r(QPoint(ith_col_x(31 - field.last_bit) + sep_sz, tot_hdr_sz), - QPoint(ith_col_x(32 - field.first_bit), h - sep_sz)); - painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush); - painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush); - r.setY(r.y() + gap_h + sep_sz); - // draw rotated text - painter.save(); - painter.translate(r.bottomLeft()); - painter.rotate(-90); - //painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red)); - QRect r2(0, 0, r.height(), r.width()); - painter.drawText(r2, Qt::AlignCenter, QString::fromStdString(field.name)); - painter.restore(); - } -#undef ith_col_x -} - -/** - * GrowingTextEdit - */ -GrowingTextEdit::GrowingTextEdit(QWidget *parent) - :QTextEdit(parent) -{ - connect(this, SIGNAL(textChanged()), this, SLOT(TextChanged())); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -} - -void GrowingTextEdit::TextChanged() -{ - int content_size = document()->documentLayout()->documentSize().height(); - content_size = qMax(content_size, fontMetrics().height()); - setFixedHeight(content_size + contentsMargins().top() + contentsMargins().bottom()); -} - -/** - * GrowingTableWidget - */ -GrowingTableWidget::GrowingTableWidget(QWidget *parent) - :QTableWidget(parent) -{ - connect(model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(DataChanged(const QModelIndex&, const QModelIndex&))); -} - -void GrowingTableWidget::DataChanged(const QModelIndex& tl, const QModelIndex& br) -{ - Q_UNUSED(tl); - Q_UNUSED(br); - resizeRowsToContents(); - resizeColumnsToContents(); - int h = contentsMargins().top() + contentsMargins().bottom(); - h += horizontalHeader()->height(); - for(int i = 0; i < rowCount(); i++) - h += rowHeight(i); - setMinimumHeight(h); -} - -/** - * MyTextEditor - */ -MyTextEditor::MyTextEditor(QWidget *parent) - :QWidget(parent) -{ - QVBoxLayout *layout = new QVBoxLayout; - m_toolbar = new QToolBar(this); - m_edit = new QTextEdit(this); - layout->addWidget(m_toolbar, 0); - layout->addWidget(m_edit, 1); - setLayout(layout); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - m_edit->setAcceptRichText(false); - m_edit->setAutoFormatting(QTextEdit::AutoAll); - - m_bold_button = new QToolButton(this); - m_bold_button->setIcon(QIcon::fromTheme("format-text-bold")); - m_bold_button->setText("bold"); - m_bold_button->setCheckable(true); - - m_italic_button = new QToolButton(this); - m_italic_button->setIcon(QIcon::fromTheme("format-text-italic")); - m_italic_button->setText("italic"); - m_italic_button->setCheckable(true); - - m_underline_button = new QToolButton(this); - m_underline_button->setIcon(QIcon::fromTheme("format-text-underline")); - m_underline_button->setText("underline"); - m_underline_button->setCheckable(true); - - m_toolbar->addWidget(m_bold_button); - m_toolbar->addWidget(m_italic_button); - m_toolbar->addWidget(m_underline_button); - - connect(m_bold_button, SIGNAL(toggled(bool)), this, SLOT(OnTextBold(bool))); - connect(m_italic_button, SIGNAL(toggled(bool)), this, SLOT(OnTextItalic(bool))); - connect(m_underline_button, SIGNAL(toggled(bool)), this, SLOT(OnTextUnderline(bool))); - connect(m_edit, SIGNAL(textChanged()), this, SLOT(OnInternalTextChanged())); - connect(m_edit, SIGNAL(currentCharFormatChanged(const QTextCharFormat&)), - this, SLOT(OnCharFormatChanged(const QTextCharFormat&))); - - SetGrowingMode(false); - SetReadOnly(false); -} - -void MyTextEditor::SetReadOnly(bool en) -{ - m_read_only = en; - if(en) - m_toolbar->hide(); - else - m_toolbar->hide(); - m_edit->setReadOnly(en); -} - -void MyTextEditor::SetGrowingMode(bool en) -{ - m_growing_mode = en; - if(en) - { - m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - m_edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - OnTextChanged(); - } - else - { - m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - m_edit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - } -} - -void MyTextEditor::OnInternalTextChanged() -{ - if(m_growing_mode) - { - int content_size = m_edit->document()->documentLayout()->documentSize().height(); - content_size = qMax(content_size, m_edit->fontMetrics().height()); - m_edit->setMinimumHeight(content_size + m_edit->contentsMargins().top() + - m_edit->contentsMargins().bottom()); - } - emit OnTextChanged(); -} - -void MyTextEditor::OnTextBold(bool checked) -{ - QTextCursor cursor = m_edit->textCursor(); - QTextCharFormat fmt = cursor.charFormat(); - fmt.setFontWeight(checked ? QFont::Bold : QFont::Normal); - cursor.setCharFormat(fmt); - m_edit->setTextCursor(cursor); -} - -void MyTextEditor::OnTextItalic(bool checked) -{ - QTextCursor cursor = m_edit->textCursor(); - QTextCharFormat fmt = cursor.charFormat(); - fmt.setFontItalic(checked); - cursor.setCharFormat(fmt); - m_edit->setTextCursor(cursor); -} - -void MyTextEditor::OnTextUnderline(bool checked) -{ - QTextCursor cursor = m_edit->textCursor(); - QTextCharFormat fmt = cursor.charFormat(); - fmt.setFontUnderline(checked); - cursor.setCharFormat(fmt); - m_edit->setTextCursor(cursor); -} - -void MyTextEditor::OnCharFormatChanged(const QTextCharFormat& fmt) -{ - /* NOTE: changing the button states programmaticaly doesn't trigger - * the toggled() signals, otherwise it would result in a loop - * between this function and OnText{Bold,Italic,Underline,...} */ - m_bold_button->setChecked(fmt.fontWeight() > QFont::Normal); - m_italic_button->setChecked(fmt.fontItalic()); - m_underline_button->setChecked(fmt.fontUnderline()); -} - -void MyTextEditor::SetTextHtml(const QString& text) -{ - m_edit->setHtml(text); -} - -QString MyTextEditor::GetTextHtml() -{ - return m_edit->toPlainText(); -} - -bool MyTextEditor::IsModified() -{ - return m_edit->document()->isModified(); -} - -/** - * MySwitchableTextEditor - */ -MySwitchableTextEditor::MySwitchableTextEditor(QWidget *parent) - :QWidget(parent) -{ - QVBoxLayout *layout = new QVBoxLayout(this); - m_edit = new MyTextEditor(this); - m_label = new QLabel(this); - m_label->setTextFormat(Qt::RichText); - m_label->setAlignment(Qt::AlignTop); - m_line = new QLineEdit(this); - - layout->addWidget(m_label); - layout->addWidget(m_edit); - layout->addWidget(m_line); - - setLayout(layout); - - m_editor_mode = false; - m_line_mode = false; - UpdateVisibility(); -} - -void MySwitchableTextEditor::SetEditorMode(bool edit) -{ - if(edit == m_editor_mode) - return; - QString text = GetTextHtml(); - m_editor_mode = edit; - UpdateVisibility(); - SetTextHtml(text); -} - -QString MySwitchableTextEditor::GetTextHtml() -{ - if(m_editor_mode) - return m_line_mode ? m_line->text() : m_edit->GetTextHtml(); - else - return m_label->text(); -} - -void MySwitchableTextEditor::SetTextHtml(const QString& text) -{ - if(m_editor_mode) - { - if(m_line_mode) - m_line->setText(text); - else - m_edit->SetTextHtml(text); - } - else - m_label->setText(text); -} - -MyTextEditor *MySwitchableTextEditor::GetEditor() -{ - return m_edit; -} - -void MySwitchableTextEditor::SetLineMode(bool en) -{ - if(m_line_mode == en) - return; - QString text = GetTextHtml(); - m_line_mode = en; - SetTextHtml(text); - UpdateVisibility(); -} - -QLineEdit *MySwitchableTextEditor::GetLineEdit() -{ - return m_line; -} - -void MySwitchableTextEditor::UpdateVisibility() -{ - m_label->setVisible(!m_editor_mode); - m_edit->setVisible(m_editor_mode && !m_line_mode); - m_line->setVisible(m_editor_mode && m_line_mode); -} - -QLabel *MySwitchableTextEditor::GetLabel() -{ - return m_label; -} - -bool MySwitchableTextEditor::IsModified() -{ - if(!m_editor_mode) - return false; - return m_line_mode ? m_line->isModified() : m_edit->IsModified(); -} diff --git a/utils/regtools/qeditor/aux.h b/utils/regtools/qeditor/aux.h deleted file mode 100644 index ee08f1f31b..0000000000 --- a/utils/regtools/qeditor/aux.h +++ /dev/null @@ -1,277 +0,0 @@ -#ifndef AUX_H -#define AUX_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "backend.h" - -class SocBitRangeValidator : public QValidator -{ - Q_OBJECT -public: - SocBitRangeValidator(QObject *parent = 0); - - virtual void fixup(QString& input) const; - virtual State validate(QString& input, int& pos) const; - /* validate and return the interpreted value */ - State parse(const QString& input, int& last_bit, int& first_bit) const; -}; - -class SocFieldValidator : public QValidator -{ - Q_OBJECT -public: - SocFieldValidator(QObject *parent = 0); - SocFieldValidator(const soc_reg_field_t& field, QObject *parent = 0); - - virtual void fixup(QString& input) const; - virtual State validate(QString& input, int& pos) const; - /* validate and return the interpreted value */ - State parse(const QString& input, soc_word_t& val) const; - -protected: - soc_reg_field_t m_field; -}; - -class RegLineEdit : public QWidget -{ - Q_OBJECT -public: - enum EditMode - { - Write, Set, Clear, Toggle - }; - - RegLineEdit(QWidget *parent = 0); - ~RegLineEdit(); - void SetReadOnly(bool ro); - void EnableSCT(bool en); - void SetMode(EditMode mode); - EditMode GetMode(); - QLineEdit *GetLineEdit(); - void setText(const QString& text); - QString text() const; - - Q_PROPERTY(QString text READ text WRITE setText USER true) - -protected slots: - void OnWriteAct(); - void OnSetAct(); - void OnClearAct(); - void OnToggleAct(); -protected: - void ShowMode(bool show); - void DoAutoHide(); - - QHBoxLayout *m_layout; - QToolButton *m_button; - QLineEdit *m_edit; - EditMode m_mode; - bool m_has_sct; - bool m_readonly; - QMenu *m_menu; -}; - -class SocFieldItemDelegate : public QStyledItemDelegate -{ -public: - SocFieldItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent), m_bitcount(32) {} - SocFieldItemDelegate(const soc_reg_field_t& field, QObject *parent = 0) - :QStyledItemDelegate(parent), m_bitcount(field.last_bit - field.first_bit + 1) {} - - virtual QString displayText(const QVariant& value, const QLocale& locale) const; -protected: - int m_bitcount; -}; - -class SocFieldEditor : public QLineEdit -{ - Q_OBJECT - Q_PROPERTY(uint field READ field WRITE setField USER true) -public: - SocFieldEditor(const soc_reg_field_t& field, QWidget *parent = 0); - virtual ~SocFieldEditor(); - - uint field() const; - void setField(uint field); - void SetRegField(const soc_reg_field_t& field) { m_reg_field = field; } - -protected: - SocFieldValidator *m_validator; - uint m_field; - soc_reg_field_t m_reg_field; -}; - -class SocFieldEditorCreator : public QItemEditorCreatorBase -{ -public: - SocFieldEditorCreator() { m_field.first_bit = 0; m_field.last_bit = 31; } - SocFieldEditorCreator(const soc_reg_field_t& field):m_field(field) {} - - virtual QWidget *createWidget(QWidget *parent) const; - virtual QByteArray valuePropertyName() const; - -protected: - soc_reg_field_t m_field; -}; - -class SocFieldCachedValue -{ -public: - SocFieldCachedValue():m_value(0) {} - SocFieldCachedValue(const soc_reg_field_t& field, uint value) - :m_field(field), m_value(value) {} - virtual ~SocFieldCachedValue() {} - const soc_reg_field_t& field() const { return m_field; } - uint value() const { return m_value; } -protected: - soc_reg_field_t m_field; - uint m_value; -}; - -Q_DECLARE_METATYPE(SocFieldCachedValue) - -class SocFieldCachedItemDelegate : public QStyledItemDelegate -{ -public: - SocFieldCachedItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent) {} - - virtual QString displayText(const QVariant& value, const QLocale& locale) const; -}; - -class SocFieldCachedEditor : public SocFieldEditor -{ - Q_OBJECT - Q_PROPERTY(SocFieldCachedValue value READ value WRITE setValue USER true) -public: - SocFieldCachedEditor(QWidget *parent = 0); - virtual ~SocFieldCachedEditor(); - - SocFieldCachedValue value() const; - void setValue(SocFieldCachedValue field); -protected: - SocFieldCachedValue m_value; -}; - -class SocFieldCachedEditorCreator : public QItemEditorCreatorBase -{ -public: - SocFieldCachedEditorCreator() {} - - virtual QWidget *createWidget(QWidget *parent) const; - virtual QByteArray valuePropertyName() const; - -protected: -}; - -class RegSexyDisplay : public QWidget -{ - Q_OBJECT -public: - RegSexyDisplay(const SocRegRef& reg, QWidget *parent = 0); - - QSize minimumSizeHint() const; - QSize sizeHint() const; - -protected: - int marginSize() const; - int separatorSize() const; - int columnWidth() const; - int headerHeight() const; - int gapHeight() const; - int maxContentHeight() const; - int textSep() const; - void paintEvent(QPaintEvent *event); - -private: - SocRegRef m_reg; - mutable QSize m_size; -}; - -class GrowingTextEdit : public QTextEdit -{ - Q_OBJECT -public: - GrowingTextEdit(QWidget *parent = 0); - -protected slots: - void TextChanged(); -}; - -class GrowingTableWidget : public QTableWidget -{ - Q_OBJECT -public: - GrowingTableWidget(QWidget *parent = 0); - -protected slots: - void DataChanged(const QModelIndex& tl, const QModelIndex& br); -}; - -class MyTextEditor : public QWidget -{ - Q_OBJECT -public: - MyTextEditor(QWidget *parent = 0); - void SetGrowingMode(bool en); - void SetReadOnly(bool ro); - void SetTextHtml(const QString& text); - QString GetTextHtml(); - bool IsModified(); -signals: - void OnTextChanged(); - -protected slots: - void OnInternalTextChanged(); - void OnTextBold(bool checked); - void OnTextItalic(bool checked); - void OnTextUnderline(bool checked); - void OnCharFormatChanged(const QTextCharFormat& fmt); - -protected: - bool m_growing_mode; - bool m_read_only; - QToolBar *m_toolbar; - QTextEdit *m_edit; - QToolButton *m_bold_button; - QToolButton *m_italic_button; - QToolButton *m_underline_button; -}; - -class MySwitchableTextEditor : public QWidget -{ - Q_OBJECT -public: - MySwitchableTextEditor(QWidget *parent = 0); - QString GetTextHtml(); - void SetTextHtml(const QString& text); - void SetEditorMode(bool en); - MyTextEditor *GetEditor(); - QLineEdit *GetLineEdit(); - QLabel *GetLabel(); - void SetLineMode(bool en); - bool IsModified(); - -protected: - void UpdateVisibility(); - - bool m_editor_mode; - bool m_line_mode; - QLabel *m_label; - MyTextEditor *m_edit; - QLineEdit *m_line; -}; - -#endif /* AUX_H */ diff --git a/utils/regtools/qeditor/qeditor.pro b/utils/regtools/qeditor/qeditor.pro index 279b3532c0..3cf0148971 100644 --- a/utils/regtools/qeditor/qeditor.pro +++ b/utils/regtools/qeditor/qeditor.pro @@ -1,9 +1,9 @@ QT += widgets HEADERS += mainwindow.h backend.h regtab.h analyser.h settings.h \ - std_analysers.h aux.h regdisplaypanel.h regedit.h + std_analysers.h utils.h regdisplaypanel.h regedit.h SOURCES += main.cpp mainwindow.cpp regtab.cpp backend.cpp analyser.cpp \ - std_analysers.cpp settings.cpp aux.cpp regdisplaypanel.cpp regedit.cpp + std_analysers.cpp settings.cpp utils.cpp regdisplaypanel.cpp regedit.cpp LIBS += -L../lib/ -lsocdesc -lxml2 INCLUDEPATH += ../lib/ ../../hwstub/lib diff --git a/utils/regtools/qeditor/regdisplaypanel.h b/utils/regtools/qeditor/regdisplaypanel.h index b8b9729887..a000fa5611 100644 --- a/utils/regtools/qeditor/regdisplaypanel.h +++ b/utils/regtools/qeditor/regdisplaypanel.h @@ -12,7 +12,7 @@ #include #include "backend.h" #include "settings.h" -#include "aux.h" +#include "utils.h" #include "regtab.h" class RegItemEditorCreator : public QItemEditorCreatorBase diff --git a/utils/regtools/qeditor/regedit.h b/utils/regtools/qeditor/regedit.h index b5ccd249fa..cec92d7c03 100644 --- a/utils/regtools/qeditor/regedit.h +++ b/utils/regtools/qeditor/regedit.h @@ -21,7 +21,7 @@ #include "backend.h" #include "settings.h" #include "mainwindow.h" -#include "aux.h" +#include "utils.h" class AbstractRegEditPanel { diff --git a/utils/regtools/qeditor/utils.cpp b/utils/regtools/qeditor/utils.cpp new file mode 100644 index 0000000000..1662169bdb --- /dev/null +++ b/utils/regtools/qeditor/utils.cpp @@ -0,0 +1,800 @@ +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * SocBitRangeValidator + */ +SocBitRangeValidator::SocBitRangeValidator(QObject *parent) + :QValidator(parent) +{ +} + +void SocBitRangeValidator::fixup(QString& input) const +{ + input = input.trimmed(); +} + +QValidator::State SocBitRangeValidator::validate(QString& input, int& pos) const +{ + Q_UNUSED(pos); + int first, last; + State state = parse(input, last, first); + return state; +} + +QValidator::State SocBitRangeValidator::parse(const QString& input, int& last, int& first) const +{ + // the empty string is always intermediate + if(input.size() == 0) + return Intermediate; + // check if there is ':' + int pos = input.indexOf(':'); + if(pos == -1) + pos = input.size(); + // if field start with ':', the last bit is implicit and is 31 + if(pos > 0) + { + // parse last bit and check it's between 0 and 31 + bool ok = false; + last = input.left(pos).toInt(&ok); + if(!ok || last < 0 || last >= 32) + return Invalid; + } + else + last = 31; + // parse first bit + if(pos < input.size() - 1) + { + bool ok = false; + first = input.mid(pos + 1).toInt(&ok); + if(!ok || first < 0 || first > last) + return Invalid; + } + // if input ends with ':', first bit is implicit and is 0 + else if(pos == input.size() - 1) + first = 0; + // if there no ':', first=last + else + first = last; + return Acceptable; +} + +/** + * SocFieldValidator + */ + +SocFieldValidator::SocFieldValidator(QObject *parent) + :QValidator(parent) +{ + m_field.first_bit = 0; + m_field.last_bit = 31; +} + +SocFieldValidator::SocFieldValidator(const soc_reg_field_t& field, QObject *parent) + :QValidator(parent), m_field(field) +{ +} + +void SocFieldValidator::fixup(QString& input) const +{ + input = input.trimmed(); +} + +QValidator::State SocFieldValidator::validate(QString& input, int& pos) const +{ + Q_UNUSED(pos); + soc_word_t val; + State state = parse(input, val); + return state; +} + +QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val) const +{ + // the empty string is always intermediate + if(input.size() == 0) + return Intermediate; + // first check named values + State state = Invalid; + foreach(const soc_reg_field_value_t& value, m_field.value) + { + QString name = QString::fromLocal8Bit(value.name.c_str()); + // cannot be a substring if too long or empty + if(input.size() > name.size()) + continue; + // check equal string + if(input == name) + { + state = Acceptable; + val = value.value; + break; + } + // check substring + if(name.startsWith(input)) + state = Intermediate; + } + // early return for exact match + if(state == Acceptable) + return state; + // do a few special cases for convenience + if(input.compare("0x", Qt::CaseInsensitive) == 0 || + input.compare("0b", Qt::CaseInsensitive) == 0) + return Intermediate; + // try by parsing + unsigned basis, pos; + if(input.size() >= 2 && input.startsWith("0x", Qt::CaseInsensitive)) + { + basis = 16; + pos = 2; + } + else if(input.size() >= 2 && input.startsWith("0b", Qt::CaseInsensitive)) + { + basis = 2; + pos = 2; + } + else if(input.size() >= 2 && input.startsWith("0")) + { + basis = 8; + pos = 1; + } + else + { + basis = 10; + pos = 0; + } + bool ok = false; + unsigned long v = input.mid(pos).toULong(&ok, basis); + // if not ok, return result of name parsing + if(!ok) + return state; + // if ok, check if it fits in the number of bits + unsigned nr_bits = m_field.last_bit - m_field.first_bit + 1; + unsigned long max = nr_bits == 32 ? 0xffffffff : (1 << nr_bits) - 1; + if(v <= max) + { + val = v; + return Acceptable; + } + + return state; +} + +/** + * RegLineEdit + */ +RegLineEdit::RegLineEdit(QWidget *parent) + :QWidget(parent) +{ + m_layout = new QHBoxLayout(this); + m_button = new QToolButton(this); + m_button->setCursor(Qt::ArrowCursor); + m_button->setStyleSheet("QToolButton { font-weight: bold; color: white; background: black; }"); + m_button->setPopupMode(QToolButton::InstantPopup); + m_edit = new QLineEdit(this); + m_layout->addWidget(m_button); + m_layout->addWidget(m_edit); + m_menu = new QMenu(this); + connect(m_menu->addAction("Write"), SIGNAL(triggered()), this, SLOT(OnWriteAct())); + connect(m_menu->addAction("Set"), SIGNAL(triggered()), this, SLOT(OnSetAct())); + connect(m_menu->addAction("Clear"), SIGNAL(triggered()), this, SLOT(OnClearAct())); + connect(m_menu->addAction("Toggle"), SIGNAL(triggered()), this, SLOT(OnToggleAct())); + EnableSCT(false); + SetReadOnly(false); + ShowMode(true); + SetMode(Write); +} + +void RegLineEdit::SetReadOnly(bool ro) +{ + m_edit->setReadOnly(ro); + m_readonly = ro; + ShowMode(!ro); +} + +void RegLineEdit::EnableSCT(bool en) +{ + m_has_sct = en; + if(!m_has_sct) + { + m_button->setMenu(0); + SetMode(Write); + } + else + m_button->setMenu(m_menu); +} + +RegLineEdit::~RegLineEdit() +{ +} + +QLineEdit *RegLineEdit::GetLineEdit() +{ + return m_edit; +} + +void RegLineEdit::ShowMode(bool show) +{ + if(show) + m_button->show(); + else + m_button->hide(); +} + +void RegLineEdit::OnWriteAct() +{ + SetMode(Write); +} + +void RegLineEdit::OnSetAct() +{ + SetMode(Set); +} + +void RegLineEdit::OnClearAct() +{ + SetMode(Clear); +} + +void RegLineEdit::OnToggleAct() +{ + SetMode(Toggle); +} + +void RegLineEdit::SetMode(EditMode mode) +{ + m_mode = mode; + switch(m_mode) + { + case Write: m_button->setText("WR"); break; + case Set: m_button->setText("SET"); break; + case Clear: m_button->setText("CLR"); break; + case Toggle: m_button->setText("TOG"); break; + default: break; + } +} + +RegLineEdit::EditMode RegLineEdit::GetMode() +{ + return m_mode; +} + +void RegLineEdit::setText(const QString& text) +{ + m_edit->setText(text); +} + +QString RegLineEdit::text() const +{ + return m_edit->text(); +} + +/** + * SocFieldItemDelegate + */ + +QString SocFieldItemDelegate::displayText(const QVariant& value, const QLocale& locale) const +{ + if(value.type() == QVariant::UInt) + return QString("0x%1").arg(value.toUInt(), (m_bitcount + 3) / 4, 16, QChar('0')); + else + return QStyledItemDelegate::displayText(value, locale); +} + +/** + * SocFieldEditor + */ +SocFieldEditor::SocFieldEditor(const soc_reg_field_t& field, QWidget *parent) + :QLineEdit(parent), m_reg_field(field) +{ + m_validator = new SocFieldValidator(field); + setValidator(m_validator); +} + +SocFieldEditor::~SocFieldEditor() +{ + delete m_validator; +} + +uint SocFieldEditor::field() const +{ + soc_word_t v; + /* in case validator fails to parse, return old value */ + if(m_validator->parse(text(), v) == QValidator::Acceptable) + return v; + else + return m_field; +} + +void SocFieldEditor::setField(uint field) +{ + m_field = field; + int digits = (m_reg_field.last_bit - m_reg_field.first_bit + 4) / 4; + setText(QString("0x%1").arg(field, digits, 16, QChar('0'))); +} + +/** + * SocFieldCachedItemDelegate + */ + +QString SocFieldCachedItemDelegate::displayText(const QVariant& value, const QLocale& locale) const +{ + // FIXME see QTBUG-30392 + if(value.type() == QVariant::UserType && value.userType() == qMetaTypeId< SocFieldCachedValue >()) + { + const SocFieldCachedValue& v = value.value< SocFieldCachedValue >(); + int bitcount = v.field().last_bit - v.field().first_bit; + return QString("0x%1").arg(v.value(), (bitcount + 3) / 4, 16, QChar('0')); + } + else + return QStyledItemDelegate::displayText(value, locale); +} + +/** + * SocFieldCachedEditor + */ +SocFieldCachedEditor::SocFieldCachedEditor(QWidget *parent) + :SocFieldEditor(soc_reg_field_t(), parent) +{ +} + +SocFieldCachedEditor::~SocFieldCachedEditor() +{ +} + +SocFieldCachedValue SocFieldCachedEditor::value() const +{ + return SocFieldCachedValue(m_value.field(), field()); +} + +void SocFieldCachedEditor::setValue(SocFieldCachedValue val) +{ + m_value = val; + SetRegField(m_value.field()); + setField(m_value.value()); +} + +/** + * SocFieldEditorCreator + */ +QWidget *SocFieldEditorCreator::createWidget(QWidget *parent) const +{ + return new SocFieldEditor(m_field, parent); +} + +QByteArray SocFieldEditorCreator::valuePropertyName() const +{ + return QByteArray("field"); +} + +/** + * SocFieldCachedEditorCreator + */ +QWidget *SocFieldCachedEditorCreator::createWidget(QWidget *parent) const +{ + return new SocFieldCachedEditor(parent); +} + +QByteArray SocFieldCachedEditorCreator::valuePropertyName() const +{ + return QByteArray("value"); +} + +/** + * RegSexyDisplay + */ +RegSexyDisplay::RegSexyDisplay(const SocRegRef& reg, QWidget *parent) + :QWidget(parent), m_reg(reg) +{ + m_size = QSize(); +} + +int RegSexyDisplay::separatorSize() const +{ + return 1; +} + +int RegSexyDisplay::marginSize() const +{ + return fontMetrics().height() / 3; +} + +int RegSexyDisplay::textSep() const +{ + return marginSize() / 2; +} + +int RegSexyDisplay::headerHeight() const +{ + return 2 * marginSize() + textSep() + 2 * fontMetrics().height(); +} + +int RegSexyDisplay::columnWidth() const +{ + return 2 * marginSize() + fontMetrics().height(); +} + +int RegSexyDisplay::maxContentHeight() const +{ + int max = 0; + QFontMetrics metrics = fontMetrics(); + for(size_t i = 0; i < m_reg.GetReg().field.size(); i++) + { + QString s = QString::fromStdString(m_reg.GetReg().field[i].name); + // add extra spaces arounds + s = " " + s + " "; + max = qMax(max, metrics.boundingRect(s).width()); + } + return 2 * marginSize() + max; +} + +int RegSexyDisplay::gapHeight() const +{ + return marginSize() / 2; +} + +QSize RegSexyDisplay::minimumSizeHint() const +{ + /* cache computation because it's expensive */ + if(m_size.isValid()) + return m_size; + /* width: display 32 columns + 33 vertical separators */ + m_size.setWidth(32 * columnWidth() + 33 * separatorSize()); + /* height: one separator + two digits + one separator + margin + separator + * + names + separator */ + m_size.setHeight(4 * separatorSize() + headerHeight() + gapHeight() + maxContentHeight()); + return m_size; +} + +QSize RegSexyDisplay::sizeHint() const +{ + return minimumSizeHint(); +} + +void RegSexyDisplay::paintEvent(QPaintEvent *event) +{ + // FIXME could be optimised with QStaticText + Q_UNUSED(event); + int txt_h = fontMetrics().height(); + int sep_sz = separatorSize(); + int w = width(); + int h = height() - 1; + int col_w = (w - 33 * sep_sz) / 32; + int hdr_h = headerHeight(); + int gap_h = gapHeight(); + int tot_w = 33 * sep_sz + 32 * col_w; + int margin = marginSize(); + int txt_sep = textSep(); + int tot_hdr_sz = 2 * sep_sz + hdr_h; + // computer xshift + int x_shift = (w - tot_w) / 2; +#define ith_col_x(i) (x_shift + (i) * (sep_sz + col_w)) + + QPainter painter(this); + QBrush back_brush = palette().base(); + QBrush line_brush = palette().dark(); + + // fill interesting zone with base + painter.fillRect(x_shift, 0, tot_w, h, back_brush); + + // draw top and bottom lines + painter.setPen(QPen(palette().dark(), sep_sz)); + painter.fillRect(x_shift, 0, tot_w, sep_sz, line_brush); + painter.fillRect(x_shift, h - sep_sz, tot_w, sep_sz, line_brush); + // draw intemediate lines + for(int i = 0; i <= 32; i++) + painter.fillRect(ith_col_x(i), 0, sep_sz, 2 * sep_sz + hdr_h, line_brush); + // draw bottom header lines + painter.fillRect(ith_col_x(0), sep_sz + hdr_h, tot_w, sep_sz, line_brush); + painter.fillRect(ith_col_x(0), tot_hdr_sz + gap_h, tot_w, sep_sz, line_brush); + // redraw some lines but wider + for(int i = 4; i < 32; i += 4) + painter.fillRect(ith_col_x(i) - sep_sz, 0, 3 * sep_sz, tot_hdr_sz, line_brush); + // draw numbers in the header + painter.setPen(palette().brush(QPalette::ButtonText).color()); + for(int i = 0; i < 32; i++) + { + QRect r(ith_col_x(i), sep_sz + margin, col_w, txt_h); + painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) / 10)); + r.translate(0, txt_h + txt_sep); + painter.drawText(r, Qt::AlignCenter, QString("%1").arg((31 - i) % 10)); + } + // display content + for(size_t i = 0; i < m_reg.GetReg().field.size(); i++) + { + const soc_reg_field_t& field = m_reg.GetReg().field[i]; + QRect r(QPoint(ith_col_x(31 - field.last_bit) + sep_sz, tot_hdr_sz), + QPoint(ith_col_x(32 - field.first_bit), h - sep_sz)); + painter.fillRect(r.x() - sep_sz, r.y(), sep_sz, r.height(), line_brush); + painter.fillRect(r.right(), r.y(), sep_sz, r.height(), line_brush); + r.setY(r.y() + gap_h + sep_sz); + // draw rotated text + painter.save(); + painter.translate(r.bottomLeft()); + painter.rotate(-90); + //painter.fillRect(QRect(0, 0, r.height(), r.width()), QBrush(Qt::red)); + QRect r2(0, 0, r.height(), r.width()); + painter.drawText(r2, Qt::AlignCenter, QString::fromStdString(field.name)); + painter.restore(); + } +#undef ith_col_x +} + +/** + * GrowingTextEdit + */ +GrowingTextEdit::GrowingTextEdit(QWidget *parent) + :QTextEdit(parent) +{ + connect(this, SIGNAL(textChanged()), this, SLOT(TextChanged())); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +} + +void GrowingTextEdit::TextChanged() +{ + int content_size = document()->documentLayout()->documentSize().height(); + content_size = qMax(content_size, fontMetrics().height()); + setFixedHeight(content_size + contentsMargins().top() + contentsMargins().bottom()); +} + +/** + * GrowingTableWidget + */ +GrowingTableWidget::GrowingTableWidget(QWidget *parent) + :QTableWidget(parent) +{ + connect(model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), + this, SLOT(DataChanged(const QModelIndex&, const QModelIndex&))); +} + +void GrowingTableWidget::DataChanged(const QModelIndex& tl, const QModelIndex& br) +{ + Q_UNUSED(tl); + Q_UNUSED(br); + resizeRowsToContents(); + resizeColumnsToContents(); + int h = contentsMargins().top() + contentsMargins().bottom(); + h += horizontalHeader()->height(); + for(int i = 0; i < rowCount(); i++) + h += rowHeight(i); + setMinimumHeight(h); +} + +/** + * MyTextEditor + */ +MyTextEditor::MyTextEditor(QWidget *parent) + :QWidget(parent) +{ + QVBoxLayout *layout = new QVBoxLayout; + m_toolbar = new QToolBar(this); + m_edit = new QTextEdit(this); + layout->addWidget(m_toolbar, 0); + layout->addWidget(m_edit, 1); + setLayout(layout); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + m_edit->setAcceptRichText(false); + m_edit->setAutoFormatting(QTextEdit::AutoAll); + + m_bold_button = new QToolButton(this); + m_bold_button->setIcon(QIcon::fromTheme("format-text-bold")); + m_bold_button->setText("bold"); + m_bold_button->setCheckable(true); + + m_italic_button = new QToolButton(this); + m_italic_button->setIcon(QIcon::fromTheme("format-text-italic")); + m_italic_button->setText("italic"); + m_italic_button->setCheckable(true); + + m_underline_button = new QToolButton(this); + m_underline_button->setIcon(QIcon::fromTheme("format-text-underline")); + m_underline_button->setText("underline"); + m_underline_button->setCheckable(true); + + m_toolbar->addWidget(m_bold_button); + m_toolbar->addWidget(m_italic_button); + m_toolbar->addWidget(m_underline_button); + + connect(m_bold_button, SIGNAL(toggled(bool)), this, SLOT(OnTextBold(bool))); + connect(m_italic_button, SIGNAL(toggled(bool)), this, SLOT(OnTextItalic(bool))); + connect(m_underline_button, SIGNAL(toggled(bool)), this, SLOT(OnTextUnderline(bool))); + connect(m_edit, SIGNAL(textChanged()), this, SLOT(OnInternalTextChanged())); + connect(m_edit, SIGNAL(currentCharFormatChanged(const QTextCharFormat&)), + this, SLOT(OnCharFormatChanged(const QTextCharFormat&))); + + SetGrowingMode(false); + SetReadOnly(false); +} + +void MyTextEditor::SetReadOnly(bool en) +{ + m_read_only = en; + if(en) + m_toolbar->hide(); + else + m_toolbar->hide(); + m_edit->setReadOnly(en); +} + +void MyTextEditor::SetGrowingMode(bool en) +{ + m_growing_mode = en; + if(en) + { + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + m_edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + OnTextChanged(); + } + else + { + m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_edit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + } +} + +void MyTextEditor::OnInternalTextChanged() +{ + if(m_growing_mode) + { + int content_size = m_edit->document()->documentLayout()->documentSize().height(); + content_size = qMax(content_size, m_edit->fontMetrics().height()); + m_edit->setMinimumHeight(content_size + m_edit->contentsMargins().top() + + m_edit->contentsMargins().bottom()); + } + emit OnTextChanged(); +} + +void MyTextEditor::OnTextBold(bool checked) +{ + QTextCursor cursor = m_edit->textCursor(); + QTextCharFormat fmt = cursor.charFormat(); + fmt.setFontWeight(checked ? QFont::Bold : QFont::Normal); + cursor.setCharFormat(fmt); + m_edit->setTextCursor(cursor); +} + +void MyTextEditor::OnTextItalic(bool checked) +{ + QTextCursor cursor = m_edit->textCursor(); + QTextCharFormat fmt = cursor.charFormat(); + fmt.setFontItalic(checked); + cursor.setCharFormat(fmt); + m_edit->setTextCursor(cursor); +} + +void MyTextEditor::OnTextUnderline(bool checked) +{ + QTextCursor cursor = m_edit->textCursor(); + QTextCharFormat fmt = cursor.charFormat(); + fmt.setFontUnderline(checked); + cursor.setCharFormat(fmt); + m_edit->setTextCursor(cursor); +} + +void MyTextEditor::OnCharFormatChanged(const QTextCharFormat& fmt) +{ + /* NOTE: changing the button states programmaticaly doesn't trigger + * the toggled() signals, otherwise it would result in a loop + * between this function and OnText{Bold,Italic,Underline,...} */ + m_bold_button->setChecked(fmt.fontWeight() > QFont::Normal); + m_italic_button->setChecked(fmt.fontItalic()); + m_underline_button->setChecked(fmt.fontUnderline()); +} + +void MyTextEditor::SetTextHtml(const QString& text) +{ + m_edit->setHtml(text); +} + +QString MyTextEditor::GetTextHtml() +{ + return m_edit->toPlainText(); +} + +bool MyTextEditor::IsModified() +{ + return m_edit->document()->isModified(); +} + +/** + * MySwitchableTextEditor + */ +MySwitchableTextEditor::MySwitchableTextEditor(QWidget *parent) + :QWidget(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + m_edit = new MyTextEditor(this); + m_label = new QLabel(this); + m_label->setTextFormat(Qt::RichText); + m_label->setAlignment(Qt::AlignTop); + m_line = new QLineEdit(this); + + layout->addWidget(m_label); + layout->addWidget(m_edit); + layout->addWidget(m_line); + + setLayout(layout); + + m_editor_mode = false; + m_line_mode = false; + UpdateVisibility(); +} + +void MySwitchableTextEditor::SetEditorMode(bool edit) +{ + if(edit == m_editor_mode) + return; + QString text = GetTextHtml(); + m_editor_mode = edit; + UpdateVisibility(); + SetTextHtml(text); +} + +QString MySwitchableTextEditor::GetTextHtml() +{ + if(m_editor_mode) + return m_line_mode ? m_line->text() : m_edit->GetTextHtml(); + else + return m_label->text(); +} + +void MySwitchableTextEditor::SetTextHtml(const QString& text) +{ + if(m_editor_mode) + { + if(m_line_mode) + m_line->setText(text); + else + m_edit->SetTextHtml(text); + } + else + m_label->setText(text); +} + +MyTextEditor *MySwitchableTextEditor::GetEditor() +{ + return m_edit; +} + +void MySwitchableTextEditor::SetLineMode(bool en) +{ + if(m_line_mode == en) + return; + QString text = GetTextHtml(); + m_line_mode = en; + SetTextHtml(text); + UpdateVisibility(); +} + +QLineEdit *MySwitchableTextEditor::GetLineEdit() +{ + return m_line; +} + +void MySwitchableTextEditor::UpdateVisibility() +{ + m_label->setVisible(!m_editor_mode); + m_edit->setVisible(m_editor_mode && !m_line_mode); + m_line->setVisible(m_editor_mode && m_line_mode); +} + +QLabel *MySwitchableTextEditor::GetLabel() +{ + return m_label; +} + +bool MySwitchableTextEditor::IsModified() +{ + if(!m_editor_mode) + return false; + return m_line_mode ? m_line->isModified() : m_edit->IsModified(); +} diff --git a/utils/regtools/qeditor/utils.h b/utils/regtools/qeditor/utils.h new file mode 100644 index 0000000000..ee08f1f31b --- /dev/null +++ b/utils/regtools/qeditor/utils.h @@ -0,0 +1,277 @@ +#ifndef AUX_H +#define AUX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "backend.h" + +class SocBitRangeValidator : public QValidator +{ + Q_OBJECT +public: + SocBitRangeValidator(QObject *parent = 0); + + virtual void fixup(QString& input) const; + virtual State validate(QString& input, int& pos) const; + /* validate and return the interpreted value */ + State parse(const QString& input, int& last_bit, int& first_bit) const; +}; + +class SocFieldValidator : public QValidator +{ + Q_OBJECT +public: + SocFieldValidator(QObject *parent = 0); + SocFieldValidator(const soc_reg_field_t& field, QObject *parent = 0); + + virtual void fixup(QString& input) const; + virtual State validate(QString& input, int& pos) const; + /* validate and return the interpreted value */ + State parse(const QString& input, soc_word_t& val) const; + +protected: + soc_reg_field_t m_field; +}; + +class RegLineEdit : public QWidget +{ + Q_OBJECT +public: + enum EditMode + { + Write, Set, Clear, Toggle + }; + + RegLineEdit(QWidget *parent = 0); + ~RegLineEdit(); + void SetReadOnly(bool ro); + void EnableSCT(bool en); + void SetMode(EditMode mode); + EditMode GetMode(); + QLineEdit *GetLineEdit(); + void setText(const QString& text); + QString text() const; + + Q_PROPERTY(QString text READ text WRITE setText USER true) + +protected slots: + void OnWriteAct(); + void OnSetAct(); + void OnClearAct(); + void OnToggleAct(); +protected: + void ShowMode(bool show); + void DoAutoHide(); + + QHBoxLayout *m_layout; + QToolButton *m_button; + QLineEdit *m_edit; + EditMode m_mode; + bool m_has_sct; + bool m_readonly; + QMenu *m_menu; +}; + +class SocFieldItemDelegate : public QStyledItemDelegate +{ +public: + SocFieldItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent), m_bitcount(32) {} + SocFieldItemDelegate(const soc_reg_field_t& field, QObject *parent = 0) + :QStyledItemDelegate(parent), m_bitcount(field.last_bit - field.first_bit + 1) {} + + virtual QString displayText(const QVariant& value, const QLocale& locale) const; +protected: + int m_bitcount; +}; + +class SocFieldEditor : public QLineEdit +{ + Q_OBJECT + Q_PROPERTY(uint field READ field WRITE setField USER true) +public: + SocFieldEditor(const soc_reg_field_t& field, QWidget *parent = 0); + virtual ~SocFieldEditor(); + + uint field() const; + void setField(uint field); + void SetRegField(const soc_reg_field_t& field) { m_reg_field = field; } + +protected: + SocFieldValidator *m_validator; + uint m_field; + soc_reg_field_t m_reg_field; +}; + +class SocFieldEditorCreator : public QItemEditorCreatorBase +{ +public: + SocFieldEditorCreator() { m_field.first_bit = 0; m_field.last_bit = 31; } + SocFieldEditorCreator(const soc_reg_field_t& field):m_field(field) {} + + virtual QWidget *createWidget(QWidget *parent) const; + virtual QByteArray valuePropertyName() const; + +protected: + soc_reg_field_t m_field; +}; + +class SocFieldCachedValue +{ +public: + SocFieldCachedValue():m_value(0) {} + SocFieldCachedValue(const soc_reg_field_t& field, uint value) + :m_field(field), m_value(value) {} + virtual ~SocFieldCachedValue() {} + const soc_reg_field_t& field() const { return m_field; } + uint value() const { return m_value; } +protected: + soc_reg_field_t m_field; + uint m_value; +}; + +Q_DECLARE_METATYPE(SocFieldCachedValue) + +class SocFieldCachedItemDelegate : public QStyledItemDelegate +{ +public: + SocFieldCachedItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent) {} + + virtual QString displayText(const QVariant& value, const QLocale& locale) const; +}; + +class SocFieldCachedEditor : public SocFieldEditor +{ + Q_OBJECT + Q_PROPERTY(SocFieldCachedValue value READ value WRITE setValue USER true) +public: + SocFieldCachedEditor(QWidget *parent = 0); + virtual ~SocFieldCachedEditor(); + + SocFieldCachedValue value() const; + void setValue(SocFieldCachedValue field); +protected: + SocFieldCachedValue m_value; +}; + +class SocFieldCachedEditorCreator : public QItemEditorCreatorBase +{ +public: + SocFieldCachedEditorCreator() {} + + virtual QWidget *createWidget(QWidget *parent) const; + virtual QByteArray valuePropertyName() const; + +protected: +}; + +class RegSexyDisplay : public QWidget +{ + Q_OBJECT +public: + RegSexyDisplay(const SocRegRef& reg, QWidget *parent = 0); + + QSize minimumSizeHint() const; + QSize sizeHint() const; + +protected: + int marginSize() const; + int separatorSize() const; + int columnWidth() const; + int headerHeight() const; + int gapHeight() const; + int maxContentHeight() const; + int textSep() const; + void paintEvent(QPaintEvent *event); + +private: + SocRegRef m_reg; + mutable QSize m_size; +}; + +class GrowingTextEdit : public QTextEdit +{ + Q_OBJECT +public: + GrowingTextEdit(QWidget *parent = 0); + +protected slots: + void TextChanged(); +}; + +class GrowingTableWidget : public QTableWidget +{ + Q_OBJECT +public: + GrowingTableWidget(QWidget *parent = 0); + +protected slots: + void DataChanged(const QModelIndex& tl, const QModelIndex& br); +}; + +class MyTextEditor : public QWidget +{ + Q_OBJECT +public: + MyTextEditor(QWidget *parent = 0); + void SetGrowingMode(bool en); + void SetReadOnly(bool ro); + void SetTextHtml(const QString& text); + QString GetTextHtml(); + bool IsModified(); +signals: + void OnTextChanged(); + +protected slots: + void OnInternalTextChanged(); + void OnTextBold(bool checked); + void OnTextItalic(bool checked); + void OnTextUnderline(bool checked); + void OnCharFormatChanged(const QTextCharFormat& fmt); + +protected: + bool m_growing_mode; + bool m_read_only; + QToolBar *m_toolbar; + QTextEdit *m_edit; + QToolButton *m_bold_button; + QToolButton *m_italic_button; + QToolButton *m_underline_button; +}; + +class MySwitchableTextEditor : public QWidget +{ + Q_OBJECT +public: + MySwitchableTextEditor(QWidget *parent = 0); + QString GetTextHtml(); + void SetTextHtml(const QString& text); + void SetEditorMode(bool en); + MyTextEditor *GetEditor(); + QLineEdit *GetLineEdit(); + QLabel *GetLabel(); + void SetLineMode(bool en); + bool IsModified(); + +protected: + void UpdateVisibility(); + + bool m_editor_mode; + bool m_line_mode; + QLabel *m_label; + MyTextEditor *m_edit; + QLineEdit *m_line; +}; + +#endif /* AUX_H */ -- cgit v1.2.3