-
Notifications
You must be signed in to change notification settings - Fork 120
Add more representations of unprintable bytes #380
base: master
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,7 @@ | |
| #include <QMouseEvent> | ||
| #include <QStaticText> | ||
| #include <QStringList> | ||
| #include <QTextCodec> | ||
|
|
||
| #include "ui/createchunkdialog.h" | ||
| #include "ui/fileblobmodel.h" | ||
|
|
@@ -39,6 +40,11 @@ namespace ui { | |
| class HexEdit : public QAbstractScrollArea { | ||
| Q_OBJECT | ||
| public: | ||
| enum class UnprintablesMode { | ||
| Dots, | ||
| Windows_1250, | ||
| }; // do not change the order as settings may invalidate. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put this comment right after the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
|
||
| explicit HexEdit(FileBlobModel* dataModel, | ||
| QItemSelectionModel* selectionModel = nullptr, | ||
| QWidget* parent = nullptr); | ||
|
|
@@ -63,6 +69,8 @@ class HexEdit : public QAbstractScrollArea { | |
| in_insert_mode_ = in_insert_mode; | ||
| } | ||
| void saveToFile(const QString& file_name); | ||
| QString unprintablesModeToString(UnprintablesMode mode); | ||
| void setUnprintablesMode(UnprintablesMode mode); | ||
|
|
||
| public slots: | ||
| void newBinData(); | ||
|
|
@@ -177,6 +185,9 @@ class HexEdit : public QAbstractScrollArea { | |
| QScopedPointer<util::encoders::TextEncoder> textEncoder_; | ||
| util::EditEngine edit_engine_; | ||
|
|
||
| UnprintablesMode unprintables_mode_; | ||
| QTextCodec* windows1250_codec_; | ||
|
|
||
| void recalculateValues(); | ||
| void initParseMenu(); | ||
| void adjustBytesPerRowToWindowSize(); | ||
|
|
@@ -188,7 +199,10 @@ class HexEdit : public QAbstractScrollArea { | |
| WindowArea pointToWindowArea(QPoint pos); | ||
| QString addressAsText(qint64 pos); | ||
| QString hexRepresentationFromByte(uint64_t byte_val); | ||
| static QString asciiRepresentationFromByte(uint64_t byte_val); | ||
|
|
||
| QString asciiRepresentationFromByte(uint64_t byte_val); | ||
| void updateAsciiCache(); | ||
| void updateHexCache(); | ||
|
|
||
| static QColor byteTextColorFromByteValue(uint64_t byte_val); | ||
| QColor byteBackroundColorFromPos(qint64 pos, bool modified); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,9 @@ | |
| */ | ||
| #pragma once | ||
|
|
||
| #include <ui/hexedit.h> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't include our files using angle braces, use quotation marks.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| #include <QString> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separate this includes with a blank line (see https://google.github.io/styleguide/cppguide.html#Names_and_Order_of_Includes)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
|
||
| namespace veles { | ||
| namespace util { | ||
| namespace settings { | ||
|
|
@@ -25,6 +28,8 @@ int columnsNumber(); | |
| void setColumnsNumber(int number); | ||
| bool resizeColumnsToWindowWidth(); | ||
| void setResizeColumnsToWindowWidth(bool on); | ||
| veles::ui::HexEdit::UnprintablesMode unprintablesMode(); | ||
| void setUnprintablesMode(veles::ui::HexEdit::UnprintablesMode); | ||
|
|
||
| } // namespace hexedit | ||
| } // namespace settings | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ | |
| #include "util/encoders/factory.h" | ||
| #include "util/misc.h" | ||
| #include "util/random.h" | ||
| #include "util/settings/hexedit.h" | ||
| #include "util/settings/theme.h" | ||
|
|
||
| using veles::util::misc::array_size; | ||
|
|
@@ -127,7 +128,9 @@ HexEdit::HexEdit(FileBlobModel* dataModel, QItemSelectionModel* selectionModel, | |
| cursor_pos_in_byte_(0), | ||
| cursor_visible_(false), | ||
| in_insert_mode_(false), | ||
| edit_engine_(dataModel_) { | ||
| edit_engine_(dataModel_), | ||
| windows1250_codec_(QTextCodec::codecForName("windows-1250")) { | ||
| // TODO Add log warning if codec is unavailable (== nullptr) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| auto font = util::settings::theme::font(); | ||
| setFont(font); | ||
|
|
||
|
|
@@ -142,16 +145,9 @@ HexEdit::HexEdit(FileBlobModel* dataModel, QItemSelectionModel* selectionModel, | |
| recalculateValues(); | ||
|
|
||
| // Initialize hex & ASCII text cache. | ||
| for (size_t i = 0; i < array_size(hex_text_cache_); i++) { | ||
| hex_text_cache_[i].setPerformanceHint(QStaticText::ModerateCaching); | ||
| hex_text_cache_[i].setText(hexRepresentationFromByte(i)); | ||
| hex_text_cache_[i].setTextFormat(Qt::PlainText); | ||
| } | ||
| for (size_t i = 0; i < array_size(ascii_text_cache_); i++) { | ||
| ascii_text_cache_[i].setPerformanceHint(QStaticText::ModerateCaching); | ||
| ascii_text_cache_[i].setText(asciiRepresentationFromByte(i)); | ||
| ascii_text_cache_[i].setTextFormat(Qt::PlainText); | ||
| } | ||
| unprintables_mode_ = util::settings::hexedit::unprintablesMode(); | ||
| updateAsciiCache(); | ||
| updateHexCache(); | ||
|
|
||
| connect(verticalScrollBar(), &QAbstractSlider::valueChanged, this, | ||
| &HexEdit::recalculateValues); | ||
|
|
@@ -602,6 +598,27 @@ void HexEdit::saveToFile(const QString& file_name) { | |
| saveDataToFile(0, edit_engine_.dataSize(), file_name); | ||
| } | ||
|
|
||
| QString HexEdit::unprintablesModeToString(UnprintablesMode mode) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method can be static.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| switch (mode) { | ||
| case UnprintablesMode::Windows_1250: | ||
| return "Windows-1250"; | ||
| case UnprintablesMode::Dots: | ||
| default: | ||
| return "Dots"; | ||
| } | ||
| } | ||
|
|
||
| void HexEdit::setUnprintablesMode(UnprintablesMode mode) { | ||
| unprintables_mode_ = mode; | ||
| if (mode == UnprintablesMode::Windows_1250 && windows1250_codec_ == nullptr) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should do this check before assigning to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| QMessageBox::warning(this, "Error", "Windows-1250 is unavailable.", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| QMessageBox::Ok); | ||
| return; | ||
| } | ||
| updateAsciiCache(); | ||
| viewport()->update(); | ||
| } | ||
|
|
||
| void HexEdit::discardChanges() { | ||
| edit_engine_.clear(); | ||
| recalculateValues(); | ||
|
|
@@ -643,10 +660,53 @@ QString HexEdit::addressAsText(qint64 pos) { | |
| } | ||
|
|
||
| QString HexEdit::asciiRepresentationFromByte(uint64_t byte_val) { | ||
| if (byte_val >= 0x20 && byte_val < 0x7f) { | ||
| return QChar::fromLatin1(byte_val); | ||
| if (byte_val > 0xff) { | ||
| return "."; | ||
| } | ||
| if (windows1250_codec_ != nullptr && | ||
| unprintables_mode_ == UnprintablesMode::Windows_1250) { | ||
| char a = veles::util::misc::ucharToChar(byte_val); | ||
| QChar unicode_repr = windows1250_codec_->toUnicode(&a, 1).at(0); | ||
|
|
||
| bool is_undefined_windows1250 = byte_val == 0x81 || byte_val == 0x83 || | ||
| byte_val == 0x88 || byte_val == 0x90 || | ||
| byte_val == 0x98; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it would be better to check this before converting with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
|
||
| bool is_whitespace = unicode_repr.isSpace() || unicode_repr.isNull(); | ||
|
|
||
| if (is_whitespace || is_undefined_windows1250) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a check for 0x7f here, it decodes to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| return " "; | ||
| } | ||
|
|
||
| // printable ASCII chars | ||
| if (byte_val >= 0x20 && byte_val < 0x7f) { | ||
| return QChar::fromLatin1(byte_val); | ||
| } | ||
|
|
||
| // unprintable ASCII chars | ||
| return byte_val >= 0x7f ? windows1250_codec_->toUnicode(&a, 1) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| : QChar(static_cast<uint>(byte_val) + | ||
| 0x180); // greek for < 0x20 | ||
| } | ||
| // dots mode | ||
| return (byte_val >= 0x20 && byte_val < 0x7f) ? QChar::fromLatin1(byte_val) | ||
| : QString("."); | ||
| } | ||
|
|
||
| void HexEdit::updateAsciiCache() { | ||
| for (size_t i = 0; i < array_size(ascii_text_cache_); i++) { | ||
| ascii_text_cache_[i].setPerformanceHint(QStaticText::ModerateCaching); | ||
| ascii_text_cache_[i].setText(asciiRepresentationFromByte(i)); | ||
| ascii_text_cache_[i].setTextFormat(Qt::PlainText); | ||
| } | ||
| } | ||
|
|
||
| void HexEdit::updateHexCache() { | ||
| for (size_t i = 0; i < array_size(hex_text_cache_); i++) { | ||
| hex_text_cache_[i].setPerformanceHint(QStaticText::ModerateCaching); | ||
| hex_text_cache_[i].setText(hexRepresentationFromByte(i)); | ||
| hex_text_cache_[i].setTextFormat(Qt::PlainText); | ||
| } | ||
| return "."; | ||
| } | ||
|
|
||
| QColor HexEdit::byteTextColorFromByteValue(uint64_t byte_val) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,6 +84,9 @@ HexEditWidget::HexEditWidget( | |
| setParserIds(dynamic_cast<VelesMainWindow*>( | ||
| MainWindowWithDetachableDockWidgets::getFirstMainWindow()) | ||
| ->parsersList()); | ||
|
|
||
| initUnprintablesMenu(); | ||
|
|
||
| selectionChanged(0, 0); | ||
| } | ||
|
|
||
|
|
@@ -282,6 +285,18 @@ void HexEditWidget::createToolBars() { | |
| addToolBar(edit_tool_bar_); | ||
|
|
||
| view_tool_bar_ = new QToolBar(tr("View")); | ||
|
|
||
| auto unprintables_tool_button = new QToolButton(); | ||
| unprintables_tool_button->setMenu(&unprintables_menu_); | ||
| unprintables_tool_button->setPopupMode(QToolButton::InstantPopup); | ||
| unprintables_tool_button->setIcon(QIcon(":/images/brightness.png")); | ||
| unprintables_tool_button->setText(tr("&Unprintables")); | ||
| unprintables_tool_button->setToolTip(tr("Appearance of unprintable bytes")); | ||
| unprintables_tool_button->setAutoRaise(true); | ||
| auto unprintables_widget_action = new QWidgetAction(view_tool_bar_); | ||
| unprintables_widget_action->setDefaultWidget(unprintables_tool_button); | ||
|
|
||
| view_tool_bar_->addAction(unprintables_widget_action); | ||
| view_tool_bar_->addAction(remove_column_act_); | ||
| view_tool_bar_->addAction(add_column_act_); | ||
| view_tool_bar_->addSeparator(); | ||
|
|
@@ -302,6 +317,21 @@ void HexEditWidget::initParsersMenu() { | |
| } | ||
| } | ||
|
|
||
| void HexEditWidget::initUnprintablesMenu() { | ||
| unprintables_menu_.clear(); | ||
|
|
||
| HexEdit::UnprintablesMode modes[] = {HexEdit::UnprintablesMode::Dots, | ||
| HexEdit::UnprintablesMode::Windows_1250}; | ||
|
|
||
| for (auto mode : modes) { | ||
| QAction* action = new QAction(hex_edit_->unprintablesModeToString(mode), | ||
| &unprintables_menu_); | ||
| connect(action, &QAction::triggered, | ||
| [=]() { this->hex_edit_->setUnprintablesMode(mode); }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| unprintables_menu_.addAction(action); | ||
| } | ||
| } | ||
|
|
||
| void HexEditWidget::createSelectionInfo() { | ||
| auto* widget_action = new QWidgetAction(this); | ||
| auto* selection_panel = new QWidget; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ | |
|
|
||
| #include <QMessageBox> | ||
|
|
||
| #include <ui/hexedit.h> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please fix:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
| #include "ui_optionsdialog.h" | ||
| #include "util/settings/hexedit.h" | ||
| #include "util/settings/theme.h" | ||
|
|
@@ -48,6 +49,13 @@ void OptionsDialog::show() { | |
| ui->hexColumnsSpinBox->setValue(util::settings::hexedit::columnsNumber()); | ||
| ui->hexColumnsSpinBox->setEnabled(checkState != Qt::Checked); | ||
|
|
||
| ui->unprintablesModeDots->setChecked( | ||
| util::settings::hexedit::unprintablesMode() == | ||
| veles::ui::HexEdit::UnprintablesMode::Dots); | ||
| ui->unprintablesModeWindows1250->setChecked( | ||
| util::settings::hexedit::unprintablesMode() == | ||
| veles::ui::HexEdit::UnprintablesMode::Windows_1250); | ||
|
|
||
| QWidget::show(); | ||
| } | ||
|
|
||
|
|
@@ -63,6 +71,13 @@ void OptionsDialog::accept() { | |
| ui->hexColumnsAutoCheckBox->checkState() == Qt::Checked); | ||
| util::settings::hexedit::setColumnsNumber(ui->hexColumnsSpinBox->value()); | ||
|
|
||
| if (ui->unprintablesModeDots->isChecked()) | ||
| util::settings::hexedit::setUnprintablesMode( | ||
| veles::ui::HexEdit::UnprintablesMode::Dots); | ||
| if (ui->unprintablesModeWindows1250->isChecked()) | ||
| util::settings::hexedit::setUnprintablesMode( | ||
| veles::ui::HexEdit::UnprintablesMode::Windows_1250); | ||
|
|
||
| if (restart_needed) { | ||
| QMessageBox::about( | ||
| this, tr("Options change"), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use uppercase names (see Google style guide)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.