GemRepoInspector.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 <GemRepo/GemRepoInspector.h>
  9. #include <GemRepo/GemRepoItemDelegate.h>
  10. #include <PythonBindingsInterface.h>
  11. #include <AzQtComponents/Components/Widgets/ElidingLabel.h>
  12. #include <QFrame>
  13. #include <QLabel>
  14. #include <QVBoxLayout>
  15. #include <QIcon>
  16. #include <QPushButton>
  17. #include <QClipboard>
  18. #include <QGuiApplication>
  19. #include <QItemSelectionModel>
  20. namespace O3DE::ProjectManager
  21. {
  22. GemRepoInspector::GemRepoInspector(GemRepoModel* model, QItemSelectionModel* selectionModel,QWidget* parent)
  23. : QScrollArea(parent)
  24. , m_model(model)
  25. , m_selectionModel(selectionModel)
  26. {
  27. setObjectName("gemRepoInspector");
  28. setWidgetResizable(true);
  29. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  30. setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  31. m_mainWidget = new QWidget();
  32. setWidget(m_mainWidget);
  33. m_mainLayout = new QVBoxLayout();
  34. m_mainLayout->setMargin(15);
  35. m_mainLayout->setAlignment(Qt::AlignTop);
  36. m_mainWidget->setLayout(m_mainLayout);
  37. InitMainWidget();
  38. connect(selectionModel, &QItemSelectionModel::selectionChanged, this, &GemRepoInspector::OnSelectionChanged);
  39. Update({});
  40. }
  41. void GemRepoInspector::OnSelectionChanged(const QItemSelection& selected, [[maybe_unused]] const QItemSelection& deselected)
  42. {
  43. const QModelIndexList selectedIndices = selected.indexes();
  44. if (selectedIndices.empty())
  45. {
  46. Update({});
  47. return;
  48. }
  49. Update(selectedIndices[0]);
  50. }
  51. void GemRepoInspector::Update(const QModelIndex& modelIndex)
  52. {
  53. m_curModelIndex = modelIndex;
  54. if (!modelIndex.isValid())
  55. {
  56. m_mainWidget->hide();
  57. }
  58. // Repo name and url link
  59. m_nameLabel->setText(m_model->GetName(modelIndex));
  60. const QString repoUri = m_model->GetRepoUri(modelIndex);
  61. // ideally we would use Qt::TextWrapAnywhere to wrap and display the full URL
  62. // but QLabel only supports word-break wrapping so elide the text
  63. // clicking on the link will display the full URL and ask the user
  64. // to confirm they want to visit it
  65. m_repoLinkLabel->SetText(repoUri);
  66. m_repoLinkLabel->SetUrl(repoUri);
  67. // Repo summary
  68. m_summaryLabel->setText(m_model->GetSummary(modelIndex));
  69. m_summaryLabel->adjustSize();
  70. // Additional information
  71. if (m_model->HasAdditionalInfo(modelIndex))
  72. {
  73. m_addInfoTitleLabel->show();
  74. m_addInfoTextLabel->show();
  75. m_addInfoSpacer->changeSize(0, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);
  76. m_addInfoTextLabel->setText(m_model->GetAdditionalInfo(modelIndex));
  77. }
  78. else
  79. {
  80. m_addInfoTitleLabel->hide();
  81. m_addInfoTextLabel->hide();
  82. m_addInfoSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
  83. }
  84. // Included Gems
  85. const QVector<Tag>& gemTags = m_model->GetIncludedGemTags(modelIndex);
  86. m_includedGems->setVisible(!gemTags.isEmpty());
  87. if (!gemTags.empty())
  88. {
  89. m_includedGems->Update(tr("Included Gems"), "", gemTags);
  90. }
  91. const QVector<Tag>& projectTags = m_model->GetIncludedProjectTags(modelIndex);
  92. m_includedProjects->setVisible(!projectTags.isEmpty());
  93. if (!projectTags.empty())
  94. {
  95. m_includedProjects->Update(tr("Included Projects"), "", projectTags);
  96. }
  97. const QVector<Tag>& templateTags = m_model->GetIncludedProjectTemplateTags(modelIndex);
  98. m_includedTemplates->setVisible(!templateTags.isEmpty());
  99. if (!templateTags.empty())
  100. {
  101. m_includedTemplates->Update(tr("Included Project Templates"), "", templateTags);
  102. }
  103. m_mainWidget->adjustSize();
  104. m_mainWidget->show();
  105. }
  106. void GemRepoInspector::InitMainWidget()
  107. {
  108. // Repo name and url link
  109. m_nameLabel = new AzQtComponents::ElidingLabel();
  110. m_nameLabel->setObjectName("gemRepoInspectorNameLabel");
  111. m_nameLabel->setWordWrap(true);
  112. m_mainLayout->addWidget(m_nameLabel);
  113. m_repoLinkLabel = new LinkLabel(tr("Repo URL"), QUrl(), 12, this);
  114. m_mainLayout->addWidget(m_repoLinkLabel);
  115. m_copyDownloadLinkLabel = new LinkLabel(tr("Copy Repo URL"));
  116. m_mainLayout->addWidget(m_copyDownloadLinkLabel);
  117. connect(m_copyDownloadLinkLabel, &LinkLabel::clicked, this, &GemRepoInspector::OnCopyDownloadLinkClicked);
  118. m_mainLayout->addSpacing(5);
  119. // Repo summary
  120. m_summaryLabel = new QLabel();
  121. m_summaryLabel->setObjectName("gemRepoInspectorBodyLabel");
  122. m_summaryLabel->setWordWrap(true);
  123. m_summaryLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
  124. m_summaryLabel->setOpenExternalLinks(true);
  125. m_mainLayout->addWidget(m_summaryLabel);
  126. m_mainLayout->addSpacing(20);
  127. // Separating line
  128. QFrame* hLine = new QFrame();
  129. hLine->setFrameShape(QFrame::HLine);
  130. hLine->setObjectName("horizontalSeparatingLine");
  131. m_mainLayout->addWidget(hLine);
  132. m_mainLayout->addSpacing(10);
  133. // Additional information
  134. m_addInfoTitleLabel = new QLabel();
  135. m_addInfoTitleLabel->setObjectName("gemRepoInspectorAddInfoTitleLabel");
  136. m_addInfoTitleLabel->setText(tr("Additional Information"));
  137. m_mainLayout->addWidget(m_addInfoTitleLabel);
  138. m_addInfoTextLabel = new QLabel();
  139. m_addInfoTextLabel->setObjectName("gemRepoInspectorBodyLabel");
  140. m_addInfoTextLabel->setWordWrap(true);
  141. m_addInfoTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
  142. m_addInfoTextLabel->setOpenExternalLinks(true);
  143. m_mainLayout->addWidget(m_addInfoTextLabel);
  144. // Conditional spacing for additional info section
  145. m_addInfoSpacer = new QSpacerItem(0, 20, QSizePolicy::Fixed);
  146. m_mainLayout->addSpacerItem(m_addInfoSpacer);
  147. // Included Gems
  148. m_includedGems = new GemsSubWidget();
  149. m_mainLayout->addWidget(m_includedGems);
  150. m_includedProjects = new GemsSubWidget();
  151. m_mainLayout->addWidget(m_includedProjects);
  152. m_includedTemplates = new GemsSubWidget();
  153. m_mainLayout->addWidget(m_includedTemplates);
  154. m_mainLayout->addSpacing(20);
  155. m_removeRepoButton = new QPushButton(tr("Remove"));
  156. m_removeRepoButton->setProperty("danger", true);
  157. m_mainLayout->addWidget(m_removeRepoButton);
  158. connect(m_removeRepoButton, &QPushButton::clicked, this , [this]{ emit RemoveRepo(m_curModelIndex); });
  159. }
  160. void GemRepoInspector::OnCopyDownloadLinkClicked()
  161. {
  162. const auto& url = m_repoLinkLabel->GetUrl();
  163. if (!url.toString().isEmpty())
  164. {
  165. if(QClipboard* clipboard = QGuiApplication::clipboard(); clipboard != nullptr)
  166. {
  167. clipboard->setText(url.toString());
  168. emit ShowToastNotification(tr("%1 URL copied to clipboard").arg(m_nameLabel->text()));
  169. }
  170. else
  171. {
  172. emit ShowToastNotification("Failed to copy URL to clipboard");
  173. }
  174. }
  175. }
  176. } // namespace O3DE::ProjectManager