datawindow.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. Zint Barcode Generator - the open source barcode generator
  3. Copyright (C) 2009-2024 Robin Stuart <rstuart114@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. /* SPDX-License-Identifier: GPL-3.0-or-later */
  17. //#include <QDebug>
  18. #include <QFileDialog>
  19. #include <QMessageBox>
  20. #include <QRegularExpression>
  21. #include <QSettings>
  22. #include <QStringList>
  23. #include <QUiLoader>
  24. #include "datawindow.h"
  25. // Shorthand
  26. #define QSL QStringLiteral
  27. static const int tempMessageTimeout = 2000;
  28. DataWindow::DataWindow(const QString &input, bool isEscaped, int seg_no) : Valid(false), Escaped(false),
  29. m_isEscaped(isEscaped), m_seg_no(seg_no)
  30. {
  31. setupUi(this);
  32. QSettings settings;
  33. #if QT_VERSION < 0x60000
  34. settings.setIniCodec("UTF-8");
  35. #endif
  36. QByteArray geometry = settings.value(QSL("studio/data/window_geometry")).toByteArray();
  37. restoreGeometry(geometry);
  38. QIcon closeIcon(QIcon::fromTheme(QSL("window-close"), QIcon(QSL(":res/x.svg"))));
  39. QIcon clearIcon(QSL(":res/delete.svg"));
  40. QIcon okIcon(QIcon(QSL(":res/check.svg")));
  41. btnCancel->setIcon(closeIcon);
  42. btnDataClear->setIcon(clearIcon);
  43. btnOK->setIcon(okIcon);
  44. if (isEscaped && input.contains(QSL("\\n"))) {
  45. // Substitute escaped Line Feeds with actual Line Feeds
  46. QString out;
  47. out.reserve(input.length());
  48. int lastPosn = 0;
  49. QRegularExpression escRE(QSL("\\\\(?:[0EabtnvfreGR\\\\]|d[0-9]{3}|o[0-7]{3}|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}"
  50. "|U[0-9A-Fa-f]{6})"));
  51. QRegularExpressionMatchIterator matchI = escRE.globalMatch(input);
  52. while (matchI.hasNext()) {
  53. QRegularExpressionMatch match = matchI.next();
  54. if (match.captured(0) == QSL("\\n")) {
  55. out += input.mid(lastPosn, match.capturedStart(0) - lastPosn) + '\n';
  56. lastPosn = match.capturedEnd(0);
  57. }
  58. }
  59. out += input.mid(lastPosn);
  60. txtDataInput->setPlainText(out);
  61. statusBarData->showMessage(tr("Converted LFs"), tempMessageTimeout);
  62. } else {
  63. txtDataInput->setPlainText(input);
  64. }
  65. txtDataInput->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
  66. connect(btnCancel, SIGNAL(clicked(bool)), SLOT(close()));
  67. connect(btnDataClear, SIGNAL(clicked(bool)), SLOT(clear_data()));
  68. connect(btnOK, SIGNAL(clicked(bool)), SLOT(okay()));
  69. connect(btnFromFile, SIGNAL(clicked(bool)), SLOT(from_file()));
  70. connect(txtDataInput, SIGNAL(textChanged()), this, SLOT(text_changed()));
  71. btnDataClear->setEnabled(!txtDataInput->toPlainText().isEmpty());
  72. }
  73. DataWindow::~DataWindow()
  74. {
  75. QSettings settings;
  76. #if QT_VERSION < 0x60000
  77. settings.setIniCodec("UTF-8");
  78. #endif
  79. settings.setValue(QSL("studio/data/window_geometry"), saveGeometry());
  80. }
  81. void DataWindow::clear_data()
  82. {
  83. txtDataInput->clear();
  84. }
  85. void DataWindow::text_changed()
  86. {
  87. bool escaped = m_isEscaped;
  88. const QString &text = escapedData(escaped);
  89. btnDataClear->setEnabled(!text.isEmpty());
  90. emit dataChanged(text, escaped, m_seg_no);
  91. }
  92. void DataWindow::okay()
  93. {
  94. Valid = true;
  95. DataOutput = escapedData(Escaped);
  96. close();
  97. }
  98. QString DataWindow::escapedData(bool &escaped)
  99. {
  100. QString text = txtDataInput->toPlainText();
  101. if (text.contains('\n')) {
  102. // Escape Line Feeds
  103. text.replace('\n', QSL("\\n"));
  104. escaped = true;
  105. }
  106. return text;
  107. }
  108. void DataWindow::from_file()
  109. {
  110. QSettings settings;
  111. #if QT_VERSION < 0x60000
  112. settings.setIniCodec("UTF-8");
  113. #endif
  114. QFileDialog open_dialog;
  115. QString filename;
  116. QFile file;
  117. QByteArray outstream;
  118. open_dialog.setWindowTitle("Import File");
  119. open_dialog.setDirectory(settings.value("studio/default_dir",
  120. QDir::toNativeSeparators(QDir::homePath())).toString());
  121. if (open_dialog.exec()) {
  122. filename = open_dialog.selectedFiles().at(0);
  123. } else {
  124. return;
  125. }
  126. file.setFileName(filename);
  127. if (!file.open(QIODevice::ReadOnly)) {
  128. QMessageBox::critical(this, tr("Open Error"), tr("Could not open selected file."));
  129. return;
  130. }
  131. outstream = file.readAll();
  132. /* Allow some non-printing (control) characters to be read from file
  133. by converting them to escape sequences */
  134. QString escape_string(outstream); // Converts to UTF-8 (NOTE: QString can't handle embedded NULs)
  135. QRegularExpression escRE(QSL("[\\x04\\x07\\x08\\x09\\x0B\\x0C\\x0D\\x1B\\x1D\\x1E\\x5C]"));
  136. if (escape_string.contains(escRE)) {
  137. escape_string.replace((QChar)'\\', QSL("\\\\"));
  138. escape_string.replace((QChar)0x04, QSL("\\E")); /* End of Transmission */
  139. escape_string.replace((QChar)'\a', QSL("\\a")); /* Bell (0x07) */
  140. escape_string.replace((QChar)'\b', QSL("\\b")); /* Backspace (0x08) */
  141. escape_string.replace((QChar)'\t', QSL("\\t")); /* Horizontal tab (0x09) */
  142. // Leaving Line Feed (0x0A)
  143. escape_string.replace((QChar)'\v', QSL("\\v")); /* Vertical tab (0x0B) */
  144. escape_string.replace((QChar)'\f', QSL("\\f")); /* Form feed (0x0C) */
  145. escape_string.replace((QChar)'\r', QSL("\\r")); /* Carriage return (0x0D) */
  146. escape_string.replace((QChar)0x1b, QSL("\\e")); /* Escape */
  147. escape_string.replace((QChar)0x1d, QSL("\\G")); /* Group Separator */
  148. escape_string.replace((QChar)0x1e, QSL("\\R")); /* Record Separator */
  149. Escaped = true;
  150. statusBarData->showMessage(tr("Escaped data"), tempMessageTimeout);
  151. }
  152. txtDataInput->setPlainText(escape_string);
  153. file.close();
  154. settings.setValue("studio/default_dir", filename.mid(0, filename.lastIndexOf(QDir::separator())));
  155. }
  156. /* vim: set ts=4 sw=4 et : */