clipboardmanager.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "clipboardmanager.h"
  2. #include <QApplication>
  3. #include <QRegularExpression>
  4. #include <QJsonDocument>
  5. #include <QJsonParseError>
  6. #include <QJsonObject>
  7. #include <QDateTime>
  8. #include <QByteArray>
  9. #include <QMimeData>
  10. #include <QFile>
  11. #include <QThread>
  12. #include <QDebug>
  13. constexpr int FILESIZELIMITMB = 8;
  14. ClipboardManager::ClipboardManager(QObject *parent) :
  15. QObject(parent),
  16. m_pclipboard(QApplication::clipboard()),
  17. m_pbinbuf(new QByteArray),
  18. m_ptextbuf(new QByteArray),
  19. m_myHardwareId(QSysInfo::machineUniqueId())
  20. {
  21. connect (m_pclipboard, &QClipboard::changed, this, &ClipboardManager::handleClipboard);
  22. }
  23. QByteArray ClipboardManager::data() const
  24. {
  25. return QByteArray::fromBase64(*m_ptextbuf);
  26. }
  27. void ClipboardManager::clear()
  28. {
  29. emit clearFields();
  30. m_ptextbuf->clear();
  31. m_pbinbuf->clear();
  32. m_fileName.clear();
  33. }
  34. void ClipboardManager::handleClipboard()
  35. {
  36. QString text = m_pclipboard->mimeData()->text();
  37. // Попытка чтения локального файла
  38. QString path = QByteArray::fromPercentEncoding(text.toUtf8());
  39. path.remove(QRegularExpression("^file://"));
  40. path.remove("\r\n");
  41. #ifdef WIN32
  42. path.remove(QRegularExpression("^/"));
  43. #endif
  44. QFile file(path);
  45. if (file.exists())
  46. {
  47. clear();
  48. if (not file.open(QIODevice::ReadOnly))
  49. {
  50. emit clearFields();
  51. return;
  52. }
  53. int sizeMb = file.size() / 1024 / 1024;
  54. if (FILESIZELIMITMB < sizeMb)
  55. {
  56. emit tooBigSize(QString("Size limit is %1 MB, selected file is %2 MB").arg(FILESIZELIMITMB).arg(sizeMb));
  57. file.close();
  58. return;
  59. }
  60. m_fileName = path;
  61. m_fileName.remove(QRegularExpression("^.*/"));
  62. *m_pbinbuf = file.read(FILESIZELIMITMB*1024*1024);
  63. file.close();
  64. rawBufferChanged(m_fileName);
  65. return;
  66. }
  67. // На Debian буфер больше ~0.5МБ обнуляется (последовательно фрагментируется)
  68. // Накапливаем во внутренний буфер, если информация поступает за <500 ms.
  69. if (QDateTime::currentMSecsSinceEpoch() - m_lastBufferChanging < 500)
  70. {
  71. if (not text.isEmpty())
  72. {
  73. *m_ptextbuf += text.toUtf8();
  74. }
  75. }else{
  76. clear();
  77. *m_ptextbuf = text.toUtf8();
  78. }
  79. // Возможно, JSON => Получение
  80. QJsonParseError jErr;
  81. QJsonDocument::fromJson(*m_ptextbuf, &jErr);
  82. if (jErr.error == QJsonParseError::NoError)
  83. {
  84. QJsonObject obj = QJsonDocument::fromJson(text.toUtf8()).object();
  85. bool status = obj.value("clipboardTransferBase64String").toBool();
  86. QString name = obj.value("fileName").toString();
  87. QString data = obj.value("data").toString();
  88. if (status and !name.isEmpty() and !data.isEmpty())
  89. {
  90. if (obj.value("hardwareId").toString() == m_myHardwareId)
  91. {
  92. m_ptextbuf->clear();
  93. emit preparedToTransfer(name);
  94. return;
  95. }
  96. m_lastBufferChanging = m_lastBufferChanging-501;
  97. *m_ptextbuf = data.toUtf8();
  98. emit readyToSave(name);
  99. }
  100. }
  101. m_lastBufferChanging = QDateTime::currentMSecsSinceEpoch();
  102. }
  103. void ClipboardManager::prepareToTransfer()
  104. {
  105. QJsonObject obj;
  106. obj.insert("clipboardTransferBase64String", true);
  107. obj.insert("fileName", m_fileName);
  108. obj.insert("hardwareId", m_myHardwareId);
  109. obj.insert("data", QString(m_pbinbuf->toBase64()));
  110. QByteArray array = QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact);
  111. m_pclipboard->setText(array);
  112. // int pos = 0;
  113. // int arraySize = array.size();
  114. // while (pos < arraySize)
  115. // {
  116. // qInfo() << "INSERTING";
  117. // QByteArray tmpArr (array);
  118. // tmpArr.remove(0, pos);
  119. // int partSize = 528288; // 0,5 MiB
  120. // int tail = arraySize - pos;
  121. // if (tail < partSize) partSize = tail;
  122. // pos += partSize;
  123. // m_pclipboard->setText(tmpArr.left(partSize));
  124. //// QThread::msleep(10);
  125. // }
  126. }