Clipboard.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorDefs.h"
  9. #include "Clipboard.h"
  10. #include "Util/Image.h"
  11. #include <QClipboard>
  12. #include <QMessageBox>
  13. #include <QVariant>
  14. XmlNodeRef CClipboard::m_node;
  15. QString CClipboard::m_title;
  16. QVariant CClipboard::s_pendingPut;
  17. //////////////////////////////////////////////////////////////////////////
  18. // Clipboard implementation.
  19. //////////////////////////////////////////////////////////////////////////
  20. CClipboard::CClipboard(QWidget* parent)
  21. : m_parent(parent != nullptr ? parent : QApplication::activeWindow())
  22. {
  23. m_putDebounce.setSingleShot(true);
  24. m_putDebounce.setInterval(0);
  25. // Wait one frame before setting clipboard contents, in case we're updated frequently
  26. QObject::connect(&m_putDebounce, &QTimer::timeout, [this](){SendPendingPut();});
  27. }
  28. void CClipboard::Put(XmlNodeRef& node, const QString& title)
  29. {
  30. m_title = title;
  31. if (m_title.isEmpty())
  32. {
  33. m_title = node->getTag();
  34. }
  35. m_node = node;
  36. PutString(m_node->getXML().c_str(), title);
  37. }
  38. //////////////////////////////////////////////////////////////////////////
  39. XmlNodeRef CClipboard::Get() const
  40. {
  41. QString str = GetString();
  42. return XmlHelpers::LoadXmlFromBuffer(str.toUtf8().data(), str.toUtf8().length(), true);
  43. }
  44. //////////////////////////////////////////////////////////////////////////
  45. void CClipboard::PutString(const QString& text, [[maybe_unused]] const QString& title /* = "" */)
  46. {
  47. s_pendingPut = text;
  48. m_putDebounce.start();
  49. }
  50. //////////////////////////////////////////////////////////////////////////
  51. QString CClipboard::GetString() const
  52. {
  53. if (s_pendingPut.type() == QVariant::String)
  54. {
  55. return s_pendingPut.toString();
  56. }
  57. return QApplication::clipboard()->text();
  58. }
  59. //////////////////////////////////////////////////////////////////////////
  60. bool CClipboard::IsEmpty() const
  61. {
  62. return GetString().isEmpty();
  63. }
  64. //////////////////////////////////////////////////////////////////////////
  65. void CClipboard::PutImage(const CImageEx& img)
  66. {
  67. QImage image(img.GetWidth(), img.GetHeight(), QImage::Format_RGBA8888);
  68. s_pendingPut = image;
  69. m_putDebounce.start();
  70. }
  71. //////////////////////////////////////////////////////////////////////////
  72. bool CClipboard::GetImage(CImageEx& img)
  73. {
  74. QImage image;
  75. if (s_pendingPut.type() == QVariant::Image)
  76. {
  77. image = s_pendingPut.value<QImage>();
  78. }
  79. else
  80. {
  81. image = QApplication::clipboard()->image();
  82. }
  83. img.Allocate(image.width(), image.height());
  84. unsigned char* pSrc = (unsigned char*)image.scanLine(0);
  85. unsigned char* pDst = (unsigned char*)img.GetData();
  86. int stSrc = (image.depth() == 24) ? 3 : 4;
  87. for (int y = 0; y < image.height(); y++)
  88. {
  89. for (int x = 0; x < image.width(); x++)
  90. {
  91. pDst[x * 4 + (image.height() - y - 1) * image.width() * 4] = pSrc[x * stSrc + y * image.bytesPerLine()];
  92. pDst[x * 4 + (image.height() - y - 1) * image.width() * 4 + 1] = pSrc[x * stSrc + y * image.bytesPerLine() + 1];
  93. pDst[x * 4 + (image.height() - y - 1) * image.width() * 4 + 2] = pSrc[x * stSrc + y * image.bytesPerLine() + 2];
  94. pDst[x * 4 + (image.height() - y - 1) * image.width() * 4 + 3] = 0;
  95. }
  96. }
  97. return true;
  98. }
  99. //////////////////////////////////////////////////////////////////////////
  100. void CClipboard::SendPendingPut()
  101. {
  102. if (s_pendingPut.type() == QVariant::String)
  103. {
  104. QString text = s_pendingPut.toString();
  105. QApplication::clipboard()->setText(text);
  106. }
  107. else if (s_pendingPut.type() == QVariant::Image)
  108. {
  109. QImage image = s_pendingPut.value<QImage>();
  110. QApplication::clipboard()->setImage(image);
  111. }
  112. s_pendingPut = {};
  113. }