/dev/Code/Sandbox/Plugins/MaglevControlPanel/FilePathLabel.h

https://github.com/aws/lumberyard · C Header · 179 lines · 128 code · 27 blank · 24 comment · 6 complexity · c543459be38cfb16f211d8d24c2f8e1b MD5 · raw file

  1. /*
  2. * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
  3. * its licensors.
  4. *
  5. * For complete copyright and license terms please see the LICENSE at the root of this
  6. * distribution (the "License"). All use of this software is governed by the License,
  7. * or, if provided, by the license below or the license accompanying this file. Do not
  8. * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
  9. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. *
  11. */
  12. #pragma once
  13. #include <QLabel>
  14. #include <QDesktopServices>
  15. #include <QPainter>
  16. #include <QFontMetrics>
  17. #include <QUrl>
  18. #include <QMenu>
  19. #include <QFileInfo>
  20. #include <QApplication>
  21. #include <QClipboard>
  22. #include <IEditor.h>
  23. #include <IFileUtil.h>
  24. class FilePathLabel
  25. : public QLabel
  26. {
  27. public:
  28. FilePathLabel()
  29. {
  30. // Let the HBoxLayout set the label's size basedo on the space
  31. // available in the window instead of the width of the label's
  32. // text.
  33. setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
  34. setContextMenuPolicy(Qt::CustomContextMenu);
  35. connect(this, &QLabel::customContextMenuRequested, this, &FilePathLabel::OnContextMenuRequested);
  36. }
  37. void setText(const QString& text)
  38. {
  39. QLabel::setText(text);
  40. if (text.isEmpty())
  41. {
  42. setToolTip("");
  43. }
  44. else
  45. {
  46. setToolTip("Double click to open in script editor or Explorer.");
  47. }
  48. // QLabel isn't repainting correctly. This forces the issue.
  49. // The root cause is size policy set in the constructor. It
  50. // seems that QLabel assumes it will be resized to fit its
  51. // text, so it doesn't bother erasing anything outside the
  52. // area the text occupies. Hence it leaves behind scraps from
  53. // longer strings.
  54. repaint();
  55. }
  56. void paintEvent(QPaintEvent* event) override
  57. {
  58. // If the text is too wide to fit in the space available,
  59. // truncate and prefix with "...".
  60. QPainter p(this);
  61. QFontMetrics fm(font());
  62. if (fm.width(text()) > contentsRect().width())
  63. {
  64. QString elidedText {
  65. this->fontMetrics().elidedText(text(), Qt::ElideLeft, rect().width())
  66. };
  67. p.drawText(rect(), elidedText);
  68. }
  69. else
  70. {
  71. QLabel::paintEvent(event);
  72. }
  73. }
  74. void mouseDoubleClickEvent(QMouseEvent* event) override
  75. {
  76. QFileInfo fileInfo {
  77. text()
  78. };
  79. if (fileInfo.isDir())
  80. {
  81. OnOpenPathInExplorer();
  82. }
  83. else
  84. {
  85. OnOpenInScriptEditor();
  86. }
  87. }
  88. void OnCopyPathToClipboard()
  89. {
  90. auto clipboard = QApplication::clipboard();
  91. clipboard->setText(text());
  92. }
  93. void OnOpenPathInExplorer()
  94. {
  95. // GetIEditor()->GetFileUtil()->ShowInExplorer doesn't handle full paths. Using openUrl instead.
  96. QDesktopServices::openUrl(QUrl::fromLocalFile(text()));
  97. }
  98. void OnOpenLocationInExplorer()
  99. {
  100. // GetIEditor()->GetFileUtil()->ShowInExplorer doesn't handle full paths. Using openUrl instead.
  101. QFileInfo fileInfo {
  102. text()
  103. };
  104. QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absolutePath()));
  105. }
  106. void OnOpenInScriptEditor()
  107. {
  108. GetIEditor()->GetFileUtil()->EditTextFile(text().toStdString().c_str(), 0, IFileUtil::FILE_TYPE_SCRIPT);
  109. }
  110. QMenu* GetContextMenu()
  111. {
  112. if (text().isEmpty())
  113. {
  114. return nullptr;
  115. }
  116. QFileInfo fileInfo {
  117. text()
  118. };
  119. auto menu = new QMenu {};
  120. if (fileInfo.isDir())
  121. {
  122. auto openPathInExplorer = menu->addAction("View in Explorer");
  123. openPathInExplorer->setToolTip(tr("View the directory in Windows Explorer."));
  124. connect(openPathInExplorer, &QAction::triggered, this, &FilePathLabel::OnOpenPathInExplorer);
  125. auto copyPathToClipboard = menu->addAction("Copy path to clipboard");
  126. copyPathToClipboard->setToolTip(tr("Copy the directory path to the clipboard."));
  127. connect(copyPathToClipboard, &QAction::triggered, this, &FilePathLabel::OnCopyPathToClipboard);
  128. }
  129. else
  130. {
  131. auto openFile = menu->addAction("Open in script editor");
  132. openFile->setToolTip(tr("Open file in the scripted editor configured in Lumberyard's global preferences."));
  133. connect(openFile, &QAction::triggered, this, &FilePathLabel::OnOpenInScriptEditor);
  134. auto openPathInExplorer = menu->addAction("View in Explorer");
  135. openPathInExplorer->setToolTip(tr("View the file in Windows Explorer."));
  136. connect(openPathInExplorer, &QAction::triggered, this, &FilePathLabel::OnOpenLocationInExplorer);
  137. menu->addSeparator();
  138. auto copyPathToClipboard = menu->addAction("Copy path to clipboard");
  139. copyPathToClipboard->setToolTip(tr("Copy the file path to the clipboard."));
  140. connect(copyPathToClipboard, &QAction::triggered, this, &FilePathLabel::OnCopyPathToClipboard);
  141. }
  142. return menu;
  143. }
  144. void OnContextMenuRequested(QPoint pos)
  145. {
  146. auto menu = GetContextMenu();
  147. if (menu)
  148. {
  149. menu->popup(mapToGlobal(pos));
  150. }
  151. }
  152. };