diff --git a/icons.qrc b/icons.qrc new file mode 100644 index 0000000..2b8fe2f --- /dev/null +++ b/icons.qrc @@ -0,0 +1,8 @@ + + + icons/open-file-48.png + icons/logout-52.png + icons/save-50.png + icons/save-as-64.png + + diff --git a/icons/logout-52.png b/icons/logout-52.png new file mode 100644 index 0000000..83af84b Binary files /dev/null and b/icons/logout-52.png differ diff --git a/icons/open-file-48.png b/icons/open-file-48.png new file mode 100644 index 0000000..b9f0031 Binary files /dev/null and b/icons/open-file-48.png differ diff --git a/icons/save-50.png b/icons/save-50.png new file mode 100644 index 0000000..f78bd73 Binary files /dev/null and b/icons/save-50.png differ diff --git a/icons/save-as-64.png b/icons/save-as-64.png new file mode 100644 index 0000000..3e9ca55 Binary files /dev/null and b/icons/save-as-64.png differ diff --git a/ini_utils.pro b/ini_utils.pro new file mode 100644 index 0000000..86c23e1 --- /dev/null +++ b/ini_utils.pro @@ -0,0 +1,32 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + main.cpp \ + widget.cpp + +HEADERS += \ + widget.h + +FORMS += \ + widget.ui + +TRANSLATIONS += \ + ini_utils_ru_RU.ts +CONFIG += lrelease +CONFIG += embed_translations + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + icons.qrc diff --git a/ini_utils_ru_RU.ts b/ini_utils_ru_RU.ts new file mode 100644 index 0000000..743f57f --- /dev/null +++ b/ini_utils_ru_RU.ts @@ -0,0 +1,3 @@ + + + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..bb95124 --- /dev/null +++ b/main.cpp @@ -0,0 +1,23 @@ +#include "widget.h" + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QTranslator translator; + const QStringList uiLanguages = QLocale::system().uiLanguages(); + for (const QString &locale : uiLanguages) { + const QString baseName = "ini_utils_" + QLocale(locale).name(); + if (translator.load(":/i18n/" + baseName)) { + a.installTranslator(&translator); + break; + } + } + Widget w; + w.show(); + return a.exec(); +} diff --git a/widget.cpp b/widget.cpp new file mode 100644 index 0000000..9b53246 --- /dev/null +++ b/widget.cpp @@ -0,0 +1,197 @@ +#include "widget.h" +#include "ui_widget.h" + +#include + +myTable::myTable(const records &hash):QTableWidget() { + fill(hash); +} +void myTable::fill(const records &hash) { + setRowCount(hash.size()); + setColumnCount(2); + int ii=0; + for (const auto &rec: hash ) { + QTableWidgetItem *item1 = new QTableWidgetItem(rec.first); + QTableWidgetItem *item2 = new QTableWidgetItem(rec.second); + setItem(ii, 0, item1); + setItem(ii, 1, item2); + ++ii; + } +} +Widget::Widget(QWidget *parent) + : QWidget(parent), ui(new Ui::Widget) +{ + ui->setupUi(this); + ui->lineEdit->hide(); + ui->pushButton->setIcon(QIcon(":/res/icons/open-file-48.png")); + ui->pushButton->setIconSize(QSize(28, 28)); + ui->pushButton->setToolTip("Открыть INI файл..."); + ui->pushButton_2->setIcon(QIcon(":/res/icons/logout-52.png")); + ui->pushButton_2->setIconSize(QSize(26, 22)); + ui->pushButton_2->setToolTip("Выход"); + ui->pushButton_3->setIcon(QIcon(":/res/icons/save-as-64.png")); + ui->pushButton_3->setIconSize(QSize(28, 28)); + ui->pushButton_3->setToolTip("Сохранить как..."); + ui->pushButton_3->setEnabled(false); + ui->pushButton_4->setIcon(QIcon(":/res/icons/save-50.png")); + ui->pushButton_4->setIconSize(QSize(26, 26)); + ui->pushButton_4->setToolTip("Сохранить"); + ui->pushButton_4->setEnabled(false); + ui->tabWidget->hide(); + + setWindowIcon(QIcon()); +} + +Widget::~Widget() +{ + delete ui; +} + + +void Widget::on_pushButton_clicked() +{ + QString pathStr = ui->lineEdit->text(); + if (pathStr.isEmpty()) pathStr = QDir::currentPath(); + QString fileName = QFileDialog::getOpenFileName(this, + tr("Выберите файл"), + pathStr, + tr("INI файлы (*.ini)")); + if (!fileName.isEmpty()) { + ui->lineEdit->setText(fileName); + QTimer::singleShot(200, this, SLOT(genTabs())); + } +} + +void Widget::genTabs() { + ui->tabWidget->hide(); + tabs.clear(); + QTabWidget *tw = ui->tabWidget; + for (int i=tw->count()-1; i>=0; i--) { + QWidget *w = tw->widget(i); + tw->removeTab(i); + if (w!= nullptr) delete w; + } + tw->clear(); + this->setWindowTitle(ui->lineEdit->text()); + QFile file(ui->lineEdit->text()); + if (!file.open(QIODevice::ReadOnly)) { + QMessageBox::critical(this, "Ошибка", "Ошибка открытия файла"); + ui->pushButton_3->setEnabled(false); + ui->pushButton_4->setEnabled(false); + return; + } + + ui->pushButton_3->setEnabled(true); + ui->pushButton_4->setEnabled(true); + + proceedFile(file); + if (file.isOpen()) file.close(); + + const QIcon nullIcon; + + for (int i=0; iaddTab(local_tab, nullIcon, tabs[i].m_name); + } + tw->setCurrentIndex(0); + tw->show(); + +} + +void Widget::on_lineEdit_returnPressed() +{ + QTimer::singleShot(200, this, SLOT(genTabs())); +} + +void Widget::on_pushButton_2_clicked() +{ + close(); +} + +void Widget::proceedFile(QFile &file) { + int numLine = 0; + comments.clear(); + while (!file.atEnd()) { + numLine++; + QByteArray line = file.readLine(); + QString str = QString::fromLocal8Bit(line.data()); + if (str.length()>1 && str.right(2) == "\r\n") str.chop(2); + while (!str.isEmpty() && str.back()=='\t') str.chop(1); + if (str.isEmpty()) continue; + if (str.front()==';') { + comments.insert(numLine, str); + continue; + } + if (str.front() == '[') { + tabs.push_back(tabChapter(str)); + continue; + } + QString strKey = str.section('=', 0, 0); + QString strData = str.section('=', 1); + QPair pair(strKey, strData); + tabs.back().m_hash.push_back(pair); + } +} + +void Widget::on_pushButton_4_clicked() +{ +// saveBtn + QString path = ui->lineEdit->text(); + saveDataToFile(path); +} + +void Widget::on_pushButton_3_clicked() +{ +// saveAsBtn + QString pathStr = ui->lineEdit->text(); + if (pathStr.isEmpty()) pathStr = QDir::currentPath(); + QString fileName = QFileDialog::getSaveFileName(this, + tr("Выберите файл"), + pathStr, + tr("INI файлы (*.ini)")); + if (!fileName.isEmpty()) { + saveDataToFile(fileName); + } +} + +void Widget::saveDataToFile(QString &name) { + QFile fd(name); + if (!fd.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::critical(this, "Ошибка файла", "Ошибка открытия файла на запись"); + } + + int numLine = 1; + + while (comments.find(numLine)!=comments.end()) { + fd.write(comments[numLine++].toLocal8Bit()); + fd.write("\n"); + } + + for (int i=0; itabWidget->count(); ++i) { + fd.write(ui->tabWidget->tabText(i).toLocal8Bit()); + fd.write("\n"); + numLine++; + while (comments.find(numLine)!=comments.end()) { + fd.write(comments[numLine++].toLocal8Bit()); + fd.write("\n"); + } + + myTable *tab = (myTable *)ui->tabWidget->widget(i); + for (int j=0; jrowCount(); j++) { + QString str = tab->item(j, 0)->text() + + QString("=") + tab->item(j, 1)->text() + "\n"; + fd.write(str.toLocal8Bit()); + numLine++; + while (comments.find(numLine)!=comments.end()) { + fd.write(comments[numLine++].toLocal8Bit()); + fd.write("\n"); + } + } + fd.write("\n"); + numLine++; + + } + + if (fd.isOpen()) fd.close(); + setWindowTitle(name); +} diff --git a/widget.h b/widget.h new file mode 100644 index 0000000..9b6d555 --- /dev/null +++ b/widget.h @@ -0,0 +1,63 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class Widget; } +QT_END_NAMESPACE + +using record = QPair; +using records = QVector; + +class tabChapter { +public: + tabChapter(); + tabChapter(QString _name) : m_name(_name) {} + QString m_name; + records m_hash; +}; + +class myTable : public QTableWidget +{ + Q_OBJECT +public: + myTable(const records &hash = {}); +private: + void fill(const records &hash); +}; + +class Widget : public QWidget +{ + Q_OBJECT + +public: + Widget(QWidget *parent = nullptr); + ~Widget(); + +private slots: + void on_pushButton_clicked(); + void genTabs(); + void on_lineEdit_returnPressed(); + + void on_pushButton_2_clicked(); + + void on_pushButton_4_clicked(); + + void on_pushButton_3_clicked(); + +private: + Ui::Widget *ui; + void proceedFile(QFile &file); + QVector tabs; + QHash comments; + void saveDataToFile(QString &fileName); +}; +#endif // WIDGET_H diff --git a/widget.ui b/widget.ui new file mode 100644 index 0000000..f2444b1 --- /dev/null +++ b/widget.ui @@ -0,0 +1,118 @@ + + + Widget + + + + 0 + 0 + 574 + 792 + + + + + 0 + 0 + + + + + 574 + 792 + + + + + 574 + 792 + + + + ini_UTILS + + + + false + + + + 30 + 70 + 521 + 24 + + + + + + + + + + 30 + 20 + 51 + 41 + + + + + + + + + + 210 + 20 + 51 + 41 + + + + + + + + + + 149 + 20 + 51 + 41 + + + + + + + + + + 89 + 20 + 51 + 41 + + + + + + + + + + 30 + 70 + 530 + 711 + + + + -1 + + + + + +