/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #pragma once #include "CloudFormationTemplateDetailWidget.h" #include class CloudFormationTemplateResourceDetailWidget : public CloudFormationTemplateDetailWidget { public: CloudFormationTemplateResourceDetailWidget(ResourceManagementView* view, QSharedPointer templateModel, const QString& resourceSection) : CloudFormationTemplateDetailWidget{view, templateModel} , m_resourceSection{resourceSection} { m_textEdit->setPlainText(GetDisplayedContent()); } void show() override { auto deleteButton = m_view->EnableDeleteButton(tr("Delete the resource from the local configuration")); connectUntilHidden(deleteButton, &QPushButton::clicked, this, &CloudFormationTemplateResourceDetailWidget::OnDeleteResourceRequested); CloudFormationTemplateDetailWidget::show(); } QMenu* GetTreeContextMenu() override { auto menu = new ToolTipMenu {}; auto deleteResource = menu->addAction("Delete resource"); deleteResource->setToolTip(tr("Delete the resource from the local configuration")); connectUntilDeleted(deleteResource, &QAction::triggered, this, &CloudFormationTemplateResourceDetailWidget::OnDeleteResourceRequested); menu->addSeparator(); auto saveFile = menu->addAction("Save file"); saveFile->setToolTip(m_view->m_menuSave->toolTip()); saveFile->setEnabled(ShouldAllowSave()); connectUntilDeleted(saveFile, &QAction::triggered, this, &FileContentDetailWidget::OnSaveRequested); auto openFile = menu->addAction("Open in script editor"); openFile->setToolTip(tr("Open file in the default script editor.")); connectUntilDeleted(openFile, &QAction::triggered, this, &FileContentDetailWidget::OnOpenInScriptEditor); auto openPathInExplorer = menu->addAction("View in Explorer"); openPathInExplorer->setToolTip(tr("View the file in Windows Explorer.")); connectUntilDeleted(openPathInExplorer, &QAction::triggered, this, &FileContentDetailWidget::OnOpenLocationInExplorer); menu->addSeparator(); auto copyPathToClipboard = menu->addAction("Copy path to clipboard"); copyPathToClipboard->setToolTip(tr("Copy the file's path to the clipboard.")); connectUntilDeleted(copyPathToClipboard, &QAction::triggered, this, &FileContentDetailWidget::OnCopyPathToClipboard); QString functionId = GetLambdaFunctionId(m_resourceSection); if (functionId != "") { auto uploadCode = menu->addAction("Upload Lambda function code"); uploadCode->setToolTip("Upload the Lambda function code without a full feature stack update."); connectUntilDeleted(uploadCode, &QAction::triggered, this, &CloudFormationTemplateResourceDetailWidget::OnUploadCode); auto viewCloudWatchLogs = menu->addAction("View Cloud Watch Logs"); viewCloudWatchLogs->setToolTip(tr("View the Cloud Watch logs generated by the lambda function.")); QString destString = "https://console.aws.amazon.com/"; destString += "cloudwatch/?#"; destString += "logStream:group=/aws/lambda/" + functionId; connectUntilDeleted(viewCloudWatchLogs, &QAction::triggered, this, [destString]() { GetIEditor()->LaunchAWSConsole(destString); }); } return menu; } QString GetLambdaFunctionId(QString resourceSection) { QSharedPointer stackStatusModel = GetTemplateModel()->GetStackStatusModel(); QString selectedFunctionId = ""; if (stackStatusModel) { QSharedPointer stackResourcesModel = stackStatusModel->GetStackResourcesModel(); QList resourceNameIndexList = stackResourcesModel->findItems(resourceSection, Qt::MatchExactly, IStackResourcesModel::NameColumn); if (!resourceNameIndexList.isEmpty()) { QModelIndex resourceNameIndex = stackResourcesModel->indexFromItem(resourceNameIndexList[0]); int row = resourceNameIndex.row(); if (stackResourcesModel->item(row, IStackResourcesModel::ResourceTypeColumn)->text() == "AWS::Lambda::Function") selectedFunctionId = stackResourcesModel->data(stackResourcesModel->index(row, IStackResourcesModel::PhysicalResourceIdColumn), Qt::ToolTipRole).toString(); } } return selectedFunctionId; } void OnUploadCode() { QSharedPointer stackStatusModel = GetTemplateModel()->GetStackStatusModel(); m_view->UploadLambdaCode(stackStatusModel, m_resourceSection); } protected: virtual void UpdateModifiedContent() override { if (m_textEdit && m_textEdit->IsModified()) { UpdateResourceContent(); } } virtual QString GetDisplayedContent() const override { return GetTemplateModel()->GetResourceContent(m_resourceSection, true); } void UpdateResourceContent() { GetTemplateModel()->ReadResources(m_textEdit->toPlainText()); } void OnDeleteResourceRequested() { QDialog dialog { m_view, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::Dialog }; dialog.setWindowTitle("Delete resource"); QVBoxLayout* queryLayout = new QVBoxLayout; QFrame* queryFrame = new QFrame; queryLayout->addWidget(queryFrame); QVBoxLayout* frameLayout = new QVBoxLayout; queryFrame->setLayout(frameLayout); QString deleteString("Delete the \"" + m_resourceSection + "\" resource?"); QLabel* queryLabel = new QLabel(deleteString); frameLayout->addWidget(queryLabel); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal); queryLayout->addWidget(buttonBox); QObject::connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); QObject::connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); dialog.setLayout(queryLayout); if (dialog.exec() == QDialog::Accepted) { AttemptDeleteResource(m_resourceSection); } } void AttemptDeleteResource(const QString& resourceSection) { QObject::connect(&*GetSourceControlModel(), &IFileSourceControlModel::SourceControlStatusUpdated, this, [resourceSection, this]() { CloudFormationTemplateResourceDetailWidget::AttemptDeleteSourceUpdated(resourceSection); }); AWSResourceManager::RequestUpdateSourceModel(GetSourceControlModel(), GetTemplateModel()); } void AttemptDeleteSourceUpdated(const QString& resourceSection) { QObject::disconnect(&*GetSourceControlModel(), &IFileSourceControlModel::SourceControlStatusUpdated, this, 0); if (FileNeedsCheckout()) { auto reply = QMessageBox::warning( this, "Check out file", "This file needs to be checked out before it can be saved. Check out now?", QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::Yes) { QObject::connect(&*GetSourceControlModel(), &IFileSourceControlModel::SourceControlStatusChanged, this, [resourceSection, this]() {CloudFormationTemplateResourceDetailWidget::FinishDeleteResource(resourceSection); }); DoRequestEdit(); } return; } FinishDeleteResource(resourceSection); ; } void FinishDeleteResource(const QString& resourceSection) { QObject::disconnect(&*GetSourceControlModel(), &IFileSourceControlModel::SourceControlStatusChanged, this, 0); GetTemplateModel()->DeleteResource(resourceSection); DoSaveAction(); m_view->SelectDetailWidget(); } virtual void DoSaveAction() override { if (ShouldAllowSave()) { UpdateResourceContent(); if (!GetTemplateModel()->Save()) { ShowSaveFailedDialog(); } } UpdateFileSaveControls(); m_view->SelectDetailWidget(); } QString GetResourceType() const { return ResourceParsing::GetResourceTypeFromFirstObject(m_textEdit->toPlainText()); } virtual QString GetHelpLabelText() const { QString typeString = GetResourceType(); if (!typeString.length()) { return "Learn more about the syntax used to add and edit AWS resources to your game in the AWS CloudFormation documentation."; } if (typeString == "AWS::DynamoDB::Table") { return "Learn about adding a DynamoDB table to your game in the AWS DynamoDB documentation."; } else if (typeString == "AWS::S3::Bucket") { return "Learn about adding an S3 bucket to your game in the AWS S3 documentation."; } else if (typeString == "AWS::SQS::Queue") { return "Learn about adding an SQS Queue to your game in the AWS SQS documentation."; } else if (typeString == "AWS::SNS::Topc") { return "Learn about adding an S3 bucket to your game in the AWS SNS documentation."; } else if (typeString == "AWS::Lambda::Function") { return "Learn about adding a Lambda Function to your game in the AWS Lambda documentation."; } else if (typeString == "AWS::GameLift::Fleet") { return "Learn about adding a GameLift Fleet to your game in the Amazon GameLift Fleet documentation."; } else if (typeString == "AWS::GameLift::Build") { return "Learn about adding a GameLift Build to your game in the Amazon GameLift Build documentation."; } else if (typeString == "AWS::GameLift::Alias") { return "Learn about adding a GameLift Alias to your game in the Amazon GameLift Alias documentation."; } return "Learn more about the syntax used to add and edit AWS resources to your game in the AWS CloudFormation documentation."; } private: QString m_resourceSection; };