/src/modules/xml/xmlerrormanagerdialog.cpp

https://github.com/lbellonda/qxmledit · C++ · 166 lines · 144 code · 13 blank · 9 comment · 24 complexity · 1fac2abb2fb6eaf1ab1be3f311a19326 MD5 · raw file

  1. #include "xmlerrormanagerdialog.h"
  2. #include "ui_xmlerrormanagerdialog.h"
  3. #include "modules/xml/xmlloadcontext.h"
  4. #include <QDesktopServices>
  5. #include "utils.h"
  6. XMLErrorManagerDialog::XMLErrorManagerDialog(QWidget *parent, XMLLoadContext *newContext, QXmlStreamReader *xmlReader) :
  7. QDialog(parent),
  8. ui(new Ui::XMLErrorManagerDialog)
  9. {
  10. _xmlReader = xmlReader ;
  11. _error = false;
  12. _context = newContext ;
  13. ui->setupUi(this);
  14. Utils::showWaitCursor();
  15. readErrorData();
  16. Utils::restoreCursor();
  17. QPushButton *noButton = ui->buttonBox->button(QDialogButtonBox::No);
  18. if(NULL != noButton) {
  19. noButton->setDefault(true);
  20. }
  21. if(NULL != xmlReader) {
  22. QFile *file = qobject_cast<QFile*>(xmlReader->device());
  23. if(NULL != file) {
  24. _filePath = file->fileName();
  25. QFileInfo info(*file);
  26. QDir dir = info.dir();
  27. _dirPath = dir.absolutePath();
  28. }
  29. }
  30. if(_filePath.isEmpty()) {
  31. ui->copyFilePath->setEnabled(false);
  32. }
  33. if(_dirPath.isEmpty()) {
  34. ui->showContainingFolder->setEnabled(false);
  35. }
  36. }
  37. XMLErrorManagerDialog::~XMLErrorManagerDialog()
  38. {
  39. delete ui;
  40. }
  41. static qint64 clip0(const qint64 input)
  42. {
  43. if(input < 0) {
  44. return 0;
  45. }
  46. return input;
  47. }
  48. /*
  49. n = 2
  50. n-4 = -2
  51. -2|-1| 0| 1| 2|
  52. ..|..|..|..| X|
  53. 4| 3| 2| 1| 0|
  54. */
  55. int XMLErrorManagerDialog::charsBeforeError(const qint64 charOffset, const int bufferSize)
  56. {
  57. qint64 charErrorPosition = 0;
  58. const qint64 firstCharacterToLoad = charOffset - bufferSize ;
  59. if(firstCharacterToLoad < 0) {
  60. charErrorPosition = charOffset - 1;
  61. } else {
  62. charErrorPosition = bufferSize ;
  63. }
  64. return static_cast<int>(charErrorPosition) ;
  65. }
  66. void XMLErrorManagerDialog::readErrorData()
  67. {
  68. readData(_xmlReader->device());
  69. if(_error) {
  70. ui->textAfter->setVisible(false);
  71. ui->textError->setVisible(false);
  72. ui->textBefore->setVisible(false);
  73. ui->errorAfter->setVisible(false);
  74. ui->errorError->setVisible(false);
  75. ui->errorBefore->setVisible(false);
  76. }
  77. ui->errorMessage->setText(_context->errorMessage());
  78. ui->textAfter->setText(_afterString);
  79. ui->textError->setText(_errorPosString);
  80. ui->textBefore->setText(_beforeString);
  81. }
  82. bool XMLErrorManagerDialog::readData(QIODevice *device)
  83. {
  84. _error = true ;
  85. if(!device->seek(0)) {
  86. return false ;
  87. }
  88. QTextStream stream(device);
  89. stream.setCodec(QTextCodec::codecForName(_context->encoding().toLatin1().data()));
  90. return readData(&stream, _context->characterOffset());
  91. }
  92. bool XMLErrorManagerDialog::readData(QTextStream *stream, const qint64 charOffset)
  93. {
  94. _error = false;
  95. // this is the first character to load
  96. const qint64 firstCharacterToLoad = clip0(charOffset - CharsBefore) ;
  97. const qint64 blocksToSkip = firstCharacterToLoad / BlockSize ;
  98. const qint64 lastFractionSize = clip0(firstCharacterToLoad - (blocksToSkip * BlockSize)) ;
  99. const int beforeErrorChars = charsBeforeError(charOffset - firstCharacterToLoad, CharsBefore);
  100. for(qint64 index = 0; index < blocksToSkip ; index ++) {
  101. stream->read(BlockSize) ;
  102. if(stream->status() != QTextStream::Ok) {
  103. _error = true ;
  104. return false ;
  105. }
  106. }
  107. if(lastFractionSize > 0) {
  108. stream->read(lastFractionSize) ;
  109. if(stream->status() != QTextStream::Ok) {
  110. _error = true ;
  111. return false ;
  112. }
  113. }
  114. // read the effective data
  115. const QString &result = stream->read(CharsBefore * 2) ;
  116. if(stream->status() != QTextStream::Ok) {
  117. _error = true ;
  118. return false ;
  119. }
  120. if(beforeErrorChars > 0) {
  121. _beforeString = escapeString(result.left(beforeErrorChars));
  122. }
  123. _errorPosString = escapeString(result.mid(beforeErrorChars, 1));
  124. _afterString = escapeString(result.mid(beforeErrorChars + 1));
  125. return true;
  126. }
  127. QString XMLErrorManagerDialog::escapeString(const QString &str)
  128. {
  129. QString result = str ;
  130. result = result.replace("\r\n", "\\r\\n");
  131. result = result.replace("\n", "\\n");
  132. result = result.replace("\r", "\\r");
  133. return result;
  134. }
  135. void XMLErrorManagerDialog::on_buttonBox_accepted()
  136. {
  137. accept();
  138. }
  139. void XMLErrorManagerDialog::on_buttonBox_rejected()
  140. {
  141. reject();
  142. }
  143. void XMLErrorManagerDialog::on_showContainingFolder_clicked()
  144. {
  145. QDesktopServices::openUrl(QUrl::fromLocalFile(_dirPath));
  146. }
  147. void XMLErrorManagerDialog::on_copyFilePath_clicked()
  148. {
  149. QClipboard *clipboard = QApplication::clipboard();
  150. if(NULL != clipboard) {
  151. clipboard->setText(_filePath);
  152. }
  153. }