File indexing completed on 2024-06-16 05:25:07

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2010, 2012 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "viewprofileedit.hpp"
0010 
0011 // Okteta Gui Kasten
0012 #include <Kasten/Okteta/ByteArrayViewProfile>
0013 // Okteta core
0014 #include <Okteta/CharCodec>
0015 // KF
0016 #include <KLocalizedString>
0017 #include <KComboBox>
0018 // Qt
0019 #include <QVBoxLayout>
0020 #include <QGroupBox>
0021 #include <QFormLayout>
0022 #include <QCheckBox>
0023 #include <QSpinBox>
0024 #include <QLineEdit>
0025 // Std
0026 #include <limits>
0027 
0028 namespace Kasten {
0029 
0030 static constexpr int
0031 listIndexFromByteArrayCodingsFlags(int byteArrayCodingsFlags)
0032 {
0033     return byteArrayCodingsFlags - 1;
0034 }
0035 
0036 static constexpr int
0037 byteArrayCodingsFlagsFromListIndex(int listIndex)
0038 {
0039     return listIndex + 1;
0040 }
0041 
0042 ViewProfileEdit::ViewProfileEdit(QWidget* parent)
0043     : QWidget(parent)
0044 {
0045     auto* layout = new QVBoxLayout(this);
0046     layout->setContentsMargins(0, 0, 0, 0);
0047 
0048     // titel
0049     auto* titleFormLayout = new QFormLayout;
0050     // char for non-printable bytes
0051     mTitleEdit = new QLineEdit(this);
0052     mTitleEdit->setClearButtonEnabled(true);
0053     connect(mTitleEdit, &QLineEdit::textChanged,
0054             this, &ViewProfileEdit::profileTitleChanged);
0055     titleFormLayout->addRow(i18n("Title:"), mTitleEdit);
0056 
0057     // display settings
0058     auto* displayBox = new QGroupBox(this);
0059     displayBox->setTitle(i18n("Display"));
0060     auto* displayBoxFormLayout = new QFormLayout(displayBox);
0061     // line offset shown
0062     mLineOffsetShownCheckBox = new QCheckBox(displayBox);
0063     displayBoxFormLayout->addRow(i18n("Show Line Offset:"), mLineOffsetShownCheckBox);
0064     // offset coding
0065     mOffsetCodingComboBox = new KComboBox(displayBox);
0066     const QStringList offsetCodingList {
0067         i18nc("@item:inmenu offset in the hexadecimal format", "Hexadecimal"),
0068         i18nc("@item:inmenu offset in the decimal format", "Decimal"),
0069         i18nc("@item:inmenu offset in the octal format", "Octal"),
0070     };
0071     mOffsetCodingComboBox->addItems(offsetCodingList);
0072     displayBoxFormLayout->addRow(i18n("Offset Coding:"), mOffsetCodingComboBox);
0073     // values or char shown
0074     mValuesCharsShownComboBox = new KComboBox(displayBox);
0075     const QStringList valuesCharsList {
0076         i18nc("@item:", "Values"),
0077         i18nc("@item:", "Chars"),
0078         i18nc("@item:", "Values & Chars"),
0079     };
0080     mValuesCharsShownComboBox->addItems(valuesCharsList);
0081     displayBoxFormLayout->addRow(i18n("Show Values or Chars:"), mValuesCharsShownComboBox);
0082     // display mode
0083     const QString displayModeLabel =
0084         i18nc("@label:listbox ",
0085               "Show with Rows or Columns:");
0086     mDisplayModeComboBox = new KComboBox(displayBox);
0087     const QStringList displayModeList {
0088         i18nc("@item:", "Columns"),
0089         i18nc("@item:", "Rows"),
0090     };
0091     mDisplayModeComboBox->addItems(displayModeList);
0092     displayBoxFormLayout->addRow(displayModeLabel, mDisplayModeComboBox);
0093 
0094     // layout settings
0095     auto* layoutBox = new QGroupBox(this);
0096     layoutBox->setTitle(i18n("Layout"));
0097     auto* layoutBoxFormLayout = new QFormLayout(layoutBox);
0098     // line break
0099     mLineBreakComboBox = new KComboBox(layoutBox);
0100     const QStringList lineBreakList {
0101         i18nc("@item:inmenu  The layout will not change on size changes.",
0102               "Off"),
0103         i18nc("@item:inmenu  The layout will adapt to the size, but only with complete groups of bytes.",
0104               "Wrap Only Complete Byte Groups"),
0105         i18nc("@item:inmenu  The layout will adapt to the size and fit in as much bytes per line as possible.",
0106               "On"),
0107     };
0108     mLineBreakComboBox->addItems(lineBreakList);
0109     connect(mLineBreakComboBox, qOverload<int>(&KComboBox::currentIndexChanged),
0110             this, &ViewProfileEdit::onLineBreakIndexChanged);
0111     layoutBoxFormLayout->addRow(i18n("Break lines:"), mLineBreakComboBox);
0112     // bytes per group
0113     mGroupedBytesCountEdit = new QSpinBox(this);
0114     mGroupedBytesCountEdit->setRange(0, std::numeric_limits<int>::max());
0115     const QString noGroupingText = i18nc("@label",
0116                                          "No grouping.");
0117     mGroupedBytesCountEdit->setSpecialValueText(noGroupingText);
0118     const QString groupedBytesCountLabel =
0119         i18nc("@label:spinbox number of bytes which are grouped",
0120               "Bytes per Group:");
0121     layoutBoxFormLayout->addRow(groupedBytesCountLabel, mGroupedBytesCountEdit);
0122     // bytes per group
0123     mBytesPerLineEdit = new QSpinBox(this);
0124     mBytesPerLineEdit->setRange(1, std::numeric_limits<int>::max());
0125     const QString bytesPerLineLabel =
0126         i18nc("@label:spinbox number of bytes which are shown per line",
0127               "Bytes per Line:");
0128     layoutBoxFormLayout->addRow(bytesPerLineLabel, mBytesPerLineEdit);
0129 
0130     // value settings
0131     auto* valuesBox = new QGroupBox(this);
0132     valuesBox->setTitle(i18n("Values"));
0133     auto* valuesBoxFormLayout = new QFormLayout(valuesBox);
0134     // coding
0135     mValueCodingComboBox = new KComboBox(valuesBox);
0136     const QStringList valueCodingList {
0137         i18nc("@item:inmenu encoding of the bytes as values in the hexadecimal format",
0138               "Hexadecimal"),
0139         i18nc("@item:inmenu encoding of the bytes as values in the decimal format",
0140               "Decimal"),
0141         i18nc("@item:inmenu encoding of the bytes as values in the octal format",
0142               "Octal"),
0143         i18nc("@item:inmenu encoding of the bytes as values in the binary format",
0144               "Binary"),
0145     };
0146     mValueCodingComboBox->addItems(valueCodingList);
0147     valuesBoxFormLayout->addRow(i18n("Coding:"), mValueCodingComboBox);
0148 
0149     // char settings
0150     auto* charsBox = new QGroupBox(this);
0151     charsBox->setTitle(i18n("Chars"));
0152     auto* charsBoxFormLayout = new QFormLayout(charsBox);
0153     // coding
0154     mCharCodingComboBox = new KComboBox(charsBox);
0155     mCharCodingComboBox->addItems(Okteta::CharCodec::codecNames());
0156     charsBoxFormLayout->addRow(i18n("Coding:"), mCharCodingComboBox);
0157     // line offset shown
0158     mNonPrintableShownCheckBox = new QCheckBox(charsBox);
0159     // TODOSHOWNONPRINTING hide from UI for now
0160     mNonPrintableShownCheckBox->hide();
0161     // charsBoxFormLayout->addRow(i18n("Show Non-printable:"), mNonPrintableShownCheckBox);
0162     // char for non-printable bytes
0163     mNonPrintableCharEdit = new QLineEdit(charsBox);   // TODO: use a validator to ensure always one char
0164     mNonPrintableCharEdit->setClearButtonEnabled(true);
0165     mNonPrintableCharEdit->setMaxLength(1);
0166     charsBoxFormLayout->addRow(i18n("Char for non-printable bytes:"), mNonPrintableCharEdit);
0167     // char for undefined bytes
0168     mUndefinedCharEdit = new QLineEdit(charsBox);   // TODO: use a validator to ensure always one char
0169     mUndefinedCharEdit->setClearButtonEnabled(true);
0170     mUndefinedCharEdit->setMaxLength(1);
0171     charsBoxFormLayout->addRow(i18n("Char for undefined bytes:"), mUndefinedCharEdit);
0172 
0173     layout->addLayout(titleFormLayout);
0174     layout->addWidget(displayBox);
0175     layout->addWidget(layoutBox);
0176     layout->addWidget(valuesBox);
0177     layout->addWidget(charsBox);
0178 
0179     mTitleEdit->setFocus();
0180 }
0181 
0182 ViewProfileEdit::~ViewProfileEdit() = default;
0183 
0184 ByteArrayViewProfile ViewProfileEdit::viewProfile() const
0185 {
0186     ByteArrayViewProfile viewProfile;
0187     viewProfile.setViewProfileTitle(mTitleEdit->text());
0188 
0189     viewProfile.setOffsetColumnVisible(mLineOffsetShownCheckBox->isChecked());
0190     viewProfile.setOffsetCoding(mOffsetCodingComboBox->currentIndex());
0191     const int visibleByteArrayCodings =
0192         byteArrayCodingsFlagsFromListIndex(mValuesCharsShownComboBox->currentIndex());
0193     viewProfile.setVisibleByteArrayCodings(visibleByteArrayCodings);
0194     viewProfile.setViewModus(mDisplayModeComboBox->currentIndex());
0195 
0196     viewProfile.setLayoutStyle(mLineBreakComboBox->currentIndex());
0197     viewProfile.setNoOfGroupedBytes(mGroupedBytesCountEdit->value());
0198     viewProfile.setNoOfBytesPerLine(mBytesPerLineEdit->value());
0199 
0200     viewProfile.setValueCoding(mValueCodingComboBox->currentIndex());
0201 
0202     viewProfile.setCharCoding(mCharCodingComboBox->currentText());
0203     viewProfile.setShowsNonprinting(mNonPrintableShownCheckBox->isChecked());
0204     viewProfile.setSubstituteChar(mNonPrintableCharEdit->text().at(0));   // TODO: need make sure is one char
0205     viewProfile.setUndefinedChar(mUndefinedCharEdit->text().at(0));   // TODO: need make sure is one char
0206 
0207     return viewProfile;
0208 }
0209 
0210 void ViewProfileEdit::setViewProfile(const ByteArrayViewProfile& viewProfile)
0211 {
0212     mTitleEdit->setText(viewProfile.viewProfileTitle());
0213 
0214     mLineOffsetShownCheckBox->setChecked(viewProfile.offsetColumnVisible());
0215     mOffsetCodingComboBox->setCurrentIndex(viewProfile.offsetCoding());
0216     const int valuesCharsShownListIndex =
0217         listIndexFromByteArrayCodingsFlags(viewProfile.visibleByteArrayCodings());
0218     mValuesCharsShownComboBox->setCurrentIndex(valuesCharsShownListIndex);
0219     mDisplayModeComboBox->setCurrentIndex(viewProfile.viewModus());
0220 
0221     mLineBreakComboBox->setCurrentIndex(viewProfile.layoutStyle());
0222     mGroupedBytesCountEdit->setValue(viewProfile.noOfGroupedBytes());
0223     mBytesPerLineEdit->setValue(viewProfile.noOfBytesPerLine());
0224 
0225     mValueCodingComboBox->setCurrentIndex(viewProfile.valueCoding());
0226 
0227     mCharCodingComboBox->setCurrentItem(viewProfile.charCodingName());
0228     mNonPrintableShownCheckBox->setChecked(viewProfile.showsNonprinting());
0229     mNonPrintableCharEdit->setText(viewProfile.substituteChar());
0230     mUndefinedCharEdit->setText(viewProfile.undefinedChar());
0231 }
0232 
0233 void ViewProfileEdit::onLineBreakIndexChanged(int lineBreakIndex)
0234 {
0235     const bool isLineBreakByByte = (lineBreakIndex == 0);
0236 
0237     mBytesPerLineEdit->setEnabled(isLineBreakByByte);
0238 }
0239 
0240 }
0241 
0242 #include "moc_viewprofileedit.cpp"