Merge branch 'stabilization/2106' into Atom/dmcdiar/ATOM-15951
This commit is contained in:
@@ -47,7 +47,7 @@ set(ENABLED_GEMS
|
||||
LmbrCentral
|
||||
LyShine
|
||||
HttpRequestor
|
||||
Atom_AtomBridge
|
||||
Atom
|
||||
AWSCore
|
||||
AWSClientAuth
|
||||
AWSMetrics
|
||||
|
||||
@@ -51,4 +51,18 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::GameLauncherWithGPU
|
||||
TEST_SUITE sandbox
|
||||
TEST_REQUIRES gpu
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_GameLauncher_EnterExitGameMode_Works.py
|
||||
TIMEOUT 100
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::PythonBindingsExample
|
||||
Legacy::Editor
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -111,7 +111,6 @@ ly_add_target(
|
||||
AZ::AzCore
|
||||
AZ::AzToolsFramework
|
||||
Gem::LmbrCentral.Static
|
||||
Legacy::NewsShared
|
||||
AZ::AWSNativeSDKInit
|
||||
AZ::AtomCore
|
||||
Gem::Atom_RPI.Edit
|
||||
|
||||
@@ -463,25 +463,7 @@ void EditorViewportWidget::Update()
|
||||
SetFOV(cameraState.m_fovOrZoom);
|
||||
m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip);
|
||||
}
|
||||
else if (!ed_useNewCameraSystem)
|
||||
{
|
||||
m_renderViewport->GetViewportContext()->SetCameraTransform(LYTransformToAZTransform(m_Camera.GetMatrix()));
|
||||
}
|
||||
|
||||
// Don't override the game mode FOV
|
||||
if (!GetIEditor()->IsInGameMode())
|
||||
{
|
||||
AZ::Matrix4x4 clipMatrix;
|
||||
AZ::MakePerspectiveFovMatrixRH(
|
||||
clipMatrix,
|
||||
GetFOV(),
|
||||
aznumeric_cast<float>(width()) / aznumeric_cast<float>(height()),
|
||||
m_Camera.GetNearPlane(),
|
||||
m_Camera.GetFarPlane(),
|
||||
true
|
||||
);
|
||||
m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix);
|
||||
}
|
||||
// Reset the camera update flag now that we're finished updating our viewport context
|
||||
m_updateCameraPositionNextTick = false;
|
||||
|
||||
@@ -637,7 +619,6 @@ void EditorViewportWidget::SetViewEntity(const AZ::EntityId& viewEntityId, bool
|
||||
void EditorViewportWidget::ResetToViewSourceType(const ViewSourceType& viewSourceType)
|
||||
{
|
||||
LockCameraMovement(true);
|
||||
m_pCameraFOVVariable = nullptr;
|
||||
m_viewEntityId.SetInvalid();
|
||||
m_cameraObjectId = GUID_NULL;
|
||||
m_viewSourceType = viewSourceType;
|
||||
@@ -2416,13 +2397,26 @@ void EditorViewportWidget::CenterOnSliceInstance()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::SetFOV(float fov)
|
||||
{
|
||||
if (m_pCameraFOVVariable)
|
||||
if (m_viewEntityId.IsValid())
|
||||
{
|
||||
m_pCameraFOVVariable->Set(fov);
|
||||
Camera::CameraRequestBus::Event(m_viewEntityId, &Camera::CameraComponentRequests::SetFov, AZ::RadToDeg(fov));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_camFOV = fov;
|
||||
// Set the active camera's FOV
|
||||
{
|
||||
AZ::Matrix4x4 clipMatrix;
|
||||
AZ::MakePerspectiveFovMatrixRH(
|
||||
clipMatrix,
|
||||
GetFOV(),
|
||||
aznumeric_cast<float>(width()) / aznumeric_cast<float>(height()),
|
||||
m_Camera.GetNearPlane(),
|
||||
m_Camera.GetFarPlane(),
|
||||
true
|
||||
);
|
||||
m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_viewPane)
|
||||
@@ -2449,13 +2443,7 @@ float EditorViewportWidget::GetFOV() const
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pCameraFOVVariable)
|
||||
{
|
||||
float fov;
|
||||
m_pCameraFOVVariable->Get(fov);
|
||||
return fov;
|
||||
}
|
||||
else if (m_viewEntityId.IsValid())
|
||||
if (m_viewEntityId.IsValid())
|
||||
{
|
||||
float fov = AZ::RadToDeg(m_camFOV);
|
||||
Camera::CameraRequestBus::EventResult(fov, m_viewEntityId, &Camera::CameraComponentRequests::GetFov);
|
||||
|
||||
@@ -505,7 +505,6 @@ protected:
|
||||
|
||||
CPredefinedAspectRatios m_predefinedAspectRatios;
|
||||
|
||||
IVariable* m_pCameraFOVVariable = nullptr;
|
||||
bool m_bCursorHidden = false;
|
||||
|
||||
void OnMenuResolutionCustom();
|
||||
|
||||
@@ -41,6 +41,7 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/Application/Ticker.h>
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
#include <AzToolsFramework/API/EditorAnimationSystemRequestBus.h>
|
||||
#include <AzToolsFramework/SourceControl/QtSourceControlNotificationHandler.h>
|
||||
#include <AzToolsFramework/PythonTerminal/ScriptTermDialog.h>
|
||||
@@ -93,6 +94,8 @@ AZ_POP_DISABLE_WARNING
|
||||
#include "AssetEditor/AssetEditorWindow.h"
|
||||
#include "ActionManager.h"
|
||||
|
||||
#include <ImGuiBus.h>
|
||||
|
||||
using namespace AZ;
|
||||
using namespace AzQtComponents;
|
||||
using namespace AzToolsFramework;
|
||||
@@ -489,6 +492,16 @@ void MainWindow::Initialize()
|
||||
ActionOverrideRequestBus::Event(
|
||||
GetEntityContextId(), &ActionOverrideRequests::SetupActionOverrideHandler, this);
|
||||
|
||||
if (auto imGuiManager = AZ::Interface<ImGui::IImGuiManager>::Get())
|
||||
{
|
||||
auto handleImGuiStateChangeFn = [](bool enabled)
|
||||
{
|
||||
EditorWindowUIRequestBus::Broadcast(&EditorWindowUIRequests::SetEditorUiEnabled, enabled);
|
||||
};
|
||||
m_handleImGuiStateChangeHandler = ImGui::IImGuiManager::ImGuiSetEnabledEvent::Handler(handleImGuiStateChangeFn);
|
||||
imGuiManager->ConnectImGuiSetEnabledChangedHandler(m_handleImGuiStateChangeHandler);
|
||||
}
|
||||
|
||||
AzToolsFramework::EditorEventsBus::Broadcast(&AzToolsFramework::EditorEvents::NotifyMainWindowInitialized, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -249,6 +249,7 @@ private:
|
||||
|
||||
QPointer<ToolbarCustomizationDialog> m_toolbarCustomizationDialog;
|
||||
QScopedPointer<AzToolsFramework::QtSourceControlNotificationHandler> m_sourceControlNotifHandler;
|
||||
AZ::Event<bool>::Handler m_handleImGuiStateChangeHandler;
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
static MainWindow* m_instance;
|
||||
|
||||
@@ -27,6 +27,7 @@ ly_add_target(
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::Qt::Core
|
||||
3rdParty::Qt::Widgets
|
||||
AZ::AzCore
|
||||
AZ::AzToolsFramework
|
||||
Legacy::CryCommon
|
||||
|
||||
+2
@@ -66,3 +66,5 @@ namespace EntityOutliner
|
||||
emit OnOptionToggled(DisplayOption::AutoExpand, checked);
|
||||
}
|
||||
}
|
||||
|
||||
#include <UI/Outliner/moc_OutlinerDisplayOptionsMenu.cpp>
|
||||
|
||||
@@ -269,10 +269,12 @@ OutlinerWidget::OutlinerWidget(QWidget* pParent, Qt::WindowFlags flags)
|
||||
AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusConnect(
|
||||
AzToolsFramework::GetEntityContextId());
|
||||
AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorWindowUIRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
OutlinerWidget::~OutlinerWidget()
|
||||
{
|
||||
AzToolsFramework::EditorWindowUIRequestBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::EditorPickModeNotificationBus::Handler::BusDisconnect();
|
||||
@@ -1321,16 +1323,25 @@ static void SetEntityOutlinerState(Ui::OutlinerWidgetUI* entityOutlinerUi, const
|
||||
AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on);
|
||||
}
|
||||
|
||||
void OutlinerWidget::EnableUi(bool enable)
|
||||
{
|
||||
SetEntityOutlinerState(m_gui, enable);
|
||||
setEnabled(enable);
|
||||
}
|
||||
|
||||
void OutlinerWidget::SetEditorUiEnabled(bool enable)
|
||||
{
|
||||
EnableUi(enable);
|
||||
}
|
||||
|
||||
void OutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
SetEntityOutlinerState(m_gui, false);
|
||||
setEnabled(false);
|
||||
EnableUi(false);
|
||||
}
|
||||
|
||||
void OutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
setEnabled(true);
|
||||
SetEntityOutlinerState(m_gui, true);
|
||||
EnableUi(true);
|
||||
}
|
||||
|
||||
void OutlinerWidget::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, AZ::SliceComponent::SliceInstanceAddress& sliceAddress, const AzFramework::SliceInstantiationTicket& /*ticket*/)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/base.h>
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
@@ -57,6 +58,7 @@ class OutlinerWidget
|
||||
, private AzToolsFramework::SliceEditorEntityOwnershipServiceNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorEntityInfoNotificationBus::Handler
|
||||
, private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorWindowUIRequestBus::Handler
|
||||
{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
@@ -106,6 +108,9 @@ private:
|
||||
void EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
|
||||
void LeftComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes) override;
|
||||
|
||||
// EditorWindowUIRequestBus overrides
|
||||
void SetEditorUiEnabled(bool enable) override;
|
||||
|
||||
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
|
||||
template <class EntityIdCollection>
|
||||
QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds);
|
||||
@@ -171,6 +176,7 @@ private:
|
||||
AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const;
|
||||
QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const;
|
||||
void ExtractEntityIdsFromSelection(const QItemSelection& selection, AzToolsFramework::EntityIdList& entityIdList) const;
|
||||
void EnableUi(bool enable);
|
||||
|
||||
// AzToolsFramework::OutlinerModelNotificationBus::Handler
|
||||
// Receive notification from the outliner model that we should scroll
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
; EditorCommon.def : Declares the module parameters for the DLL.
|
||||
|
||||
LIBRARY
|
||||
|
||||
EXPORTS
|
||||
; Explicit exports can go here
|
||||
Binary file not shown.
@@ -23,6 +23,7 @@ ly_add_target(
|
||||
.
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::Qt::Core
|
||||
AZ::AzCore
|
||||
Legacy::CryCommon
|
||||
Legacy::EditorLib
|
||||
|
||||
@@ -17,19 +17,8 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// STL
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CRY Stuff ////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#include <ISystem.h>
|
||||
#include "Util/EditorUtils.h"
|
||||
#include "EditorCoreAPI.h"
|
||||
|
||||
@@ -31,6 +31,8 @@ ly_add_target(
|
||||
.
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::Qt::Core
|
||||
3rdParty::Qt::Widgets
|
||||
AZ::AzCore
|
||||
Legacy::CryCommon
|
||||
Legacy::EditorLib
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<QtMOC>
|
||||
<OutputFileName>%(RootDir)%(Directory)%(FileName).moc</OutputFileName>
|
||||
<CommandLineTemplate>$(QTDIR)\bin\moc.exe [AllOptions] [Inputs]</CommandLineTemplate>
|
||||
<ExecutionDescription>Moc'ing %(Filename)%(Extension)...</ExecutionDescription>
|
||||
</QtMOC>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<PropertyPageSchema
|
||||
Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
|
||||
<AvailableItemName Include="QtMOC">
|
||||
<Targets>_QtMOC</Targets>
|
||||
</AvailableItemName>
|
||||
</ItemGroup>
|
||||
<UsingTask
|
||||
TaskName="QtMOC"
|
||||
TaskFactory="XamlTaskFactory"
|
||||
AssemblyName="Microsoft.Build.Tasks.v4.0">
|
||||
<Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>
|
||||
</UsingTask>
|
||||
<Target
|
||||
Name="_QtMOC"
|
||||
BeforeTargets="ClCompile"
|
||||
AfterTargets="CustomBuild"
|
||||
Condition="'@(QtMOC)' != ''"
|
||||
Outputs="%(QtMOC.OutputFileName)"
|
||||
Inputs="%(QtMOC.Identity);$(MSBuildProjectFile)"
|
||||
DependsOnTargets="_SelectedFiles">
|
||||
<ItemGroup Condition="'@(SelectedFiles)' != ''">
|
||||
<QtMOC Remove="@(QtMOC)" Condition="'%(Identity)' != '@(SelectedFiles)'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMOC_tlog Include="%(QtMOC.OutputFileName)" Condition="'%(QtMOC.OutputFileName)' != '' and '%(QtMOC.ExcludedFromBuild)' != 'true'">
|
||||
<Source>@(QtMOC, '|')</Source>
|
||||
</QtMOC_tlog>
|
||||
</ItemGroup>
|
||||
<Message
|
||||
Importance="High"
|
||||
Text="%(QtMOC.ExecutionDescription)" />
|
||||
<WriteLinesToFile
|
||||
Condition="'@(QtMOC_tlog)' != '' and '%(QtMOC_tlog.ExcludedFromBuild)' != 'true'"
|
||||
File="$(IntDir)$(ProjectName).moc.1.tlog"
|
||||
Lines="^%(QtMOC_tlog.Source);@(QtMOC_tlog->'%(Fullpath)')"/>
|
||||
<QtMOC
|
||||
Condition="'@(QtMOC)' != '' and '%(QtMOC.ExcludedFromBuild)' != 'true'"
|
||||
CommandLineTemplate="%(QtMOC.CommandLineTemplate)"
|
||||
OutputFileName="%(QtMOC.OutputFileName)"
|
||||
AdditionalOptions="%(QtMOC.AdditionalOptions)"
|
||||
Inputs="%(QtMOC.Fullpath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||
<Rule
|
||||
Name="QtMOC"
|
||||
PageTemplate="tool"
|
||||
DisplayName="Qt MOC"
|
||||
Order="200">
|
||||
<Rule.DataSource>
|
||||
<DataSource
|
||||
Persistence="ProjectFile"
|
||||
ItemType="QtMOC" />
|
||||
</Rule.DataSource>
|
||||
<Rule.Categories>
|
||||
<Category
|
||||
Name="General">
|
||||
<Category.DisplayName>
|
||||
<sys:String>General</sys:String>
|
||||
</Category.DisplayName>
|
||||
</Category>
|
||||
<Category
|
||||
Name="Command Line"
|
||||
Subtype="CommandLine">
|
||||
<Category.DisplayName>
|
||||
<sys:String>Command Line</sys:String>
|
||||
</Category.DisplayName>
|
||||
</Category>
|
||||
</Rule.Categories>
|
||||
<StringProperty
|
||||
Name="OutputFileName"
|
||||
Category="General"
|
||||
DisplayName="Output File Name"
|
||||
Description="Specifies the name of the output file."
|
||||
Switch="-o"[value]""/>
|
||||
<StringProperty
|
||||
Name="Inputs"
|
||||
Category="Command Line"
|
||||
IsRequired="true">
|
||||
<StringProperty.DataSource>
|
||||
<DataSource
|
||||
Persistence="ProjectFile"
|
||||
ItemType="QtMOC"
|
||||
SourceType="Item" />
|
||||
</StringProperty.DataSource>
|
||||
</StringProperty>
|
||||
<StringProperty
|
||||
Name="CommandLineTemplate"
|
||||
DisplayName="Command Line"
|
||||
Visible="False"
|
||||
IncludeInCommandLine="False" />
|
||||
<StringProperty
|
||||
Name="ExecutionDescription"
|
||||
DisplayName="Execution Description"
|
||||
IncludeInCommandLine="False"
|
||||
Visible="False" />
|
||||
<StringProperty
|
||||
Subtype="AdditionalOptions"
|
||||
Name="AdditionalOptions"
|
||||
Category="Command Line">
|
||||
<StringProperty.DisplayName>
|
||||
<sys:String>Additional Options</sys:String>
|
||||
</StringProperty.DisplayName>
|
||||
<StringProperty.Description>
|
||||
<sys:String>Additional Options</sys:String>
|
||||
</StringProperty.Description>
|
||||
</StringProperty>
|
||||
</Rule>
|
||||
<ItemType
|
||||
Name="QtMOC"
|
||||
DisplayName="Qt MOC" />
|
||||
<ContentType
|
||||
Name="QtMOC"
|
||||
DisplayName="Qt MOC"
|
||||
ItemType="QtMOC" />
|
||||
</ProjectSchemaDefinitions>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<QtRCC>
|
||||
<OutputFileName>%(RootDir)%(Directory)rcc_%(FileName).h</OutputFileName>
|
||||
<CommandLineTemplate>$(QTDIR)\bin\rcc.exe [AllOptions] [Inputs]</CommandLineTemplate>
|
||||
<ExecutionDescription>Rcc'ing %(Filename)%(Extension)...</ExecutionDescription>
|
||||
</QtRCC>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<PropertyPageSchema
|
||||
Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
|
||||
<AvailableItemName Include="QtRCC">
|
||||
<Targets>_QtRCC</Targets>
|
||||
</AvailableItemName>
|
||||
</ItemGroup>
|
||||
<UsingTask
|
||||
TaskName="QtRCC"
|
||||
TaskFactory="XamlTaskFactory"
|
||||
AssemblyName="Microsoft.Build.Tasks.v4.0">
|
||||
<Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>
|
||||
</UsingTask>
|
||||
<Target
|
||||
Name="_QtRCC"
|
||||
BeforeTargets="ClCompile"
|
||||
AfterTargets="CustomBuild"
|
||||
Condition="'@(QtRCC)' != ''"
|
||||
Outputs="%(QtRCC.OutputFileName)"
|
||||
Inputs="%(QtRCC.Identity);$(MSBuildProjectFile)"
|
||||
DependsOnTargets="_SelectedFiles">
|
||||
<ItemGroup Condition="'@(SelectedFiles)' != ''">
|
||||
<QtRCC Remove="@(QtRCC)" Condition="'%(Identity)' != '@(SelectedFiles)'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRCC_tlog Include="%(QtRCC.OutputFileName)" Condition="'%(QtRCC.OutputFileName)' != '' and '%(QtRCC.ExcludedFromBuild)' != 'true'">
|
||||
<Source>@(QtRCC, '|')</Source>
|
||||
</QtRCC_tlog>
|
||||
</ItemGroup>
|
||||
<Message
|
||||
Importance="High"
|
||||
Text="%(QtRCC.ExecutionDescription)" />
|
||||
<WriteLinesToFile
|
||||
Condition="'@(QtRCC_tlog)' != '' and '%(QtRCC_tlog.ExcludedFromBuild)' != 'true'"
|
||||
File="$(IntDir)$(ProjectName).rcc.1.tlog"
|
||||
Lines="^%(QtRCC_tlog.Source);@(QtRCC_tlog->'%(Fullpath)')"/>
|
||||
<QtRCC
|
||||
Condition="'@(QtRCC)' != '' and '%(QtRCC.ExcludedFromBuild)' != 'true'"
|
||||
CommandLineTemplate="%(QtRCC.CommandLineTemplate)"
|
||||
OutputFileName="%(QtRCC.OutputFileName)"
|
||||
AdditionalOptions="%(QtRCC.AdditionalOptions)"
|
||||
Inputs="%(QtRCC.Fullpath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||
<Rule
|
||||
Name="QtRCC"
|
||||
PageTemplate="tool"
|
||||
DisplayName="Qt RCC"
|
||||
Order="200">
|
||||
<Rule.DataSource>
|
||||
<DataSource
|
||||
Persistence="ProjectFile"
|
||||
ItemType="QtRCC" />
|
||||
</Rule.DataSource>
|
||||
<Rule.Categories>
|
||||
<Category
|
||||
Name="General">
|
||||
<Category.DisplayName>
|
||||
<sys:String>General</sys:String>
|
||||
</Category.DisplayName>
|
||||
</Category>
|
||||
<Category
|
||||
Name="Command Line"
|
||||
Subtype="CommandLine">
|
||||
<Category.DisplayName>
|
||||
<sys:String>Command Line</sys:String>
|
||||
</Category.DisplayName>
|
||||
</Category>
|
||||
</Rule.Categories>
|
||||
<StringProperty
|
||||
Name="OutputFileName"
|
||||
Category="General"
|
||||
DisplayName="Output File Name"
|
||||
Description="Specifies the name of the output file."
|
||||
Switch="-o "[value]""/>
|
||||
<StringProperty
|
||||
Name="Inputs"
|
||||
Category="Command Line"
|
||||
IsRequired="true">
|
||||
<StringProperty.DataSource>
|
||||
<DataSource
|
||||
Persistence="ProjectFile"
|
||||
ItemType="QtRCC"
|
||||
SourceType="Item" />
|
||||
</StringProperty.DataSource>
|
||||
</StringProperty>
|
||||
<StringProperty
|
||||
Name="CommandLineTemplate"
|
||||
DisplayName="Command Line"
|
||||
Visible="False"
|
||||
IncludeInCommandLine="False" />
|
||||
<StringProperty
|
||||
Name="ExecutionDescription"
|
||||
DisplayName="Execution Description"
|
||||
IncludeInCommandLine="False"
|
||||
Visible="False" />
|
||||
<StringProperty
|
||||
Subtype="AdditionalOptions"
|
||||
Name="AdditionalOptions"
|
||||
Category="Command Line">
|
||||
<StringProperty.DisplayName>
|
||||
<sys:String>Additional Options</sys:String>
|
||||
</StringProperty.DisplayName>
|
||||
<StringProperty.Description>
|
||||
<sys:String>Additional Options</sys:String>
|
||||
</StringProperty.Description>
|
||||
</StringProperty>
|
||||
</Rule>
|
||||
<ItemType
|
||||
Name="QtRCC"
|
||||
DisplayName="Qt RCC" />
|
||||
<ContentType
|
||||
Name="QtRCC"
|
||||
DisplayName="Qt RCC"
|
||||
ItemType="QtRCC" />
|
||||
</ProjectSchemaDefinitions>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemDefinitionGroup>
|
||||
<QtUIC>
|
||||
<OutputFileName>%(RootDir)%(Directory)ui_%(FileName).h</OutputFileName>
|
||||
<CommandLineTemplate>$(QTDIR)\bin\uic.exe [AllOptions] [Inputs]</CommandLineTemplate>
|
||||
<ExecutionDescription>Uic'ing %(Filename)%(Extension)...</ExecutionDescription>
|
||||
</QtUIC>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<PropertyPageSchema
|
||||
Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
|
||||
<AvailableItemName Include="QtUIC">
|
||||
<Targets>_QtUIC</Targets>
|
||||
</AvailableItemName>
|
||||
</ItemGroup>
|
||||
<UsingTask
|
||||
TaskName="QtUIC"
|
||||
TaskFactory="XamlTaskFactory"
|
||||
AssemblyName="Microsoft.Build.Tasks.v4.0">
|
||||
<Task>$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml</Task>
|
||||
</UsingTask>
|
||||
<Target
|
||||
Name="_QtUIC"
|
||||
BeforeTargets="ClCompile"
|
||||
AfterTargets="CustomBuild"
|
||||
Condition="'@(QtUIC)' != ''"
|
||||
Outputs="%(QtUIC.OutputFileName)"
|
||||
Inputs="%(QtUIC.Identity);$(MSBuildProjectFile)"
|
||||
DependsOnTargets="_SelectedFiles">
|
||||
<ItemGroup Condition="'@(SelectedFiles)' != ''">
|
||||
<QtUIC Remove="@(QtUIC)" Condition="'%(Identity)' != '@(SelectedFiles)'" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUIC_tlog Include="%(QtUIC.OutputFileName)" Condition="'%(QtUIC.OutputFileName)' != '' and '%(QtUIC.ExcludedFromBuild)' != 'true'">
|
||||
<Source>@(QtUIC, '|')</Source>
|
||||
</QtUIC_tlog>
|
||||
</ItemGroup>
|
||||
<Message
|
||||
Importance="High"
|
||||
Text="%(QtUIC.ExecutionDescription)" />
|
||||
<WriteLinesToFile
|
||||
Condition="'@(QtUIC_tlog)' != '' and '%(QtUIC_tlog.ExcludedFromBuild)' != 'true'"
|
||||
File="$(IntDir)$(ProjectName).uic.1.tlog"
|
||||
Lines="^%(QtUIC_tlog.Source);@(QtUIC_tlog->'%(Fullpath)')"/>
|
||||
<QtUIC
|
||||
Condition="'@(QtUIC)' != '' and '%(QtUIC.ExcludedFromBuild)' != 'true'"
|
||||
CommandLineTemplate="%(QtUIC.CommandLineTemplate)"
|
||||
OutputFileName="%(QtUIC.OutputFileName)"
|
||||
AdditionalOptions="%(QtUIC.AdditionalOptions)"
|
||||
Inputs="%(QtUIC.Fullpath)" /> <!-- CRC TODO: Should use identity instead? Inputs="%(QtUIC.Identity)" /> -->
|
||||
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||
<Rule
|
||||
Name="QtUIC"
|
||||
PageTemplate="tool"
|
||||
DisplayName="Qt UIC"
|
||||
Order="200">
|
||||
<Rule.DataSource>
|
||||
<DataSource
|
||||
Persistence="ProjectFile"
|
||||
ItemType="QtUIC" />
|
||||
</Rule.DataSource>
|
||||
<Rule.Categories>
|
||||
<Category
|
||||
Name="General">
|
||||
<Category.DisplayName>
|
||||
<sys:String>General</sys:String>
|
||||
</Category.DisplayName>
|
||||
</Category>
|
||||
<Category
|
||||
Name="Command Line"
|
||||
Subtype="CommandLine">
|
||||
<Category.DisplayName>
|
||||
<sys:String>Command Line</sys:String>
|
||||
</Category.DisplayName>
|
||||
</Category>
|
||||
</Rule.Categories>
|
||||
<StringProperty
|
||||
Name="OutputFileName"
|
||||
Category="General"
|
||||
DisplayName="Output File Name"
|
||||
Description="Specifies the name of the output file."
|
||||
Switch="-o "[value]""/>
|
||||
<StringProperty
|
||||
Name="Inputs"
|
||||
Category="Command Line"
|
||||
IsRequired="true">
|
||||
<StringProperty.DataSource>
|
||||
<DataSource
|
||||
Persistence="ProjectFile"
|
||||
ItemType="QtUIC"
|
||||
SourceType="Item" />
|
||||
</StringProperty.DataSource>
|
||||
</StringProperty>
|
||||
<StringProperty
|
||||
Name="CommandLineTemplate"
|
||||
DisplayName="Command Line"
|
||||
Visible="False"
|
||||
IncludeInCommandLine="False" />
|
||||
<StringProperty
|
||||
Name="ExecutionDescription"
|
||||
DisplayName="Execution Description"
|
||||
IncludeInCommandLine="False"
|
||||
Visible="False" />
|
||||
<StringProperty
|
||||
Subtype="AdditionalOptions"
|
||||
Name="AdditionalOptions"
|
||||
Category="Command Line">
|
||||
<StringProperty.DisplayName>
|
||||
<sys:String>Additional Options</sys:String>
|
||||
</StringProperty.DisplayName>
|
||||
<StringProperty.Description>
|
||||
<sys:String>Additional Options</sys:String>
|
||||
</StringProperty.Description>
|
||||
</StringProperty>
|
||||
</Rule>
|
||||
<ItemType
|
||||
Name="QtUIC"
|
||||
DisplayName="Qt UIC" />
|
||||
<ContentType
|
||||
Name="QtUIC"
|
||||
DisplayName="Qt UIC"
|
||||
ItemType="QtUIC" />
|
||||
</ProjectSchemaDefinitions>
|
||||
@@ -525,6 +525,7 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
|
||||
|
||||
// view pane manager is interested when we enter/exit ComponentMode
|
||||
m_componentModeNotifications.BusConnect(AzToolsFramework::GetEntityContextId());
|
||||
m_windowRequest.BusConnect();
|
||||
|
||||
m_componentModeNotifications.SetEnteredComponentModeFunc(
|
||||
[this](const AZStd::vector<AZ::Uuid>& /*componentModeTypes*/)
|
||||
@@ -545,10 +546,23 @@ QtViewPaneManager::QtViewPaneManager(QObject* parent)
|
||||
AzQtComponents::SetWidgetInteractEnabled(widget, on);
|
||||
});
|
||||
});
|
||||
|
||||
m_windowRequest.SetEnableEditorUiFunc(
|
||||
[this](bool enable)
|
||||
{
|
||||
// gray out panels when entering ImGui mode
|
||||
SetDefaultActionsEnabled(
|
||||
enable, m_registeredPanes,
|
||||
[](QWidget* widget, bool on)
|
||||
{
|
||||
AzQtComponents::SetWidgetInteractEnabled(widget, on);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
QtViewPaneManager::~QtViewPaneManager()
|
||||
{
|
||||
m_windowRequest.BusDisconnect();
|
||||
m_componentModeNotifications.BusDisconnect();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <AzQtComponents/Components/StyledDockWidget.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
@@ -249,8 +250,12 @@ private:
|
||||
QPointer<AzQtComponents::FancyDocking> m_advancedDockManager;
|
||||
|
||||
using EditorComponentModeNotificationBusImpl = AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBusImpl;
|
||||
EditorComponentModeNotificationBusImpl m_componentModeNotifications; /**< Helper for EditorComponentModeNotificationBus so
|
||||
* QtViewPaneManager does not need to inherit directly from it. */
|
||||
EditorComponentModeNotificationBusImpl m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so
|
||||
//!< QtViewPaneManager does not need to inherit directly from it. */
|
||||
|
||||
using EditorWindowRequestBusImpl = AzToolsFramework::EditorWindowRequestBusImpl;
|
||||
EditorWindowRequestBusImpl m_windowRequest; //!< Helper for EditorWindowRequestBus so
|
||||
//!< QtViewPaneManager does not need to inherit directly from it. */
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
};
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace TrackView
|
||||
bool startedCapture = false;
|
||||
AZ::Render::FrameCaptureRequestBus::BroadcastResult(
|
||||
startedCapture, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback, m_passHierarchy,
|
||||
AZStd::string("Output"), attachmentReadbackCallback);
|
||||
AZStd::string("Output"), attachmentReadbackCallback, AZ::RPI::PassAttachmentReadbackOption::Output);
|
||||
|
||||
return startedCapture;
|
||||
}
|
||||
|
||||
@@ -40,10 +40,6 @@
|
||||
#include "CryEdit.h"
|
||||
#include "LevelFileDialog.h"
|
||||
|
||||
// NewsShared
|
||||
#include <NewsShared/ResourceManagement/ResourceManifest.h> // for News::ResourceManifest
|
||||
#include <NewsShared/Qt/ArticleViewContainer.h> // for News::ArticleViewContainer
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <WelcomeScreen/ui_WelcomeScreenDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QDialog>
|
||||
#include "NewsShared/LogType.h"
|
||||
#include "NewsShared/ErrorCodes.h"
|
||||
#endif
|
||||
|
||||
namespace News {
|
||||
@@ -62,9 +60,6 @@ private:
|
||||
void OnRecentLevelTableItemClicked(const QModelIndex& index);
|
||||
void OnCloseBtnClicked(bool checked);
|
||||
|
||||
void SyncFail(News::ErrorCode error);
|
||||
void SyncSuccess();
|
||||
|
||||
private Q_SLOTS:
|
||||
void previewAreaScrolled();
|
||||
};
|
||||
|
||||
@@ -27,11 +27,17 @@ namespace AZ
|
||||
template <typename... Params>
|
||||
EventHandler<Params...>::EventHandler(const EventHandler& rhs)
|
||||
: m_callback(rhs.m_callback)
|
||||
, m_event(rhs.m_event)
|
||||
{
|
||||
// Copy the callback function, then perform a Connect with the new event
|
||||
if (rhs.m_event)
|
||||
// Copy the callback and event, then perform a Connect to the event
|
||||
if (m_callback && m_event)
|
||||
{
|
||||
rhs.m_event->Connect(*this);
|
||||
m_event->Connect(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It was not possible to connect to the event, set it to nullptr
|
||||
m_event = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,9 +71,16 @@ namespace AZ
|
||||
{
|
||||
Disconnect();
|
||||
m_callback = rhs.m_callback;
|
||||
if (rhs.m_event)
|
||||
m_event = rhs.m_event;
|
||||
// Copy the callback and event, then perform a Connect to the event
|
||||
if (m_callback && m_event)
|
||||
{
|
||||
rhs.m_event->Connect(*this);
|
||||
m_event->Connect(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It was not possible to connect to the event, set it to nullptr
|
||||
m_event = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,8 +145,13 @@ namespace AZ
|
||||
// also needs to be an overload for every version because they all represent overloads for different non-types.
|
||||
namespace AzGenericTypeInfo
|
||||
{
|
||||
template<typename...>
|
||||
constexpr bool false_v = false;
|
||||
/// Needs to match declared parameter type.
|
||||
template <template <typename...> class> constexpr bool false_v1 = false;
|
||||
template <template <AZStd::size_t...> class> constexpr bool false_v2 = false;
|
||||
template <template <typename, AZStd::size_t> class> constexpr bool false_v3 = false;
|
||||
template <template <typename, typename, AZStd::size_t> class> constexpr bool false_v4 = false;
|
||||
template <template <typename, typename, typename, AZStd::size_t> class> constexpr bool false_v5 = false;
|
||||
template <template <typename, AZStd::size_t, typename> class> constexpr bool false_v6 = false;
|
||||
|
||||
template<typename T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
@@ -157,7 +162,7 @@ namespace AZ
|
||||
template<template<typename...> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v1<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -165,7 +170,7 @@ namespace AZ
|
||||
template<template<AZStd::size_t...> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v2<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -173,7 +178,7 @@ namespace AZ
|
||||
template<template<typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v3<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -181,7 +186,7 @@ namespace AZ
|
||||
template<template<typename, typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v4<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -189,7 +194,7 @@ namespace AZ
|
||||
template<template<typename, typename, typename, AZStd::size_t> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v5<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
@@ -197,7 +202,7 @@ namespace AZ
|
||||
template<template<typename, AZStd::size_t, typename> class T>
|
||||
inline const AZ::TypeId& Uuid()
|
||||
{
|
||||
static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static_assert(false_v6<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
|
||||
static const AZ::TypeId s_uuid = AZ::TypeId::CreateNull();
|
||||
return s_uuid;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,15 @@ namespace AZ
|
||||
{
|
||||
if (m_hashes.size() < m_hashes.max_size())
|
||||
{
|
||||
constexpr size_t MaxTagSize = TagName{}.max_size();
|
||||
if (specialization.size() > MaxTagSize)
|
||||
{
|
||||
AZ_Error("Settings Registry", false, R"(Cannot append Specialization tag of "%.*s.")"
|
||||
" It is longer than the MaxTagNameSize of %zu", AZ_STRING_ARG(specialization),
|
||||
MaxTagSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_names.push_back(TagName{ specialization });
|
||||
TagName& tag = m_names.back();
|
||||
AZStd::to_lower(tag.begin(), tag.end());
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace AZ
|
||||
class Specializations
|
||||
{
|
||||
public:
|
||||
static constexpr size_t MaxTagNameSize = 32;
|
||||
static constexpr size_t MaxTagNameSize = 64;
|
||||
static constexpr size_t MaxCount = 15;
|
||||
static constexpr size_t NotFound = static_cast<size_t>(-1);
|
||||
using TagName = AZStd::fixed_string<MaxTagNameSize>;
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace AZ {
|
||||
AZStd::mutex g_dbgLoadingMutex;
|
||||
HANDLE g_currentProcess = 0; /// We deal with only one process for now.
|
||||
CRITICAL_SECTION g_csDbgHelpDll; /// All dbg help functions are single threaded, so we need to control the access.
|
||||
AZStd::fixed_vector<SymbolStorage::ModuleInfo, 256> g_moduleInfo;
|
||||
AZStd::fixed_vector<SymbolStorage::ModuleInfo, 2048> g_moduleInfo;
|
||||
|
||||
// reserve 4k of scratch space so that we can get some callstack information without any allocations and as little stack frame usage as possible.
|
||||
const size_t g_scratchSpaceSize = 2048;
|
||||
|
||||
@@ -257,6 +257,48 @@ namespace UnitTest
|
||||
EXPECT_FALSE(testEvent1.HasHandlerConnected());
|
||||
EXPECT_TRUE(testEvent2.HasHandlerConnected());
|
||||
}
|
||||
|
||||
TEST_F(EventTests, TestHandlerCopyConstructorOperator)
|
||||
{
|
||||
int32_t invokedCounter = 0;
|
||||
|
||||
AZ::Event<> testEvent;
|
||||
AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; });
|
||||
|
||||
testHandler.Connect(testEvent);
|
||||
|
||||
AZ::Event<>::Handler testHandler2(testHandler);
|
||||
|
||||
EXPECT_TRUE(testHandler.IsConnected());
|
||||
EXPECT_TRUE(testHandler2.IsConnected());
|
||||
|
||||
EXPECT_TRUE(invokedCounter == 0);
|
||||
testEvent.Signal();
|
||||
EXPECT_TRUE(invokedCounter == 2);
|
||||
}
|
||||
|
||||
TEST_F(EventTests, TestHandlerCopyAssignmentOperator)
|
||||
{
|
||||
int32_t invokedCounter = 0;
|
||||
|
||||
AZ::Event<> testEvent;
|
||||
AZ::Event<>::Handler testHandler([&invokedCounter]() { invokedCounter++; });
|
||||
|
||||
testHandler.Connect(testEvent);
|
||||
|
||||
AZ::Event<>::Handler testHandler2;
|
||||
|
||||
EXPECT_TRUE(testHandler.IsConnected());
|
||||
EXPECT_FALSE(testHandler2.IsConnected());
|
||||
|
||||
testHandler2 = testHandler;
|
||||
|
||||
EXPECT_TRUE(testHandler2.IsConnected());
|
||||
|
||||
EXPECT_TRUE(invokedCounter == 0);
|
||||
testEvent.Signal();
|
||||
EXPECT_TRUE(invokedCounter == 2);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_BENCHMARK)
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 1
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 0
|
||||
#define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh"
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1
|
||||
#define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_ERRNO_T_TYPEDEF 0
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_POSIX_LOCALTIME_R 1
|
||||
#define AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL "python.sh"
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 0
|
||||
#define AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER 1
|
||||
#define AZ_TRAIT_AZFRAMEWORK_PROCESSLAUNCH_DEFAULT 0
|
||||
|
||||
@@ -36,8 +36,47 @@ namespace AzToolsFramework
|
||||
/// Retrieve the main application window.
|
||||
virtual QWidget* GetAppMainWindow() { return nullptr; }
|
||||
};
|
||||
|
||||
using EditorWindowRequestBus = AZ::EBus<EditorWindowRequests>;
|
||||
|
||||
class EditorWindowUIRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
using Bus = AZ::EBus<EditorWindowUIRequests>;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Enable/Disable the Editor UI.
|
||||
virtual void SetEditorUiEnabled([[maybe_unused]] bool enable) {}
|
||||
};
|
||||
using EditorWindowUIRequestBus = AZ::EBus<EditorWindowUIRequests>;
|
||||
|
||||
using EnableUiFunction = AZStd::function<void(bool)>;
|
||||
|
||||
/// Helper for EditorWindowRequests to be used as a
|
||||
/// member instead of inheriting from EBus directly.
|
||||
class EditorWindowRequestBusImpl
|
||||
: public EditorWindowUIRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
/// Set the function to be called when entering ImGui Mode.
|
||||
void SetEnableEditorUiFunc(const EnableUiFunction enableEditorUiFunc)
|
||||
{
|
||||
m_enableEditorUiFunc = AZStd::move(enableEditorUiFunc);
|
||||
}
|
||||
|
||||
private:
|
||||
// EditorWindowRequestBus
|
||||
void SetEditorUiEnabled( [[maybe_unused]] bool enable) override
|
||||
{
|
||||
m_enableEditorUiFunc(enable);
|
||||
}
|
||||
|
||||
EnableUiFunction m_enableEditorUiFunc; ///< Function to call when entering ImGui Mode.
|
||||
};
|
||||
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#endif // AZTOOLSFRAMEWORK_EDITORWINDOWREQUESTBUS_H
|
||||
|
||||
+15
@@ -210,6 +210,21 @@ namespace AzToolsFramework
|
||||
|
||||
void AssetBrowserTreeView::UpdateAfterFilter(bool hasFilter, bool selectFirstValidEntry)
|
||||
{
|
||||
const QModelIndexList& selectedIndexes = selectionModel()->selectedRows();
|
||||
|
||||
// If we've cleared the filter but had something selected, ensure it stays selected and visible.
|
||||
if (!hasFilter && !selectedIndexes.isEmpty())
|
||||
{
|
||||
QModelIndex curIndex = selectedIndexes[0];
|
||||
m_expandToEntriesByDefault = true;
|
||||
m_treeStateSaver->ApplySnapshot();
|
||||
|
||||
setCurrentIndex(curIndex);
|
||||
scrollTo(curIndex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Flag our default expansion state so that we expand down to source entries after filtering
|
||||
m_expandToEntriesByDefault = hasFilter;
|
||||
// Then ask our state saver to apply its current snapshot again, falling back on asking us if entries should be expanded or not
|
||||
|
||||
+15
-4
@@ -291,10 +291,12 @@ namespace AzToolsFramework
|
||||
GetEntityContextId());
|
||||
EditorEntityInfoNotificationBus::Handler::BusConnect();
|
||||
Prefab::PrefabPublicNotificationBus::Handler::BusConnect();
|
||||
EditorWindowUIRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
EntityOutlinerWidget::~EntityOutlinerWidget()
|
||||
{
|
||||
EditorWindowUIRequestBus::Handler::BusDisconnect();
|
||||
Prefab::PrefabPublicNotificationBus::Handler::BusDisconnect();
|
||||
ComponentModeFramework::EditorComponentModeNotificationBus::Handler::BusDisconnect();
|
||||
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
|
||||
@@ -1106,16 +1108,25 @@ namespace AzToolsFramework
|
||||
AzQtComponents::SetWidgetInteractEnabled(entityOutlinerUi->m_searchWidget, on);
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::EnableUi(bool enable)
|
||||
{
|
||||
SetEntityOutlinerState(m_gui, enable);
|
||||
setEnabled(enable);
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::SetEditorUiEnabled(bool enable)
|
||||
{
|
||||
EnableUi(enable);
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::EnteredComponentMode([[maybe_unused]] const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
SetEntityOutlinerState(m_gui, false);
|
||||
setEnabled(false);
|
||||
EnableUi(false);
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::LeftComponentMode([[maybe_unused]] const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
setEnabled(true);
|
||||
SetEntityOutlinerState(m_gui, true);
|
||||
EnableUi(true);
|
||||
}
|
||||
|
||||
void EntityOutlinerWidget::OnPrefabInstancePropagationBegin()
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/base.h>
|
||||
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
@@ -58,6 +59,7 @@ namespace AzToolsFramework
|
||||
, private EditorEntityInfoNotificationBus::Handler
|
||||
, private ComponentModeFramework::EditorComponentModeNotificationBus::Handler
|
||||
, private Prefab::PrefabPublicNotificationBus::Handler
|
||||
, private EditorWindowUIRequestBus::Handler
|
||||
{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
@@ -105,6 +107,9 @@ namespace AzToolsFramework
|
||||
void OnPrefabInstancePropagationBegin() override;
|
||||
void OnPrefabInstancePropagationEnd() override;
|
||||
|
||||
// EditorWindowUIRequestBus overrides
|
||||
void SetEditorUiEnabled(bool enable) override;
|
||||
|
||||
// Build a selection object from the given entities. Entities already in the Widget's selection buffers are ignored.
|
||||
template <class EntityIdCollection>
|
||||
QItemSelection BuildSelectionFromEntities(const EntityIdCollection& entityIds);
|
||||
@@ -155,6 +160,7 @@ namespace AzToolsFramework
|
||||
AZ::EntityId GetEntityIdFromIndex(const QModelIndex& index) const;
|
||||
QModelIndex GetIndexFromEntityId(const AZ::EntityId& entityId) const;
|
||||
void ExtractEntityIdsFromSelection(const QItemSelection& selection, EntityIdList& entityIdList) const;
|
||||
void EnableUi(bool enable);
|
||||
|
||||
// OutlinerModelNotificationBus::Handler
|
||||
// Receive notification from the outliner model that we should scroll
|
||||
|
||||
+23
@@ -376,6 +376,7 @@ namespace AzToolsFramework
|
||||
ToolsApplicationEvents::Bus::Handler::BusConnect();
|
||||
AZ::EntitySystemBus::Handler::BusConnect();
|
||||
EntityPropertyEditorRequestBus::Handler::BusConnect();
|
||||
EditorWindowUIRequestBus::Handler::BusConnect();
|
||||
m_spacer = nullptr;
|
||||
|
||||
m_emptyIcon = QIcon();
|
||||
@@ -421,6 +422,7 @@ namespace AzToolsFramework
|
||||
{
|
||||
qApp->removeEventFilter(this);
|
||||
|
||||
EditorWindowUIRequestBus::Handler::BusDisconnect();
|
||||
EntityPropertyEditorRequestBus::Handler::BusDisconnect();
|
||||
ToolsApplicationEvents::Bus::Handler::BusDisconnect();
|
||||
AZ::EntitySystemBus::Handler::BusDisconnect();
|
||||
@@ -4961,6 +4963,27 @@ namespace AzToolsFramework
|
||||
EnableDisableComponentActions(widget, actions, false);
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::SetEditorUiEnabled(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
EnableComponentActions(this, m_entityComponentActions);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableComponentActions(this, m_entityComponentActions);
|
||||
}
|
||||
m_disabled = !enable;
|
||||
SetPropertyEditorState(m_gui, enable);
|
||||
|
||||
for (auto componentEditor : m_componentEditors)
|
||||
{
|
||||
AzQtComponents::SetWidgetInteractEnabled(componentEditor, enable);
|
||||
}
|
||||
// record the selected state after entering/leaving component mode
|
||||
SaveComponentEditorState();
|
||||
}
|
||||
|
||||
void EntityPropertyEditor::EnteredComponentMode(const AZStd::vector<AZ::Uuid>& componentModeTypes)
|
||||
{
|
||||
DisableComponentActions(this, m_entityComponentActions);
|
||||
|
||||
+5
@@ -21,6 +21,7 @@
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzToolsFramework/Undo/UndoSystem.h>
|
||||
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/API/EntityPropertyEditorRequestsBus.h>
|
||||
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
||||
@@ -108,6 +109,7 @@ namespace AzToolsFramework
|
||||
, public EditorInspectorComponentNotificationBus::MultiHandler
|
||||
, private AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBus::Handler
|
||||
, public AZ::EntitySystemBus::Handler
|
||||
, private EditorWindowUIRequestBus::Handler
|
||||
{
|
||||
Q_OBJECT;
|
||||
public:
|
||||
@@ -208,6 +210,9 @@ namespace AzToolsFramework
|
||||
void GetSelectedEntities(EntityIdList& selectedEntityIds) override;
|
||||
void SetNewComponentId(AZ::ComponentId componentId) override;
|
||||
|
||||
// EditorWindowRequestBus overrides
|
||||
void SetEditorUiEnabled(bool enable) override;
|
||||
|
||||
bool IsEntitySelected(const AZ::EntityId& id) const;
|
||||
bool IsSingleEntitySelected(const AZ::EntityId& id) const;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
@@ -277,7 +277,7 @@ void FileWatcherUnitTestRunner::StartTest()
|
||||
UNIT_TEST_EXPECT_TRUE(QDir::toNativeSeparators(fileAddName).toLower() == QDir::toNativeSeparators(newName3).toLower());
|
||||
|
||||
#if !defined(AZ_PLATFORM_LINUX)
|
||||
// final test... make sure that renaming a DIRECTORY works too.
|
||||
// final test... make sure that renaming a DIRECTORY works too.
|
||||
// Note that linux does not get any callbacks if just the directory is renamed (from inotify)
|
||||
QDir renamer;
|
||||
fileAddCalled = false;
|
||||
@@ -312,6 +312,9 @@ void FileWatcherUnitTestRunner::StartTest()
|
||||
Q_EMIT UnitTestPassed();
|
||||
}
|
||||
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
// File operations on Linux behave differently on Linux than Windows.
|
||||
// The system under test doesn't yet handle Linux's file operations, which surfaced as this test arbitrarily passing and failing.
|
||||
// This test is disabled on Linux until the system under test can handle Linux file system behavior correctly.
|
||||
#if !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS && !defined(AZ_PLATFORM_LINUX)
|
||||
REGISTER_UNIT_TEST(FileWatcherUnitTestRunner)
|
||||
#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_PROCESSOR_TESTS
|
||||
|
||||
@@ -10,7 +10,6 @@ add_subdirectory(AssetProcessor)
|
||||
add_subdirectory(AWSNativeSDKInit)
|
||||
add_subdirectory(AzTestRunner)
|
||||
add_subdirectory(CrashHandler)
|
||||
add_subdirectory(News)
|
||||
add_subdirectory(PythonBindingsExample)
|
||||
add_subdirectory(RemoteConsole)
|
||||
add_subdirectory(DeltaCataloger)
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
add_subdirectory(NewsBuilder)
|
||||
|
||||
if (NOT PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
ly_add_target(
|
||||
NAME NewsShared STATIC
|
||||
NAMESPACE Legacy
|
||||
AUTOMOC
|
||||
AUTOUIC
|
||||
AUTORCC
|
||||
FILES_CMAKE
|
||||
news_shared_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
.
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::Qt::Core
|
||||
3rdParty::Qt::Network
|
||||
3rdParty::Qt::Widgets
|
||||
AZ::AzQtComponents
|
||||
)
|
||||
@@ -1,38 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
|
||||
|
||||
include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
|
||||
if (NOT PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED OR NOT PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
ly_add_target(
|
||||
NAME NewsBuilder EXECUTABLE
|
||||
NAMESPACE Legacy
|
||||
AUTOMOC
|
||||
AUTOUIC
|
||||
AUTORCC
|
||||
FILES_CMAKE
|
||||
news_builder_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PUBLIC
|
||||
.
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
3rdParty::Qt::Core
|
||||
3rdParty::Qt::Widgets
|
||||
3rdParty::AWSNativeSDK::Dependencies
|
||||
3rdParty::AWSNativeSDK::Core
|
||||
3rdParty::AWSNativeSDK::S3
|
||||
Legacy::NewsShared
|
||||
AZ::AzCore
|
||||
AZ::AzQtComponents
|
||||
AZ::AzFramework
|
||||
)
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EndpointManager.h"
|
||||
#include <NewsShared/ResourceManagement/ResourceManifest.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
Endpoint::Endpoint(QString name, QString awsProfile, QString url, QString bucket)
|
||||
: m_name(name)
|
||||
, m_awsProfile(awsProfile)
|
||||
, m_url(url)
|
||||
, m_bucket(bucket)
|
||||
{}
|
||||
|
||||
Endpoint::Endpoint(const QJsonObject& json)
|
||||
: Endpoint(json["name"].toString(),
|
||||
json["awsProfile"].toString(),
|
||||
json["url"].toString(),
|
||||
json["bucket"].toString())
|
||||
{
|
||||
}
|
||||
|
||||
Endpoint::~Endpoint() {}
|
||||
|
||||
void Endpoint::Write(QJsonObject& json) const
|
||||
{
|
||||
json["name"] = m_name;
|
||||
json["awsProfile"] = m_awsProfile;
|
||||
json["url"] = m_url;
|
||||
json["bucket"] = m_bucket;
|
||||
}
|
||||
|
||||
QString Endpoint::GetName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void Endpoint::SetName(const QString& name)
|
||||
{
|
||||
m_name = QString(name);
|
||||
}
|
||||
|
||||
QString Endpoint::GetAwsProfile() const
|
||||
{
|
||||
return m_awsProfile;
|
||||
}
|
||||
|
||||
void Endpoint::SetAwsProfile(const QString& awsProfile)
|
||||
{
|
||||
m_awsProfile = QString(awsProfile);
|
||||
}
|
||||
|
||||
QString Endpoint::GetUrl() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
void Endpoint::SetUrl(const QString& url)
|
||||
{
|
||||
m_url = QString(url);
|
||||
}
|
||||
|
||||
QString Endpoint::GetBucket() const
|
||||
{
|
||||
return m_bucket;
|
||||
}
|
||||
|
||||
void Endpoint::SetBucket(const QString& bucket)
|
||||
{
|
||||
m_bucket = bucket;
|
||||
}
|
||||
|
||||
EndpointManager::EndpointManager()
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
EndpointManager::~EndpointManager()
|
||||
{
|
||||
ClearEndpoints();
|
||||
}
|
||||
|
||||
void EndpointManager::Load()
|
||||
{
|
||||
ClearEndpoints();
|
||||
QFile file("newsBuilderConfig.txt");
|
||||
if (file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&file);
|
||||
QString str = in.readAll().trimmed();
|
||||
QByteArray array(str.toStdString().c_str());
|
||||
QJsonDocument doc(QJsonDocument::fromJson(array));
|
||||
QJsonObject json = doc.object();
|
||||
QJsonArray endpointArray = json["endpoints"].toArray();
|
||||
for (auto endpointDoc : endpointArray)
|
||||
{
|
||||
m_endpoints.append(new Endpoint(endpointDoc.toObject()));
|
||||
}
|
||||
int endpointIndex = json["currentEndpointIndex"].toInt();
|
||||
if (endpointIndex >= 0 && m_endpoints.count() > endpointIndex)
|
||||
{
|
||||
m_selectedEndpoint = m_endpoints[endpointIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_selectedEndpoint = nullptr;
|
||||
}
|
||||
file.close();
|
||||
|
||||
SaveUrl();
|
||||
}
|
||||
}
|
||||
|
||||
void EndpointManager::Save()
|
||||
{
|
||||
QFile file("newsBuilderConfig.txt");
|
||||
if (file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
QJsonObject json;
|
||||
QJsonArray endpointArray;
|
||||
for (auto endpoint : m_endpoints)
|
||||
{
|
||||
QJsonObject endpointObject;
|
||||
endpoint->Write(endpointObject);
|
||||
endpointArray.append(endpointObject);
|
||||
}
|
||||
json["endpoints"] = endpointArray;
|
||||
json["currentEndpointIndex"] = m_endpoints.indexOf(m_selectedEndpoint);
|
||||
QTextStream out(&file);
|
||||
QJsonDocument doc(json);
|
||||
out << doc.toJson(QJsonDocument::Compact);
|
||||
file.close();
|
||||
|
||||
SaveUrl();
|
||||
}
|
||||
}
|
||||
|
||||
void EndpointManager::SelectEndpoint(Endpoint* endpoint)
|
||||
{
|
||||
m_selectedEndpoint = endpoint;
|
||||
}
|
||||
|
||||
void EndpointManager::AddEndpoint(Endpoint* endpoint)
|
||||
{
|
||||
m_endpoints.append(endpoint);
|
||||
}
|
||||
|
||||
void EndpointManager::RemoveEndpoint(Endpoint* endpoint)
|
||||
{
|
||||
if (endpoint == m_selectedEndpoint)
|
||||
{
|
||||
m_selectedEndpoint = nullptr;
|
||||
}
|
||||
m_endpoints.removeAll(endpoint);
|
||||
delete endpoint;
|
||||
}
|
||||
|
||||
Endpoint* EndpointManager::GetSelectedEndpoint() const
|
||||
{
|
||||
return m_selectedEndpoint;
|
||||
}
|
||||
|
||||
QList<Endpoint*>::const_iterator EndpointManager::begin() const
|
||||
{
|
||||
return m_endpoints.begin();
|
||||
}
|
||||
|
||||
QList<Endpoint*>::const_iterator EndpointManager::end() const
|
||||
{
|
||||
return m_endpoints.end();
|
||||
}
|
||||
|
||||
void EndpointManager::ClearEndpoints()
|
||||
{
|
||||
for (auto endpoint : m_endpoints)
|
||||
{
|
||||
delete endpoint;
|
||||
}
|
||||
m_endpoints.clear();
|
||||
}
|
||||
|
||||
void EndpointManager::SaveUrl() const
|
||||
{
|
||||
if (!m_selectedEndpoint)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Editor looks for config file in /dev folder, so this file is placed in parent directory
|
||||
QFile file(QCoreApplication::applicationDirPath() + "/newsConfig.txt");
|
||||
if (file.open(QIODevice::WriteOnly))
|
||||
{
|
||||
QTextStream out(&file);
|
||||
out << m_selectedEndpoint->GetUrl();
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <qobjectdefs.h>
|
||||
|
||||
class QJsonObject;
|
||||
|
||||
namespace News
|
||||
{
|
||||
//! Endpoint represents a location of news data
|
||||
class Endpoint
|
||||
{
|
||||
public:
|
||||
Endpoint(QString name, QString awsProfile, QString url, QString bucket);
|
||||
explicit Endpoint(const QJsonObject& json);
|
||||
~Endpoint();
|
||||
|
||||
void Write(QJsonObject& json) const;
|
||||
|
||||
QString GetName() const;
|
||||
void SetName(const QString& name);
|
||||
|
||||
QString GetAwsProfile() const;
|
||||
void SetAwsProfile(const QString& awsProfile);
|
||||
|
||||
QString GetUrl() const;
|
||||
void SetUrl(const QString& url);
|
||||
|
||||
QString GetBucket() const;
|
||||
void SetBucket(const QString& bucket);
|
||||
|
||||
private:
|
||||
//! name of endpoint to distinguish with others
|
||||
QString m_name;
|
||||
//! name of aws credentials file
|
||||
QString m_awsProfile;
|
||||
//! url location of news data (e.g. cloudfront url)
|
||||
QString m_url;
|
||||
//! name of s3 bucket where news data resides
|
||||
QString m_bucket;
|
||||
};
|
||||
|
||||
//! EndpointManager handles endpoint collection
|
||||
class EndpointManager
|
||||
{
|
||||
public:
|
||||
EndpointManager();
|
||||
~EndpointManager();
|
||||
|
||||
//! Load endpoints file
|
||||
void Load();
|
||||
//! Save endpoints file
|
||||
void Save();
|
||||
void SelectEndpoint(Endpoint* endpoint);
|
||||
void AddEndpoint(Endpoint* endpoint);
|
||||
void RemoveEndpoint(Endpoint* endpoint);
|
||||
Endpoint* GetSelectedEndpoint() const;
|
||||
|
||||
QList<Endpoint*>::const_iterator begin() const;
|
||||
QList<Endpoint*>::const_iterator end() const;
|
||||
|
||||
private:
|
||||
QList<Endpoint*> m_endpoints;
|
||||
Endpoint* m_selectedEndpoint = nullptr;
|
||||
|
||||
void ClearEndpoints();
|
||||
//! Saves news config file which is used by LY Editor to determine news location
|
||||
void SaveUrl() const;
|
||||
};
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE)
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE)
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE)
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED TRUE)
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
|
||||
set(PAL_TRAIT_BUILD_NEWSBUILDER_SUPPORTED FALSE)
|
||||
@@ -1,295 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ArticleDetails.h"
|
||||
#include "SelectImage.h"
|
||||
#include <NewsShared/ResourceManagement/Resource.h>
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
#include "ResourceManagement/ImageDescriptor.h"
|
||||
#include "NewsShared/ErrorCodes.h"
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
#include "Qt/ui_ArticleDetails.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
ArticleDetails::ArticleDetails(QWidget* parent,
|
||||
Resource& resource,
|
||||
BuilderResourceManifest& manifest)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::ArticleDetailsWidget)
|
||||
, m_filename("")
|
||||
, m_article(resource)
|
||||
, m_manifest(manifest)
|
||||
, m_imageIdOriginal("")
|
||||
, m_imageId("")
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->uidLabel->setText(QString("Article: %1").arg(m_article.GetResource().GetId()));
|
||||
|
||||
resizePreviewImage();
|
||||
|
||||
//! try to load image icon
|
||||
auto pImageResource = m_manifest.FindById(m_article.GetImageId());
|
||||
if (pImageResource)
|
||||
{
|
||||
m_imageIdOriginal = pImageResource->GetId();
|
||||
SetImage(*pImageResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNoImage();
|
||||
}
|
||||
|
||||
m_ui->titleText->setText(m_article.GetTitle());
|
||||
m_ui->descriptionText->setPlainText(m_article.GetBody());
|
||||
|
||||
connect(m_ui->fromFileButton, &QPushButton::clicked, this, &ArticleDetails::OpenImageFromFile);
|
||||
connect(m_ui->fromResourceButton, &QPushButton::clicked, this, &ArticleDetails::OpenImageFromResource);
|
||||
connect(m_ui->clearImageButton, &QPushButton::clicked, this, &ArticleDetails::ClearImage);
|
||||
connect(m_ui->updateButton, &QPushButton::clicked, this, &ArticleDetails::UpdateArticle);
|
||||
connect(m_ui->deleteButton, &QPushButton::clicked, this, &ArticleDetails::DeleteArticle);
|
||||
connect(m_ui->cancelButton, &QPushButton::clicked, this, &ArticleDetails::Close);
|
||||
connect(m_ui->upButton, &QPushButton::clicked, this, &ArticleDetails::MoveUp);
|
||||
connect(m_ui->downButton, &QPushButton::clicked, this, &ArticleDetails::MoveDown);
|
||||
}
|
||||
|
||||
ArticleDetails::~ArticleDetails() {}
|
||||
|
||||
void ArticleDetails::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
resizePreviewImage();
|
||||
}
|
||||
|
||||
void ArticleDetails::resizePreviewImage()
|
||||
{
|
||||
// Resize the imagePreview to keep the proportions
|
||||
int newHeight = aznumeric_cast<int>(m_imageRatio * width());
|
||||
m_ui->imagePreview->setFixedHeight(newHeight);
|
||||
}
|
||||
|
||||
ArticleDescriptor& ArticleDetails::GetArticle()
|
||||
{
|
||||
return m_article;
|
||||
}
|
||||
|
||||
QString ArticleDetails::GetId() const
|
||||
{
|
||||
return m_article.GetResource().GetId();
|
||||
}
|
||||
|
||||
void ArticleDetails::OpenImageFromFile()
|
||||
{
|
||||
m_filename = QFileDialog::getOpenFileName(this,
|
||||
"Open Image", ".", "Image Files (*.png *.jpg *.bmp)");
|
||||
SetImage(m_filename);
|
||||
}
|
||||
|
||||
void ArticleDetails::OpenImageFromResource()
|
||||
{
|
||||
m_pSelectImage = new SelectImage(m_manifest);
|
||||
if (m_pSelectImage->exec() == QDialog::DialogCode::Accepted)
|
||||
{
|
||||
auto pSelectedResource = m_pSelectImage->GetSelected();
|
||||
if (!pSelectedResource)
|
||||
{
|
||||
QMessageBox msgBox(QMessageBox::Critical,
|
||||
"Error",
|
||||
"No resource pSelectedResource",
|
||||
QMessageBox::Ok,
|
||||
this);
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
SetImage(*pSelectedResource);
|
||||
}
|
||||
delete m_pSelectImage;
|
||||
}
|
||||
|
||||
//! once the Update button is clicked, article resource is updated in this function
|
||||
void ArticleDetails::UpdateArticle()
|
||||
{
|
||||
//! this flag remains false if no new changes are detected, thus avoiding unnecessary
|
||||
//! re-uploading unchanged resources
|
||||
bool updated = false;
|
||||
|
||||
m_imageId = LoadImage();
|
||||
if (m_imageId.compare(m_imageIdOriginal) != 0)
|
||||
{
|
||||
m_article.SetImageId(m_imageId);
|
||||
m_filename = "";
|
||||
m_imageIdOriginal = m_imageId;
|
||||
m_ui->imagePathLabel->setText(QString("Image: %1").arg(m_imageId));
|
||||
updated = true;
|
||||
}
|
||||
|
||||
QString newTitle = m_ui->titleText->text();
|
||||
if (m_article.GetTitle().compare(newTitle))
|
||||
{
|
||||
m_article.SetTitle(newTitle);
|
||||
updated = true;
|
||||
}
|
||||
QString newBody = m_ui->descriptionText->toPlainText();
|
||||
if (m_article.GetBody().compare(newBody) != 0)
|
||||
{
|
||||
m_article.SetBody(newBody);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
QString newStyle = m_ui->articleStyleButtonGroup->checkedButton()->property("style").toString();
|
||||
if (m_article.GetArticleStyle() != newStyle)
|
||||
{
|
||||
m_article.SetArticleStyle(newStyle);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
m_article.Update();
|
||||
m_manifest.UpdateResource(&m_article.GetResource());
|
||||
emit logSignal(QString("Article %1 updated")
|
||||
.arg(m_article.GetResource().GetId()), LogOk);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit logSignal("Nothing to update", LogWarning);
|
||||
}
|
||||
emit updateArticleSignal();
|
||||
}
|
||||
|
||||
//! try to load an image either from filename or from another resource,
|
||||
//! update resource manifest accordingly
|
||||
QString ArticleDetails::LoadImage() const
|
||||
{
|
||||
if (!m_filename.isEmpty())
|
||||
{
|
||||
if (!m_imageIdOriginal.isEmpty())
|
||||
{
|
||||
m_manifest.FreeResource(m_imageIdOriginal);
|
||||
}
|
||||
auto pResource = m_manifest.AddImage(m_filename);
|
||||
if (pResource)
|
||||
{
|
||||
return pResource->GetId();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
if (m_imageId.compare(m_imageIdOriginal) != 0)
|
||||
{
|
||||
if (!m_imageIdOriginal.isEmpty())
|
||||
{
|
||||
m_manifest.FreeResource(m_imageIdOriginal);
|
||||
}
|
||||
if (!m_imageId.isEmpty())
|
||||
{
|
||||
m_manifest.UseResource(m_imageId);
|
||||
}
|
||||
return m_imageId;
|
||||
}
|
||||
|
||||
return m_imageIdOriginal;
|
||||
}
|
||||
|
||||
void ArticleDetails::SetImage(Resource& resource)
|
||||
{
|
||||
m_ui->imagePathLabel->setText(QString("Image: %1").arg(resource.GetId()));
|
||||
|
||||
QPixmap pixmap;
|
||||
if (pixmap.loadFromData(resource.GetData()))
|
||||
{
|
||||
m_ui->imagePreview->setPixmap(pixmap);
|
||||
m_imageId = resource.GetId();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNoImage();
|
||||
emit logSignal(QString("Failed to load image: %1.").arg(m_imageId));
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleDetails::SetImage([[maybe_unused]] QString& filename)
|
||||
{
|
||||
m_ui->imagePathLabel->setText(QString("Image: %1").arg(m_filename));
|
||||
|
||||
QPixmap pixmap;
|
||||
if (pixmap.load(m_filename))
|
||||
{
|
||||
m_ui->imagePreview->setPixmap(pixmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetNoImage();
|
||||
emit logSignal(QString("Failed to load image: %1.").arg(m_filename));
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleDetails::SetNoImage() const
|
||||
{
|
||||
m_ui->imagePreview->setPixmap(QPixmap(":/images/Resources/missing-image.png"));
|
||||
m_ui->imagePathLabel->setText("no image");
|
||||
}
|
||||
|
||||
void ArticleDetails::ClearImage()
|
||||
{
|
||||
m_imageId = "";
|
||||
m_filename = "";
|
||||
SetNoImage();
|
||||
}
|
||||
|
||||
void ArticleDetails::DeleteArticle()
|
||||
{
|
||||
if (!m_article.GetImageId().isEmpty())
|
||||
{
|
||||
m_manifest.FreeResource(m_article.GetImageId());
|
||||
}
|
||||
m_manifest.FreeResource(m_article.GetResource().GetId());
|
||||
emit deleteArticleSignal();
|
||||
}
|
||||
|
||||
void ArticleDetails::Close()
|
||||
{
|
||||
emit closeArticleSignal();
|
||||
}
|
||||
|
||||
void ArticleDetails::MoveUp()
|
||||
{
|
||||
ErrorCode error;
|
||||
if (!m_manifest.UpdateArticleOrder(m_article.GetResource().GetId(), 1, error))
|
||||
{
|
||||
emit logSignal(GetErrorMessage(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit orderChangedSignal(m_article.GetResource().GetId(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleDetails::MoveDown()
|
||||
{
|
||||
ErrorCode error;
|
||||
if (!m_manifest.UpdateArticleOrder(m_article.GetResource().GetId(), 0, error))
|
||||
{
|
||||
emit logSignal(GetErrorMessage(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit orderChangedSignal(m_article.GetResource().GetId(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
#include "Qt/moc_ArticleDetails.cpp"
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <NewsShared/ResourceManagement/ArticleDescriptor.h>
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ArticleDetailsWidget;
|
||||
}
|
||||
|
||||
namespace News {
|
||||
class SelectImage;
|
||||
class ResourceManifest;
|
||||
class Resource;
|
||||
|
||||
//! Control that allows to modify all parameters of a single article
|
||||
class ArticleDetails
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ArticleDetails(QWidget* parent,
|
||||
Resource& resource,
|
||||
BuilderResourceManifest& manifest);
|
||||
~ArticleDetails();
|
||||
ArticleDescriptor& GetArticle();
|
||||
QString GetId() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void logSignal(QString text, LogType logType = LogInfo);
|
||||
void deleteArticleSignal();
|
||||
void updateArticleSignal();
|
||||
void closeArticleSignal();
|
||||
void orderChangedSignal(QString id, bool direction);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::ArticleDetailsWidget> m_ui;
|
||||
QString m_filename;
|
||||
ArticleDescriptor m_article;
|
||||
BuilderResourceManifest& m_manifest;
|
||||
SelectImage* m_pSelectImage;
|
||||
QString m_imageIdOriginal;
|
||||
QString m_imageId;
|
||||
float m_imageRatio = 184.0f / 430.0f;
|
||||
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void resizePreviewImage();
|
||||
|
||||
void OpenImageFromFile();
|
||||
void OpenImageFromResource();
|
||||
QString LoadImage() const;
|
||||
void SetImage(Resource& resource);
|
||||
void SetImage(QString& filename);
|
||||
void SetNoImage() const;
|
||||
void ClearImage();
|
||||
|
||||
void UpdateArticle();
|
||||
void DeleteArticle();
|
||||
void Close();
|
||||
void MoveUp();
|
||||
void MoveDown();
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,406 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ArticleDetailsWidget</class>
|
||||
<widget class="QWidget" name="ArticleDetailsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>250</width>
|
||||
<height>420</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>420</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>640</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="globalLayout" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="AzQtComponents::ExtendedLabel" name="imagePreview">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="newsbuilder.qrc">:/images/Resources/missing-image.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="pixmapSize" stdset="0">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="imageLayout" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>140</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="imagePathLabel">
|
||||
<property name="text">
|
||||
<string>Image:</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="imageLayoutInner" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearImageButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fromResourceButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Library...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fromFileButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="Title" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1280</width>
|
||||
<height>1280</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="uidLabel">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Article: 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="articleStyleLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="defaultStyleRadioButton">
|
||||
<property name="text">
|
||||
<string>Default Style</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="style" stdset="0">
|
||||
<string>default</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">articleStyleButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="pinnedStyleRadioButton">
|
||||
<property name="text">
|
||||
<string>Pinned Style</string>
|
||||
</property>
|
||||
<property name="style" stdset="0">
|
||||
<string>pinned</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">articleStyleButtonGroup</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Title:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="titleText">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="Description">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="descriptionText"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteButton">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="updateButton">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="upButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Move Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="downButton">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Move Down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzQtComponents::ExtendedLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>AzQtComponents/Components/ExtendedLabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="newsbuilder.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="articleStyleButtonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ArticleDetailsContainer.h"
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
#include "ArticleDetails.h"
|
||||
#include "Qt/ui_ArticleDetailsContainer.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
ArticleDetailsContainer::ArticleDetailsContainer(
|
||||
QWidget* parent,
|
||||
BuilderResourceManifest& manifest)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::ArticleDetailsContainerWidget)
|
||||
, m_manifest(manifest)
|
||||
, m_articleDetails(nullptr)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
ArticleDetailsContainer::~ArticleDetailsContainer() {}
|
||||
|
||||
//! When article is selected, old articleDetails control is removed, new one is created
|
||||
void ArticleDetailsContainer::SelectArticle(const QString& id)
|
||||
{
|
||||
closeArticleSlot();
|
||||
|
||||
if (!id.isEmpty())
|
||||
{
|
||||
auto article = m_manifest.FindById(id);
|
||||
if (article)
|
||||
{
|
||||
m_articleDetails = new ArticleDetails(
|
||||
m_ui->scrollAreaWidgetContents,
|
||||
*article,
|
||||
m_manifest);
|
||||
m_ui->scrollAreaWidgetContents->layout()->addWidget(m_articleDetails);
|
||||
connect(m_articleDetails, &ArticleDetails::updateArticleSignal,
|
||||
this, &ArticleDetailsContainer::updateArticleSlot);
|
||||
connect(m_articleDetails, &ArticleDetails::deleteArticleSignal,
|
||||
this, &ArticleDetailsContainer::deleteArticleSlot);
|
||||
connect(m_articleDetails, &ArticleDetails::closeArticleSignal,
|
||||
this, &ArticleDetailsContainer::closeArticleSlot);
|
||||
connect(m_articleDetails, SIGNAL(logSignal(QString, LogType)),
|
||||
this, SIGNAL(logSignal(QString, LogType)));
|
||||
connect(m_articleDetails, SIGNAL(orderChangedSignal(QString, bool)),
|
||||
this, SIGNAL(orderChangedSignal(QString, bool)));
|
||||
m_selectedId = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleDetailsContainer::Reset()
|
||||
{
|
||||
SelectArticle(m_selectedId);
|
||||
}
|
||||
|
||||
void ArticleDetailsContainer::updateArticleSlot()
|
||||
{
|
||||
emit updateArticleSignal(m_articleDetails->GetId());
|
||||
}
|
||||
|
||||
void ArticleDetailsContainer::deleteArticleSlot()
|
||||
{
|
||||
emit deleteArticleSignal(m_articleDetails->GetId());
|
||||
closeArticleSlot();
|
||||
}
|
||||
|
||||
void ArticleDetailsContainer::closeArticleSlot()
|
||||
{
|
||||
if (m_articleDetails)
|
||||
{
|
||||
emit closeArticleSignal(m_selectedId);
|
||||
delete m_articleDetails;
|
||||
m_articleDetails = nullptr;
|
||||
m_selectedId = "";
|
||||
}
|
||||
}
|
||||
|
||||
#include "Qt/moc_ArticleDetailsContainer.cpp"
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
#include <NewsShared/LogType.h>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ArticleDetailsContainerWidget;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
class ArticleDetails;
|
||||
class BuilderResourceManifest;
|
||||
class SelectImage;
|
||||
class ResourceManifest;
|
||||
class Resource;
|
||||
|
||||
//! Control that manages articleDetails control
|
||||
class ArticleDetailsContainer
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ArticleDetailsContainer(QWidget* parent, BuilderResourceManifest& manifest);
|
||||
~ArticleDetailsContainer();
|
||||
|
||||
void SelectArticle(const QString& id);
|
||||
void Reset();
|
||||
|
||||
Q_SIGNALS:
|
||||
void logSignal(QString text, LogType logType = LogInfo);
|
||||
void updateArticleSignal(QString id);
|
||||
void deleteArticleSignal(QString id);
|
||||
void closeArticleSignal(QString id);
|
||||
void orderChangedSignal(QString id, bool direction);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::ArticleDetailsContainerWidget> m_ui;
|
||||
BuilderResourceManifest& m_manifest;
|
||||
ArticleDetails* m_articleDetails = nullptr;
|
||||
QString m_selectedId;
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateArticleSlot();
|
||||
void deleteArticleSlot();
|
||||
void closeArticleSlot();
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,100 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ArticleDetailsContainerWidget</class>
|
||||
<widget class="QWidget" name="ArticleDetailsContainerWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>250</width>
|
||||
<height>386</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>640</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>ArticleDetailsContainer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>248</width>
|
||||
<height>384</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,102 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>176</width>
|
||||
<height>137</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>AWS Key Id:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="textKeyId"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>AWS Secret Key:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="textKeyId_2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BuilderArticleViewContainer.h"
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
#include "ArticleDetails.h"
|
||||
#include <NewsShared/ResourceManagement/Resource.h>
|
||||
#include <NewsShared/Qt/ArticleViewContainer.h>
|
||||
#include <NewsShared/Qt/ArticleView.h>
|
||||
#include "Qt/ui_BuilderArticleViewContainer.h"
|
||||
|
||||
#include <AzQtComponents/Components/Style.h>
|
||||
|
||||
#include "QCustomMessageBox.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
BuilderArticleViewContainer::BuilderArticleViewContainer(
|
||||
QWidget* parent,
|
||||
BuilderResourceManifest& manifest)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::BuilderArticleViewContainerWidget)
|
||||
, m_container(new ArticleViewContainer(this, manifest))
|
||||
, m_manifest(manifest)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->ArticleViewContainerRoot->layout()->addWidget(m_container);
|
||||
connect(m_container, SIGNAL(articleSelectedSignal(QString)),
|
||||
this, SLOT(articleSelectedSlot(QString)));
|
||||
}
|
||||
|
||||
BuilderArticleViewContainer::~BuilderArticleViewContainer(){}
|
||||
|
||||
void BuilderArticleViewContainer::AddArticle()
|
||||
{
|
||||
auto pArticleResource = static_cast<BuilderResourceManifest&>(m_manifest).AddArticle();
|
||||
if (pArticleResource)
|
||||
{
|
||||
m_container->AddArticleView(ArticleDescriptor(*pArticleResource));
|
||||
SelectArticle(pArticleResource->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::SelectArticle(QString id)
|
||||
{
|
||||
if (m_selectedArticleId.compare(id) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UnselectArticle();
|
||||
m_selectedArticleId = id;
|
||||
auto article = m_container->FindById(id);
|
||||
if (article)
|
||||
{
|
||||
m_container->ScrollToView(article);
|
||||
emit articleSelectedSignal(id);
|
||||
|
||||
// Add class and refresh style
|
||||
AzQtComponents::Style::addClass(article, m_selectedArticleClass);
|
||||
article->style()->unpolish(qApp);
|
||||
article->style()->polish(qApp);
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::Sync()
|
||||
{
|
||||
emit logSignal("Starting sync");
|
||||
|
||||
m_manifest.Sync();
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::UpdateArticle(QString& id) const
|
||||
{
|
||||
auto view = m_container->FindById(id);
|
||||
if (view)
|
||||
{
|
||||
view->Update();
|
||||
m_container->ForceRefreshArticleView(view);
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::DeleteArticle(QString& id) const
|
||||
{
|
||||
auto view = m_container->FindById(id);
|
||||
if (view)
|
||||
{
|
||||
m_container->DeleteArticleView(view);
|
||||
}
|
||||
}
|
||||
|
||||
//possibly support multiple selection in future?
|
||||
void BuilderArticleViewContainer::CloseArticle(QString& id)
|
||||
{
|
||||
if (m_selectedArticleId == id)
|
||||
{
|
||||
UnselectArticle();
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::UpdateArticleOrder(QString& id, bool direction) const
|
||||
{
|
||||
auto view = m_container->FindById(id);
|
||||
if (view)
|
||||
{
|
||||
m_container->UpdateArticleOrder(view, direction);
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::PopulateArticles()
|
||||
{
|
||||
m_container->PopulateArticles();
|
||||
|
||||
if (!m_selectedArticleId.isEmpty())
|
||||
{
|
||||
SelectArticle(m_selectedArticleId);
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::AddErrorMessage() const
|
||||
{
|
||||
m_container->AddErrorMessage();
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::UnselectArticle()
|
||||
{
|
||||
if (m_selectedArticleId.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto article = m_container->FindById(m_selectedArticleId);
|
||||
|
||||
// Remove class and refresh style
|
||||
if (article)
|
||||
{
|
||||
AzQtComponents::Style::removeClass(article, m_selectedArticleClass);
|
||||
article->style()->unpolish(qApp);
|
||||
article->style()->polish(qApp);
|
||||
}
|
||||
|
||||
m_selectedArticleId = "";
|
||||
}
|
||||
|
||||
void BuilderArticleViewContainer::articleSelectedSlot(QString id)
|
||||
{
|
||||
SelectArticle(id);
|
||||
}
|
||||
|
||||
#include "Qt/moc_BuilderArticleViewContainer.cpp"
|
||||
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
#include <NewsShared/LogType.h>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class BuilderArticleViewContainerWidget;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
class ArticleViewContainer;
|
||||
class BuilderResourceManifest;
|
||||
|
||||
//! BuilderArticleViewContainer is a Builder container for ArticleViewContainer.
|
||||
/*!
|
||||
It is a wrapper with additional builder functionality for displaying articles
|
||||
*/
|
||||
class BuilderArticleViewContainer
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BuilderArticleViewContainer(QWidget* parent, BuilderResourceManifest& manifest);
|
||||
~BuilderArticleViewContainer();
|
||||
|
||||
void UpdateArticle(QString& id) const;
|
||||
void DeleteArticle(QString& id) const;
|
||||
void CloseArticle(QString& id);
|
||||
void UpdateArticleOrder(QString& id, bool direction) const;
|
||||
void PopulateArticles();
|
||||
void AddErrorMessage() const;
|
||||
void AddArticle();
|
||||
|
||||
Q_SIGNALS:
|
||||
void logSignal(QString text, LogType logType = LogInfo);
|
||||
void articleSelectedSignal(QString id);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::BuilderArticleViewContainerWidget> m_ui;
|
||||
ArticleViewContainer* m_container;
|
||||
QString m_selectedArticleId;
|
||||
QString m_selectedArticleClass = "SelectedArticle";
|
||||
BuilderResourceManifest& m_manifest;
|
||||
|
||||
void Sync();
|
||||
void SelectArticle(QString id);
|
||||
void UnselectArticle();
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
void articleSelectedSlot(QString id);
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,57 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BuilderArticleViewContainerWidget</class>
|
||||
<widget class="QWidget" name="BuilderArticleViewContainerWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>250</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="ArticleViewContainerRoot" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EndpointEntryView.h"
|
||||
#include "Qt/ui_EndpointEntryView.h"
|
||||
#include <EndpointManager.h>
|
||||
#include <QToolButton>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
const char* EndpointEntryView::SELECTED_CSS =
|
||||
"background-color: rgb(60, 100, 60);\ncolor: white;";
|
||||
const char* EndpointEntryView::UNSELECTED_CSS =
|
||||
"background-color: rgb(60, 60, 60);\ncolor: white;";
|
||||
|
||||
EndpointEntryView::EndpointEntryView(QWidget* parent, Endpoint* pEndpoint)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::EndpointEntryViewWidget)
|
||||
, m_pEndpoint(pEndpoint)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->labelName->setText(pEndpoint->GetName());
|
||||
|
||||
connect(m_ui->labelName, &AzQtComponents::ExtendedLabel::clicked, this, &EndpointEntryView::selectSlot);
|
||||
connect(m_ui->buttonDelete, &QToolButton::clicked, this, &EndpointEntryView::deleteSlot);
|
||||
}
|
||||
|
||||
EndpointEntryView::~EndpointEntryView() {}
|
||||
|
||||
void EndpointEntryView::SetSelected(bool selected)
|
||||
{
|
||||
setStyleSheet(selected ? SELECTED_CSS : UNSELECTED_CSS);
|
||||
}
|
||||
|
||||
Endpoint* EndpointEntryView::GetEndpoint() const
|
||||
{
|
||||
return m_pEndpoint;
|
||||
}
|
||||
|
||||
void EndpointEntryView::selectSlot()
|
||||
{
|
||||
emit selectSignal(this);
|
||||
}
|
||||
|
||||
void EndpointEntryView::deleteSlot()
|
||||
{
|
||||
emit deleteSignal(this);
|
||||
}
|
||||
|
||||
#include "Qt/moc_EndpointEntryView.cpp"
|
||||
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EndpointEntryViewWidget;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
class Endpoint;
|
||||
|
||||
//! Qt widget representing a single endpoint entry
|
||||
class EndpointEntryView
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EndpointEntryView(QWidget* parent, Endpoint* pEndpoint);
|
||||
~EndpointEntryView();
|
||||
|
||||
void SetSelected(bool selected);
|
||||
|
||||
Endpoint* GetEndpoint() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void selectSignal(EndpointEntryView* pEndpointView);
|
||||
void deleteSignal(EndpointEntryView* pEndpointView);
|
||||
|
||||
private:
|
||||
static const char* SELECTED_CSS;
|
||||
static const char* UNSELECTED_CSS;
|
||||
|
||||
QScopedPointer<Ui::EndpointEntryViewWidget> m_ui;
|
||||
Endpoint* m_pEndpoint = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void selectSlot();
|
||||
void deleteSlot();
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,87 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EndpointEntryViewWidget</class>
|
||||
<widget class="QWidget" name="EndpointEntryViewWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>356</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>23</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="AzQtComponents::ExtendedLabel" name="labelName">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonDelete">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzQtComponents::ExtendedLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>AzQtComponents/Components/ExtendedLabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "EndpointManagerView.h"
|
||||
#include "EndpointManager.h"
|
||||
#include "EndpointEntryView.h"
|
||||
#include "Qt/ui_EndpointManagerView.h"
|
||||
#include "Qt/QCustomMessageBox.h"
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
EndpointManagerView::EndpointManagerView(QWidget* parent,
|
||||
BuilderResourceManifest& manifest)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::EndpointManagerViewWidget)
|
||||
, m_pManager(manifest.GetEndpointManager())
|
||||
, m_manifest(manifest)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
for (auto endpoint : *m_pManager)
|
||||
{
|
||||
auto endpointView = AddEndpointEntry(endpoint);
|
||||
if (m_pManager->GetSelectedEndpoint() == endpoint)
|
||||
{
|
||||
selectEndpointSlot(endpointView);
|
||||
}
|
||||
}
|
||||
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(m_ui->buttonAdd, &QPushButton::clicked, this, &EndpointManagerView::addEndpointSlot);
|
||||
}
|
||||
|
||||
EndpointManagerView::~EndpointManagerView() {}
|
||||
|
||||
EndpointEntryView* EndpointManagerView::AddEndpointEntry(Endpoint* pEndpoint)
|
||||
{
|
||||
auto endpointView = new EndpointEntryView(m_ui->endpointListContents, pEndpoint);
|
||||
auto layout = static_cast<QVBoxLayout*>(m_ui->endpointListContents->layout());
|
||||
layout->insertWidget(layout->count() - 2, endpointView);
|
||||
m_endpoints.append(endpointView);
|
||||
connect(endpointView, SIGNAL(selectSignal(EndpointEntryView*)),
|
||||
this, SLOT(selectEndpointSlot(EndpointEntryView*)));
|
||||
connect(endpointView, SIGNAL(deleteSignal(EndpointEntryView*)),
|
||||
this, SLOT(deleteEndpointSlot(EndpointEntryView*)));
|
||||
// this lets us modify newly-added widget in the same function
|
||||
qApp->processEvents();
|
||||
return endpointView;
|
||||
}
|
||||
|
||||
void EndpointManagerView::Update() const
|
||||
{
|
||||
if (m_pSelectedEndpoint)
|
||||
{
|
||||
auto pEndpoint = m_pSelectedEndpoint->GetEndpoint();
|
||||
pEndpoint->SetName(m_ui->nameText->text());
|
||||
pEndpoint->SetAwsProfile(m_ui->awsProfileText->text());
|
||||
pEndpoint->SetUrl(m_ui->urlText->text());
|
||||
pEndpoint->SetBucket(m_ui->bucketText->text());
|
||||
m_pManager->SelectEndpoint(m_pSelectedEndpoint->GetEndpoint());
|
||||
}
|
||||
m_pManager->Save();
|
||||
}
|
||||
|
||||
void EndpointManagerView::accept()
|
||||
{
|
||||
enum SyncResponse
|
||||
{
|
||||
Merge, ReplaceLocal, ReplaceRemote, Cancel
|
||||
};
|
||||
enum YesNoResponse
|
||||
{
|
||||
Yes, No
|
||||
};
|
||||
|
||||
QCustomMessageBox msgBox(
|
||||
QCustomMessageBox::Question,
|
||||
tr("Pull data from Endpoint"),
|
||||
tr("You are changing an endpoint. "
|
||||
"What would you like to do with the data on the current endpoint?\n\n"
|
||||
"Merge - merge resources from the endpoint\n"
|
||||
"Replace Local - overwrite local resources with endpoint resources\n"
|
||||
"Replace Endpoint - overwrite endpoint resources with local resources\n"
|
||||
"Cancel - undo endpoint selection"
|
||||
),
|
||||
this);
|
||||
msgBox.AddButton(tr("Merge"), Merge);
|
||||
msgBox.AddButton(tr("Replace Local"), ReplaceLocal);
|
||||
msgBox.AddButton(tr("Replace Endpoint"), ReplaceRemote);
|
||||
msgBox.AddButton(tr("Cancel"), Cancel);
|
||||
|
||||
switch (msgBox.exec())
|
||||
{
|
||||
case Merge:
|
||||
{
|
||||
m_manifest.SetSyncType(SyncType::Merge);
|
||||
m_manifest.PersistLocalResources();
|
||||
}
|
||||
break;
|
||||
case ReplaceLocal:
|
||||
{
|
||||
if (m_manifest.HasChanges())
|
||||
{
|
||||
QCustomMessageBox msgBoxWarning(
|
||||
QCustomMessageBox::Critical,
|
||||
tr("Unsaved changes"),
|
||||
tr("Local resources were modified but not published."
|
||||
"Changing endpoints will cause unpublished work to be lost.\n\n"
|
||||
"Would you like to proceed?"),
|
||||
this);
|
||||
msgBoxWarning.AddButton(tr("Yes"), Yes);
|
||||
msgBoxWarning.AddButton(tr("No"), No);
|
||||
if (msgBoxWarning.exec() == No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_manifest.SetSyncType(SyncType::Merge);
|
||||
m_manifest.Reset();
|
||||
}
|
||||
break;
|
||||
case ReplaceRemote:
|
||||
{
|
||||
QCustomMessageBox msgBoxWarning2(
|
||||
QCustomMessageBox::Critical,
|
||||
tr("Warning"),
|
||||
tr("This operation will IRREVERSABLY replace ALL resources on ") +
|
||||
m_pSelectedEndpoint->GetEndpoint()->GetName() +
|
||||
tr(" endpoint with local data.\n\n"
|
||||
"Are you sure you'd like to proceed?"),
|
||||
this);
|
||||
msgBoxWarning2.AddButton(tr("Yes"), Yes);
|
||||
msgBoxWarning2.AddButton(tr("No"), No);
|
||||
if (msgBoxWarning2.exec() == No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_manifest.SetSyncType(SyncType::Overwrite);
|
||||
m_manifest.PersistLocalResources();
|
||||
}
|
||||
break;
|
||||
case Cancel:
|
||||
return;
|
||||
}
|
||||
|
||||
Update();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void EndpointManagerView::addEndpointSlot()
|
||||
{
|
||||
auto pEndpoint = new Endpoint(
|
||||
QObject::tr("New endpoint"),
|
||||
QObject::tr("Enter AWS profile name"),
|
||||
QObject::tr("Enter root URL"),
|
||||
QObject::tr("Enter s3 bucket name"));
|
||||
m_pManager->AddEndpoint(pEndpoint);
|
||||
auto endpointView = AddEndpointEntry(pEndpoint);
|
||||
selectEndpointSlot(endpointView);
|
||||
}
|
||||
|
||||
void EndpointManagerView::selectEndpointSlot(EndpointEntryView* pEndpointView)
|
||||
{
|
||||
m_pSelectedEndpoint = pEndpointView;
|
||||
|
||||
for (auto view : m_endpoints)
|
||||
{
|
||||
view->SetSelected(view == pEndpointView);
|
||||
}
|
||||
|
||||
if (pEndpointView)
|
||||
{
|
||||
auto pEndpoint = pEndpointView->GetEndpoint();
|
||||
m_ui->nameText->setText(pEndpoint->GetName());
|
||||
m_ui->awsProfileText->setText(pEndpoint->GetAwsProfile());
|
||||
m_ui->urlText->setText(pEndpoint->GetUrl());
|
||||
m_ui->bucketText->setText(pEndpoint->GetBucket());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->nameText->setText("");
|
||||
m_ui->awsProfileText->setText("");
|
||||
m_ui->urlText->setText("");
|
||||
m_ui->bucketText->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
void EndpointManagerView::deleteEndpointSlot(EndpointEntryView* pEndpointView)
|
||||
{
|
||||
m_pManager->RemoveEndpoint(pEndpointView->GetEndpoint());
|
||||
m_endpoints.removeAll(pEndpointView);
|
||||
|
||||
if (pEndpointView == m_pSelectedEndpoint)
|
||||
{
|
||||
if (m_endpoints.count() > 0)
|
||||
{
|
||||
selectEndpointSlot(m_endpoints[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectEndpointSlot(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
delete pEndpointView;
|
||||
}
|
||||
|
||||
|
||||
#include "Qt/moc_EndpointManagerView.cpp"
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EndpointManagerViewWidget;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
class BuilderResourceManifest;
|
||||
class Endpoint;
|
||||
class EndpointEntryView;
|
||||
class EndpointManager;
|
||||
|
||||
//! Qt dialog for managing endpoints
|
||||
class EndpointManagerView
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
EndpointManagerView(QWidget* parent,
|
||||
BuilderResourceManifest& manifest);
|
||||
~EndpointManagerView();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::EndpointManagerViewWidget> m_ui;
|
||||
EndpointManager* m_pManager = nullptr;
|
||||
EndpointEntryView* m_pSelectedEndpoint = nullptr;
|
||||
QList<EndpointEntryView*> m_endpoints;
|
||||
BuilderResourceManifest& m_manifest;
|
||||
|
||||
EndpointEntryView* AddEndpointEntry(Endpoint* pEndpoint);
|
||||
void Update() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void accept() override;
|
||||
void addEndpointSlot();
|
||||
void selectEndpointSlot(EndpointEntryView* pEndpoint);
|
||||
void deleteEndpointSlot(EndpointEntryView* pEndpoint);
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,224 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EndpointManagerViewWidget</class>
|
||||
<widget class="QDialog" name="EndpointManagerViewWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>350</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>350</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>350</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Change Endpoint</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="endpointListContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>363</width>
|
||||
<height>189</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonAdd">
|
||||
<property name="text">
|
||||
<string>+</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="nameText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>AWS Profile Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="awsProfileText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>URL:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="urlText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>S3 Bucket</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="bucketText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ImageItem.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
|
||||
#include "Qt/ui_ImageItem.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
const char* ImageItem::SELECTED_CSS =
|
||||
"border: 4px solid; border-color: white; background-color: rgb(45, 45, 45);";
|
||||
const char* ImageItem::UN_SELECTED_CSS =
|
||||
"background-color: rgb(45, 45, 45);";
|
||||
|
||||
ImageItem::ImageItem(Resource& resource)
|
||||
: QWidget()
|
||||
, m_ui(new Ui::ImageItemWidget)
|
||||
, m_resource(resource)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QPixmap pixmap;
|
||||
pixmap.loadFromData(m_resource.GetData());
|
||||
m_ui->ImageLabel->setPixmap(pixmap);
|
||||
|
||||
connect(m_ui->ImageLabel, &AzQtComponents::ExtendedLabel::clicked, this, &ImageItem::imageClickedSlot);
|
||||
}
|
||||
|
||||
void ImageItem::imageClickedSlot()
|
||||
{
|
||||
emit selectSignal(this);
|
||||
}
|
||||
|
||||
ImageItem::~ImageItem() {}
|
||||
|
||||
void ImageItem::SetSelect(bool selected) const
|
||||
{
|
||||
m_ui->ImageLabel->setStyleSheet(selected ? SELECTED_CSS : UN_SELECTED_CSS);
|
||||
}
|
||||
|
||||
Resource& ImageItem::GetResource() const
|
||||
{
|
||||
return m_resource;
|
||||
}
|
||||
|
||||
#include "Qt/moc_ImageItem.cpp"
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ImageItemWidget;
|
||||
}
|
||||
|
||||
namespace News {
|
||||
class Resource;
|
||||
|
||||
//! A clickable image in selectImage control
|
||||
class ImageItem
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ImageItem(Resource& resource);
|
||||
~ImageItem();
|
||||
|
||||
void SetSelect(bool selected) const;
|
||||
Resource& GetResource() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void selectSignal(ImageItem* imageItem);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::ImageItemWidget> m_ui;
|
||||
const static char* SELECTED_CSS;
|
||||
const static char* UN_SELECTED_CSS;
|
||||
|
||||
Resource& m_resource;
|
||||
private Q_SLOTS:
|
||||
void imageClickedSlot();
|
||||
};
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ImageItemWidget</class>
|
||||
<widget class="QWidget" name="ImageItemWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="AzQtComponents::ExtendedLabel" name="ImageLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmapSize" stdset="0">
|
||||
<size>
|
||||
<width>160</width>
|
||||
<height>90</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzQtComponents::ExtendedLabel1</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>AzQtComponents/Components/ExtendedLabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LogContainer.h"
|
||||
|
||||
#include "Qt/ui_LogContainer.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
LogContainer::LogContainer(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::LogContainerWidget)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
LogContainer::~LogContainer() {}
|
||||
|
||||
void LogContainer::AddLog(QString text, LogType logType) const {
|
||||
QString color;
|
||||
switch (logType)
|
||||
{
|
||||
case LogOk:
|
||||
color = "green";
|
||||
break;
|
||||
case LogInfo:
|
||||
color = "white";
|
||||
break;
|
||||
case LogError:
|
||||
color = "red";
|
||||
break;
|
||||
case LogWarning:
|
||||
color = "yellow";
|
||||
break;
|
||||
default:
|
||||
color = "white";
|
||||
break;
|
||||
}
|
||||
auto fullText = QString("<span style=\" color:%1; \"><XMP>%2</XMP></span><br>").arg(color).arg(text);
|
||||
m_ui->logText->setTextFormat(Qt::RichText);
|
||||
m_ui->logText->setText(QString("%2%1").arg(m_ui->logText->text()).arg(fullText));
|
||||
}
|
||||
|
||||
#include "Qt/moc_LogContainer.cpp"
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QWidget>
|
||||
#include <NewsShared/LogType.h>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class LogContainerWidget;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
//! A control for displaying log
|
||||
class LogContainer
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LogContainer(QWidget* parent);
|
||||
~LogContainer();
|
||||
|
||||
void AddLog(QString text, LogType logType) const;
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::LogContainerWidget> m_ui;
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,131 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LogContainerWidget</class>
|
||||
<widget class="QWidget" name="LogContainerWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>547</width>
|
||||
<height>125</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>LogContainer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="logArea_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>545</width>
|
||||
<height>123</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="logText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(45, 45, 45);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextBrowserInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/PlatformDef.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include "NewsBuilder.h"
|
||||
#include "Qt/ArticleDetails.h"
|
||||
#include "Qt/BuilderArticleViewContainer.h"
|
||||
#include "NewsShared/Qt/ArticleViewContainer.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
#include "ArticleDetailsContainer.h"
|
||||
#include "LogContainer.h"
|
||||
#include "EndpointManagerView.h"
|
||||
#include "EndpointManager.h"
|
||||
#include "Qt/QCustomMessageBox.h"
|
||||
|
||||
#include <AzQtComponents/Components/StyleManager.h>
|
||||
#include <AzQtComponents/Utilities/QtPluginPaths.h>
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4996, "-Wunknown-warning-option")
|
||||
#include <aws/core/utils/HashingUtils.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <QImage>
|
||||
#include <QFileDialog>
|
||||
#include <QSignalMapper>
|
||||
#include <QTextDocument>
|
||||
|
||||
#include "Qt/ui_Newsbuilder.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
NewsBuilder::NewsBuilder(QWidget* parent, const AZ::IO::PathView& engineRootPath)
|
||||
: QMainWindow(parent)
|
||||
, m_ui(new Ui::NewsBuilderClass())
|
||||
, m_manifest(new BuilderResourceManifest(
|
||||
std::bind(&NewsBuilder::SyncSuccess, this),
|
||||
std::bind(&NewsBuilder::SyncFail, this, std::placeholders::_1),
|
||||
std::bind(&NewsBuilder::SyncUpdate, this, std::placeholders::_1, std::placeholders::_2)))
|
||||
, m_articleDetailsContainer(new ArticleDetailsContainer(this, *m_manifest))
|
||||
, m_articleViewContainer(new BuilderArticleViewContainer(this, *m_manifest))
|
||||
, m_logContainer(new LogContainer(this))
|
||||
{
|
||||
|
||||
AzQtComponents::StyleManager* m_styleSheet = new AzQtComponents::StyleManager(this);
|
||||
m_styleSheet->initialize(qApp, engineRootPath);
|
||||
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QDir rootDir = QString::fromUtf8(engineRootPath.Native().data(), aznumeric_cast<int>(engineRootPath.Native().size()));
|
||||
const auto pathOnDisk = rootDir.absoluteFilePath("Code/Tools/News/NewsBuilder/Resources");
|
||||
const auto qrcPath = QStringLiteral(":/NewsBuilder");
|
||||
AzQtComponents::StyleManager::addSearchPaths("newsbuilder", pathOnDisk, qrcPath, engineRootPath);
|
||||
|
||||
AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral("newsbuilder:NewsBuilder.qss"));
|
||||
|
||||
UpdateEndpointLabel();
|
||||
|
||||
m_ui->articleViewContainerRoot->layout()->addWidget(m_articleViewContainer);
|
||||
m_ui->articleDetailsContainerRoot->layout()->addWidget(m_articleDetailsContainer);
|
||||
m_ui->dockWidgetContents->layout()->addWidget(m_logContainer);
|
||||
|
||||
connect(m_articleViewContainer, SIGNAL(articleSelectedSignal(QString)),
|
||||
this, SLOT(selectArticleSlot(QString)));
|
||||
connect(m_articleViewContainer, SIGNAL(logSignal(QString, LogType)),
|
||||
this, SLOT(addLogSlot(QString, LogType)));
|
||||
|
||||
connect(m_articleDetailsContainer, &ArticleDetailsContainer::updateArticleSignal,
|
||||
this, &NewsBuilder::updateArticleSlot);
|
||||
connect(m_articleDetailsContainer, &ArticleDetailsContainer::deleteArticleSignal,
|
||||
this, &NewsBuilder::deleteArticleSlot);
|
||||
connect(m_articleDetailsContainer, &ArticleDetailsContainer::orderChangedSignal,
|
||||
this, &NewsBuilder::orderChangedSlot);
|
||||
connect(m_articleDetailsContainer, &ArticleDetailsContainer::closeArticleSignal,
|
||||
this, &NewsBuilder::closeArticleSlot);
|
||||
connect(m_articleDetailsContainer, SIGNAL(logSignal(QString, LogType)),
|
||||
this, SLOT(addLogSlot(QString, LogType)));
|
||||
|
||||
m_manifest->SetSyncType(SyncType::Merge);
|
||||
m_manifest->Sync();
|
||||
|
||||
// Sync Console pane with View menu
|
||||
connect(m_ui->actionConsole, &QAction::triggered, this, &NewsBuilder::OnViewLogWindow);
|
||||
connect(m_ui->dockWidget, &QDockWidget::visibilityChanged, this, &NewsBuilder::OnViewVisibilityChanged);
|
||||
}
|
||||
|
||||
NewsBuilder::~NewsBuilder() {}
|
||||
|
||||
void NewsBuilder::selectArticleSlot(const QString& id) const
|
||||
{
|
||||
m_articleDetailsContainer->SelectArticle(id);
|
||||
}
|
||||
|
||||
void NewsBuilder::addLogSlot(QString text, LogType logType) const
|
||||
{
|
||||
AddLog(text, logType);
|
||||
}
|
||||
|
||||
void NewsBuilder::addArticleToBottomSlot() const
|
||||
{
|
||||
m_articleViewContainer->AddArticle();
|
||||
}
|
||||
|
||||
void NewsBuilder::updateArticleSlot(QString id) const
|
||||
{
|
||||
m_articleViewContainer->UpdateArticle(id);
|
||||
}
|
||||
|
||||
void NewsBuilder::deleteArticleSlot(QString id) const
|
||||
{
|
||||
m_articleViewContainer->DeleteArticle(id);
|
||||
}
|
||||
|
||||
void NewsBuilder::closeArticleSlot(QString id) const
|
||||
{
|
||||
m_articleViewContainer->CloseArticle(id);
|
||||
}
|
||||
|
||||
void NewsBuilder::orderChangedSlot(QString id, bool direction) const
|
||||
{
|
||||
m_articleViewContainer->UpdateArticleOrder(id, direction);
|
||||
}
|
||||
|
||||
void NewsBuilder::openSlot()
|
||||
{
|
||||
EndpointManagerView endpointManagerView(
|
||||
m_ui->centralWidget,
|
||||
*m_manifest);
|
||||
if (endpointManagerView.exec() == QDialog::Accepted)
|
||||
{
|
||||
m_manifest->Sync();
|
||||
}
|
||||
UpdateEndpointLabel();
|
||||
}
|
||||
|
||||
void NewsBuilder::publishSlot()
|
||||
{
|
||||
if (!m_manifest->HasChanges())
|
||||
{
|
||||
QCustomMessageBox msgBox(
|
||||
QCustomMessageBox::Information,
|
||||
tr("Nothing to publish"),
|
||||
tr("No local changes were made, nothing to publish."),
|
||||
this);
|
||||
msgBox.AddButton(tr("Good"), 0);
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
enum Response
|
||||
{
|
||||
Yes, No
|
||||
};
|
||||
|
||||
QCustomMessageBox msgBox(
|
||||
QCustomMessageBox::Critical,
|
||||
tr("Publish resources"),
|
||||
tr("You are about to overwrite the current Open 3D Engine Welcome Message. Are you sure you want to publish?"),
|
||||
this);
|
||||
msgBox.AddButton("Yes", Yes);
|
||||
msgBox.AddButton("No", No);
|
||||
if (msgBox.exec() == Yes)
|
||||
{
|
||||
m_manifest->SetSyncType(SyncType::Verify);
|
||||
m_manifest->Sync();
|
||||
}
|
||||
}
|
||||
|
||||
void NewsBuilder::OnViewVisibilityChanged([[maybe_unused]] bool visibility)
|
||||
{
|
||||
UpdateViewMenu();
|
||||
}
|
||||
|
||||
void NewsBuilder::UpdateViewMenu()
|
||||
{
|
||||
if (m_ui->actionConsole->isChecked() != m_ui->dockWidget->isVisible())
|
||||
{
|
||||
QSignalBlocker signalBlocker(m_ui->actionConsole);
|
||||
m_ui->actionConsole->setChecked(m_ui->dockWidget->isVisible());
|
||||
}
|
||||
}
|
||||
|
||||
void NewsBuilder::OnViewLogWindow()
|
||||
{
|
||||
if (m_ui->dockWidget)
|
||||
{
|
||||
m_ui->dockWidget->toggleViewAction()->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
void NewsBuilder::UpdateEndpointLabel()
|
||||
{
|
||||
auto pEndpoint = m_manifest->GetEndpointManager()->GetSelectedEndpoint();
|
||||
if (pEndpoint)
|
||||
{
|
||||
this->setWindowTitle("News Builder (" + pEndpoint->GetName() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setWindowTitle("News Builder (No endpoint selected)");
|
||||
}
|
||||
}
|
||||
|
||||
void NewsBuilder::AddLog(QString text, LogType logType) const
|
||||
{
|
||||
m_logContainer->AddLog(text, logType);
|
||||
}
|
||||
|
||||
void NewsBuilder::SyncUpdate(const QString& message, LogType logType) const
|
||||
{
|
||||
AddLog(message, logType);
|
||||
}
|
||||
|
||||
void NewsBuilder::SyncFail(ErrorCode error)
|
||||
{
|
||||
const char* errorMessage = GetErrorMessage(error);
|
||||
AddLog(tr("Sync failed: %1").arg(errorMessage), LogError);
|
||||
QCustomMessageBox msgBoxSyncFail(
|
||||
QCustomMessageBox::Critical,
|
||||
tr("Sync failed"),
|
||||
errorMessage,
|
||||
this);
|
||||
msgBoxSyncFail.AddButton("Ok", 0);
|
||||
msgBoxSyncFail.exec();
|
||||
|
||||
m_articleViewContainer->PopulateArticles();
|
||||
m_articleDetailsContainer->Reset();
|
||||
}
|
||||
|
||||
void NewsBuilder::SyncSuccess() const
|
||||
{
|
||||
AddLog("Sync completed", LogOk);
|
||||
m_articleViewContainer->PopulateArticles();
|
||||
m_articleDetailsContainer->Reset();
|
||||
}
|
||||
#include "Qt/moc_NewsBuilder.cpp"
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "NewsShared/LogType.h"
|
||||
#include "NewsShared/ErrorCodes.h"
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#endif
|
||||
|
||||
class QSignalMapper;
|
||||
class QPushButton;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class NewsBuilderClass;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
class BuilderArticleViewContainer;
|
||||
class LogContainer;
|
||||
class BuilderResourceManifest;
|
||||
class ArticleDetailsContainer;
|
||||
|
||||
//! A central control of News Builder.
|
||||
class NewsBuilder
|
||||
: public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewsBuilder(QWidget* parent, const AZ::IO::PathView& engineRootPath);
|
||||
~NewsBuilder();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::NewsBuilderClass> m_ui;
|
||||
BuilderResourceManifest* m_manifest = nullptr;
|
||||
ArticleDetailsContainer* m_articleDetailsContainer = nullptr;
|
||||
BuilderArticleViewContainer* m_articleViewContainer = nullptr;
|
||||
LogContainer* m_logContainer = nullptr;
|
||||
|
||||
void UpdateEndpointLabel();
|
||||
void AddLog(QString text, LogType logType = LogInfo) const;
|
||||
|
||||
void SyncUpdate(const QString& message, LogType logType) const;
|
||||
void SyncFail(ErrorCode error);
|
||||
void SyncSuccess() const;
|
||||
|
||||
void OnViewVisibilityChanged(bool visibility);
|
||||
void UpdateViewMenu();
|
||||
void OnViewLogWindow();
|
||||
|
||||
private Q_SLOTS:
|
||||
void selectArticleSlot(const QString& id) const;
|
||||
void addLogSlot(QString text, LogType logType) const;
|
||||
void addArticleToBottomSlot() const;
|
||||
void updateArticleSlot(QString id) const;
|
||||
void deleteArticleSlot(QString id) const;
|
||||
void closeArticleSlot(QString id) const;
|
||||
void orderChangedSlot(QString id, bool direction) const;
|
||||
void openSlot();
|
||||
void publishSlot();
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="images">
|
||||
<file>../Resources/missing-image.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,326 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>NewsBuilderClass</class>
|
||||
<widget class="QMainWindow" name="NewsBuilderClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>540</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>480</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1024</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>News Builder</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="verticalLayout1" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="articleViewContainerRoot" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>480</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="articleDetailsContainerRoot" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionOpen"/>
|
||||
<addaction name="actionPublish"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuArticle">
|
||||
<property name="title">
|
||||
<string>Article</string>
|
||||
</property>
|
||||
<addaction name="actionAdd_New"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>View</string>
|
||||
</property>
|
||||
<addaction name="actionConsole"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuArticle"/>
|
||||
<addaction name="menuView"/>
|
||||
</widget>
|
||||
<widget class="AzQtComponents::StyledDockWidget" name="dockWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>63</width>
|
||||
<height>66</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="features">
|
||||
<set>QDockWidget::DockWidgetClosable</set>
|
||||
</property>
|
||||
<property name="allowedAreas">
|
||||
<set>Qt::BottomDockWidgetArea</set>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Console</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>8</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<action name="actionOpen">
|
||||
<property name="text">
|
||||
<string>Change Endpoint</string>
|
||||
</property>
|
||||
<property name="autoRepeat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPublish">
|
||||
<property name="text">
|
||||
<string>Publish Resources</string>
|
||||
</property>
|
||||
<property name="autoRepeat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAdd_New">
|
||||
<property name="text">
|
||||
<string>Add to Bottom</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDelete_Selected">
|
||||
<property name="text">
|
||||
<string>Delete Selected</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionConsole">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Console</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="0" margin="0"/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzQtComponents::StyledDockWidget</class>
|
||||
<extends>QDockWidget</extends>
|
||||
<header>AzQtComponents/Components/StyledDockWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="newsbuilder.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionOpen</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>NewsBuilderClass</receiver>
|
||||
<slot>openSlot()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>399</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionPublish</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>NewsBuilderClass</receiver>
|
||||
<slot>publishSlot()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>399</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionAdd_New</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>NewsBuilderClass</receiver>
|
||||
<slot>addArticleToBottomSlot()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>399</x>
|
||||
<y>269</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "QCustomMessageBox.h"
|
||||
#include "Qt/ui_QCustomMessageBox.h"
|
||||
|
||||
#include <QSignalMapper>
|
||||
#include <QPushButton>
|
||||
#include <QStyle>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
QCustomMessageBox::QCustomMessageBox(
|
||||
Icon icon,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QWidget* parent)
|
||||
: QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint)
|
||||
, m_ui(new Ui::CustomMessageBoxDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_signalMapper = new QSignalMapper(this);
|
||||
|
||||
this->setWindowTitle(title);
|
||||
m_ui->labelText->setText(text);
|
||||
|
||||
QStyle* style = QApplication::style();
|
||||
QIcon tmpIcon;
|
||||
switch (icon)
|
||||
{
|
||||
case Information:
|
||||
tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation);
|
||||
break;
|
||||
case Warning:
|
||||
tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||
break;
|
||||
case Critical:
|
||||
tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical);
|
||||
break;
|
||||
case Question:
|
||||
tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!tmpIcon.isNull())
|
||||
{
|
||||
QLabel* iconLabel = new QLabel(this);
|
||||
iconLabel->setPixmap(tmpIcon.pixmap(64, 64));
|
||||
m_ui->bodyLayout->insertWidget(0, iconLabel);
|
||||
}
|
||||
|
||||
connect(m_signalMapper, SIGNAL(mapped(int)),
|
||||
this, SLOT(clickedSlot(int)));
|
||||
}
|
||||
|
||||
QCustomMessageBox::~QCustomMessageBox()
|
||||
{
|
||||
delete m_signalMapper;
|
||||
}
|
||||
|
||||
void QCustomMessageBox::AddButton(const QString& name, int result)
|
||||
{
|
||||
auto button = new QPushButton(name, this);
|
||||
connect(button, SIGNAL(clicked()), m_signalMapper, SLOT(map()));
|
||||
m_signalMapper->setMapping(button, result);
|
||||
m_ui->buttonLayout->layout()->addWidget(button);
|
||||
}
|
||||
|
||||
void QCustomMessageBox::clickedSlot(int result)
|
||||
{
|
||||
done(result);
|
||||
}
|
||||
|
||||
#include "Qt/moc_QCustomMessageBox.cpp"
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
class QSignalMapper;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CustomMessageBoxDialog;
|
||||
}
|
||||
|
||||
namespace News
|
||||
{
|
||||
class ArticleDetails;
|
||||
class BuilderResourceManifest;
|
||||
class SelectImage;
|
||||
class ResourceManifest;
|
||||
class Resource;
|
||||
|
||||
//! Allows to add custom buttons which is not well-supported by default QMessageBox
|
||||
class QCustomMessageBox
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Icon {
|
||||
NoIcon = 0,
|
||||
Information = 1,
|
||||
Warning = 2,
|
||||
Critical = 3,
|
||||
Question = 4
|
||||
};
|
||||
|
||||
QCustomMessageBox(
|
||||
Icon,
|
||||
const QString& title,
|
||||
const QString& text,
|
||||
QWidget* parent);
|
||||
~QCustomMessageBox();
|
||||
|
||||
void AddButton(const QString& name, int result);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::CustomMessageBoxDialog> m_ui;
|
||||
QSignalMapper* m_signalMapper = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void clickedSlot(int result);
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CustomMessageBoxDialog</class>
|
||||
<widget class="QDialog" name="CustomMessageBoxDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>102</width>
|
||||
<height>43</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Message Title</string>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="bodyLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelText">
|
||||
<property name="text">
|
||||
<string>Message text</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="buttonLayout">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SelectImage.h"
|
||||
#include "ImageItem.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
#include "ResourceManagement/BuilderResourceManifest.h"
|
||||
|
||||
#include "Qt/ui_SelectImage.h"
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
const int SelectImage::MAX_COLS = 2;
|
||||
|
||||
SelectImage::SelectImage(const ResourceManifest& manifest)
|
||||
: QDialog()
|
||||
, m_ui(new Ui::SelectImageDialog)
|
||||
, m_manifest(manifest)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
auto layout = static_cast<QGridLayout*>(m_ui->scrollAreaContents->layout());
|
||||
layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
//! read all image resources and populate the container
|
||||
for (auto pResource : m_manifest)
|
||||
{
|
||||
if (pResource->GetType().compare("image") == 0)
|
||||
{
|
||||
auto imageItem = new ImageItem(*pResource);
|
||||
connect(imageItem, &ImageItem::selectSignal, this, &SelectImage::ImageSelected);
|
||||
layout->addWidget(imageItem, row, col, Qt::AlignLeft);
|
||||
m_images.append(imageItem);
|
||||
col++;
|
||||
if (col >= MAX_COLS)
|
||||
{
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
SelectImage::~SelectImage() {}
|
||||
|
||||
Resource* SelectImage::GetSelected() const
|
||||
{
|
||||
return m_pSelected;
|
||||
}
|
||||
|
||||
void SelectImage::ImageSelected(ImageItem* imageItem)
|
||||
{
|
||||
for (auto image : m_images)
|
||||
{
|
||||
image->SetSelect(image == imageItem);
|
||||
}
|
||||
if (imageItem)
|
||||
{
|
||||
m_pSelected = &imageItem->GetResource();
|
||||
}
|
||||
}
|
||||
|
||||
#include "Qt/moc_SelectImage.cpp"
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QDialog>
|
||||
#endif
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SelectImageDialog;
|
||||
}
|
||||
|
||||
namespace News {
|
||||
class ImageItem;
|
||||
class Resource;
|
||||
class ResourceManifest;
|
||||
|
||||
//! Allows to select existing images for multiple messages without re-uploading same one
|
||||
class SelectImage
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SelectImage(const ResourceManifest& manifest);
|
||||
~SelectImage();
|
||||
|
||||
void Select();
|
||||
void Close();
|
||||
Resource* GetSelected() const;
|
||||
|
||||
private:
|
||||
const static int MAX_COLS;
|
||||
QScopedPointer<Ui::SelectImageDialog> m_ui;
|
||||
const ResourceManifest& m_manifest;
|
||||
QList<ImageItem*> m_images;
|
||||
Resource* m_pSelected = nullptr;
|
||||
|
||||
void ImageSelected(ImageItem* imageItem);
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,106 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SelectImageDialog</class>
|
||||
<widget class="QDialog" name="SelectImageDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>439</width>
|
||||
<height>406</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Select Image</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>437</width>
|
||||
<height>379</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,497 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BuilderResourceManifest.h"
|
||||
#include "NewsShared/ResourceManagement/QtDownloadManager.h"
|
||||
#include "NewsBuilder/S3Connector.h"
|
||||
#include "UidGenerator.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
#include "NewsBuilder/ResourceManagement/UploadDescriptor.h"
|
||||
#include "NewsBuilder/ResourceManagement/DeleteDescriptor.h"
|
||||
#include "NewsShared/ResourceManagement/ArticleDescriptor.h"
|
||||
#include "NewsBuilder/ResourceManagement/ImageDescriptor.h"
|
||||
#include "EndpointManager.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QByteArray>
|
||||
|
||||
#include <aws/core/utils/memory/stl/AwsStringStream.h>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace News {
|
||||
|
||||
BuilderResourceManifest::BuilderResourceManifest(
|
||||
std::function<void()> syncSuccessCallback,
|
||||
std::function<void(ErrorCode)> syncFailCallback,
|
||||
std::function<void(QString, LogType)> syncUpdateCallback)
|
||||
: ResourceManifest(syncSuccessCallback, syncFailCallback, syncUpdateCallback)
|
||||
, m_s3Connector(new S3Connector)
|
||||
, m_uidGenerator(new UidGenerator)
|
||||
, m_endpointManager(new EndpointManager) {}
|
||||
|
||||
|
||||
Resource* BuilderResourceManifest::AddArticle()
|
||||
{
|
||||
auto pResource = new Resource(
|
||||
QString("%1").arg(m_uidGenerator->GenerateUid()),
|
||||
"article");
|
||||
QJsonObject json;
|
||||
json["title"] = "New Article";
|
||||
json["body"] = "Enter article body here";
|
||||
json["imageId"] = "0";
|
||||
QJsonDocument doc(json);
|
||||
QByteArray data = doc.toJson(QJsonDocument::Compact).toStdString().data();
|
||||
pResource->SetData(data);
|
||||
m_toUpload.push(pResource);
|
||||
AppendResource(pResource);
|
||||
m_order.append(pResource->GetId());
|
||||
return pResource;
|
||||
}
|
||||
|
||||
Resource* BuilderResourceManifest::AddImage(const QString& filename)
|
||||
{
|
||||
auto pResource = new Resource(
|
||||
QString("%1").arg(m_uidGenerator->GenerateUid()),
|
||||
"image");
|
||||
ImageDescriptor descriptor(*pResource);
|
||||
QString error;
|
||||
if (!descriptor.Read(filename, error))
|
||||
{
|
||||
m_syncUpdateCallback(error, LogError);
|
||||
delete pResource;
|
||||
return nullptr;
|
||||
}
|
||||
m_toUpload.push(pResource);
|
||||
AppendResource(pResource);
|
||||
return pResource;
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::UpdateResource(Resource* pResource)
|
||||
{
|
||||
if (!m_toUpload.contains(pResource))
|
||||
{
|
||||
pResource->SetVersion(pResource->GetVersion() + 1);
|
||||
m_toUpload.push(pResource);
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::UseResource(const QString& id)
|
||||
{
|
||||
auto pResource = FindById(id, m_resources);
|
||||
if (!pResource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
pResource->SetRefCount(pResource->GetRefCount() + 1);
|
||||
UpdateResource(pResource);
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::FreeResource(const QString& id)
|
||||
{
|
||||
auto pResource = FindById(id, m_resources);
|
||||
if (!pResource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_toDelete.contains(pResource))
|
||||
{
|
||||
return;
|
||||
}
|
||||
pResource->SetRefCount(pResource->GetRefCount() - 1);
|
||||
if (pResource->GetRefCount() <= 0)
|
||||
{
|
||||
m_toDelete.push(pResource);
|
||||
RemoveResource(pResource);
|
||||
m_toUpload.removeAll(pResource);
|
||||
|
||||
if (pResource->GetType().compare("article") == 0)
|
||||
{
|
||||
m_order.removeAll(pResource->GetId());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_toUpload.push(pResource);
|
||||
}
|
||||
}
|
||||
|
||||
bool BuilderResourceManifest::UpdateArticleOrder(const QString& id, bool direction, ErrorCode& error)
|
||||
{
|
||||
int index = m_order.indexOf(id);
|
||||
if (index == -1)
|
||||
{
|
||||
m_syncUpdateCallback(QString("Couldn't find article: %1").arg(id), LogError);
|
||||
error = ErrorCode::MissingArticle;
|
||||
return false;
|
||||
}
|
||||
m_order.removeAll(id);
|
||||
|
||||
index = index + (direction ? -1 : 1);
|
||||
if (index < 0)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
if (index > m_order.count())
|
||||
{
|
||||
index = m_order.count();
|
||||
}
|
||||
m_order.insert(index, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
EndpointManager* BuilderResourceManifest::GetEndpointManager() const
|
||||
{
|
||||
return m_endpointManager;
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::Sync()
|
||||
{
|
||||
if (!m_endpointManager->GetSelectedEndpoint())
|
||||
{
|
||||
FailSync(ErrorCode::NoEndpoint);
|
||||
return;
|
||||
}
|
||||
if (!InitS3Connector())
|
||||
{
|
||||
FailSync(ErrorCode::S3Fail);
|
||||
return;
|
||||
}
|
||||
ResourceManifest::Sync();
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::Reset()
|
||||
{
|
||||
if (s_syncing)
|
||||
{
|
||||
m_syncUpdateCallback("Sync is already running", LogError);
|
||||
return;
|
||||
}
|
||||
|
||||
m_toUpload.clear();
|
||||
|
||||
for (auto pResource : m_toDelete)
|
||||
{
|
||||
delete pResource;
|
||||
}
|
||||
m_toDelete.clear();
|
||||
|
||||
m_uidGenerator->Clear();
|
||||
|
||||
ResourceManifest::Reset();
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::PersistLocalResources()
|
||||
{
|
||||
// we are switching to another manifest here, while having the local data still present
|
||||
// so we need to explicitly mark it for uploading so that it does not get deleted
|
||||
for (auto pResource : m_resources)
|
||||
{
|
||||
if (!m_toUpload.contains(pResource))
|
||||
{
|
||||
m_toUpload.push(pResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::SetSyncType(SyncType syncType)
|
||||
{
|
||||
m_syncType = syncType;
|
||||
}
|
||||
|
||||
bool BuilderResourceManifest::HasChanges() const
|
||||
{
|
||||
return m_toUpload.count() > 0 || m_toDelete.count() > 0;
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::AppendResource(Resource* pResource)
|
||||
{
|
||||
m_uidGenerator->AddUid(pResource->GetId().toInt());
|
||||
ResourceManifest::AppendResource(pResource);
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::RemoveResource(Resource* pResource)
|
||||
{
|
||||
m_uidGenerator->RemoveUid(pResource->GetId().toInt());
|
||||
ResourceManifest::RemoveResource(pResource);
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::OnDownloadFail()
|
||||
{
|
||||
QMessageBox msgBox(QMessageBox::Critical,
|
||||
"Sync failed",
|
||||
QString("%1\n\n%2")
|
||||
.arg(GetErrorMessage(ErrorCode::ManifestDownloadFail))
|
||||
.arg(QObject::tr("Overwrite resource manifest?")),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (msgBox.exec() == QMessageBox::Yes)
|
||||
{
|
||||
if (!UploadManifest())
|
||||
{
|
||||
m_failed = true;
|
||||
m_errorCode = ErrorCode::ManifestUploadFail;
|
||||
}
|
||||
}
|
||||
ResourceManifest::OnDownloadFail();
|
||||
}
|
||||
|
||||
//! This function overrides ResourceManifest Read and tries to do some minimal version checking
|
||||
//! NOTE: version checking is not done yet, this needs a lot more work to version check properly
|
||||
ErrorCode BuilderResourceManifest::Read(const QJsonObject& json)
|
||||
{
|
||||
int version = json["version"].toInt();
|
||||
if (version > m_version && m_syncType == SyncType::Verify)
|
||||
{
|
||||
return ErrorCode::OutOfSync;
|
||||
}
|
||||
|
||||
m_version = version;
|
||||
QJsonArray resourceArray = json["resources"].toArray();
|
||||
|
||||
// initially mark ALL existing resource for deletion
|
||||
QList<Resource*> toDelete = m_resources;
|
||||
|
||||
for (auto resourceDoc : resourceArray)
|
||||
{
|
||||
auto pNewResource = new Resource(resourceDoc.toObject());
|
||||
// find local resource with the same id as new resource
|
||||
auto pOldResource = FindById(pNewResource->GetId(), m_resources);
|
||||
// if resource with the same id already exists then check its version
|
||||
if (pOldResource)
|
||||
{
|
||||
// local resource is outdated, keep its in delete list, and download new one instead
|
||||
if (pNewResource->GetVersion() > pOldResource->GetVersion())
|
||||
{
|
||||
if (m_syncType == SyncType::Merge)
|
||||
{
|
||||
m_toDownload.push(pNewResource);
|
||||
}
|
||||
else if (m_syncType == SyncType::Overwrite)
|
||||
{
|
||||
m_toDelete.push(pNewResource);
|
||||
}
|
||||
}
|
||||
// local resource is newer or same version, keep it (remove from toDelete list)
|
||||
// and don't need to download new one
|
||||
else
|
||||
{
|
||||
delete pNewResource;
|
||||
toDelete.removeAll(pOldResource);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if remote resource was NOT deleted locally then download it
|
||||
if (!FindById(pNewResource->GetId(), m_toDelete))
|
||||
{
|
||||
if (m_syncType == SyncType::Merge)
|
||||
{
|
||||
m_toDownload.push(pNewResource);
|
||||
}
|
||||
else if (m_syncType == SyncType::Overwrite)
|
||||
{
|
||||
m_toDelete.push(pNewResource);
|
||||
}
|
||||
}
|
||||
// otherwise user deleted it... needs version check here
|
||||
else
|
||||
{
|
||||
delete pNewResource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto pResource : m_toUpload)
|
||||
{
|
||||
toDelete.removeAll(pResource);
|
||||
}
|
||||
|
||||
for (auto pResource : toDelete)
|
||||
{
|
||||
RemoveResource(pResource);
|
||||
m_toDelete.removeAll(pResource);
|
||||
delete pResource;
|
||||
}
|
||||
|
||||
//! Sync article display order
|
||||
//! this is more complex to implement because articles may have been added or deleted
|
||||
//! remotely by another developer while newsbuilder was running
|
||||
//! for now just overwrite s3 version
|
||||
QJsonArray orderArray = json["order"].toArray();
|
||||
for (auto idObject : orderArray)
|
||||
{
|
||||
QString id = idObject.toString();
|
||||
if (FindById(id, m_toDownload) && !m_order.contains(id))
|
||||
{
|
||||
m_order.append(id);
|
||||
}
|
||||
}
|
||||
return ErrorCode::None;
|
||||
}
|
||||
|
||||
//! Write resource manifest to JSON
|
||||
void BuilderResourceManifest::Write(QJsonObject& json) const
|
||||
{
|
||||
QJsonArray resourceArray;
|
||||
foreach(auto pResource, m_resources)
|
||||
{
|
||||
QJsonObject resourceObject;
|
||||
pResource->Write(resourceObject);
|
||||
resourceArray.append(resourceObject);
|
||||
}
|
||||
json["resources"] = resourceArray;
|
||||
|
||||
QJsonArray orderArray;
|
||||
foreach(auto id, m_order)
|
||||
{
|
||||
orderArray.append(id);
|
||||
}
|
||||
json["order"] = orderArray;
|
||||
json["version"] = m_version;
|
||||
}
|
||||
|
||||
//! Figure out how many resources need to be synced
|
||||
void BuilderResourceManifest::PrepareForSync()
|
||||
{
|
||||
// if resource is locally marked for deletion, then we don't need to upload/download it
|
||||
for (auto pResource : m_toDelete)
|
||||
{
|
||||
m_toDownload.removeAll(pResource);
|
||||
m_toUpload.removeAll(pResource);
|
||||
}
|
||||
|
||||
m_syncLeft =
|
||||
m_toDownload.size() +
|
||||
m_toUpload.size() +
|
||||
m_toDelete.size();
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::SyncResources()
|
||||
{
|
||||
ResourceManifest::SyncResources();
|
||||
UploadResources();
|
||||
DeleteResources();
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::UploadResources()
|
||||
{
|
||||
QStack<Resource*> failures;
|
||||
while (m_toUpload.count() > 0)
|
||||
{
|
||||
m_syncUpdateCallback(
|
||||
QString("Uploading: %1 resources left").arg(m_toUpload.count()),
|
||||
LogInfo);
|
||||
|
||||
auto pResource = m_toUpload.pop();
|
||||
|
||||
auto uploadDescriptor = UploadDescriptor(*pResource);
|
||||
uploadDescriptor.Upload(*m_s3Connector,
|
||||
[&](QString url)
|
||||
{
|
||||
UpdateSync();
|
||||
},
|
||||
[&, pResource](QString error)
|
||||
{
|
||||
failures.push(pResource);
|
||||
m_failed = true;
|
||||
UpdateSync();
|
||||
m_syncUpdateCallback(
|
||||
error,
|
||||
LogError);
|
||||
});
|
||||
}
|
||||
while (failures.count() > 0)
|
||||
{
|
||||
m_toUpload.push(failures.pop());
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::DeleteResources()
|
||||
{
|
||||
while (m_toDelete.count() > 0)
|
||||
{
|
||||
m_syncUpdateCallback(
|
||||
QString("Deleting: %1 resources left").arg(m_toDelete.count()),
|
||||
LogInfo);
|
||||
|
||||
auto pResource = m_toDelete.pop();
|
||||
|
||||
auto deleteDescriptor = DeleteDescriptor(*pResource);
|
||||
deleteDescriptor.Delete(*m_s3Connector,
|
||||
[&, pResource]()
|
||||
{
|
||||
delete pResource;
|
||||
UpdateSync();
|
||||
},
|
||||
[&, pResource](QString error)
|
||||
{
|
||||
m_failed = true;
|
||||
delete pResource;
|
||||
UpdateSync();
|
||||
m_syncUpdateCallback(
|
||||
QString("Failed to delete resource: %1").arg(error),
|
||||
LogError);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BuilderResourceManifest::FinishSync()
|
||||
{
|
||||
if (!m_failed)
|
||||
{
|
||||
QString error;
|
||||
if (!UploadManifest())
|
||||
{
|
||||
m_failed = true;
|
||||
m_errorCode = ErrorCode::ManifestUploadFail;
|
||||
}
|
||||
}
|
||||
ResourceManifest::FinishSync();
|
||||
}
|
||||
|
||||
bool BuilderResourceManifest::UploadManifest()
|
||||
{
|
||||
m_syncUpdateCallback(QObject::tr("%1 to %2")
|
||||
.arg("Uploading manifest")
|
||||
.arg(m_endpointManager->GetSelectedEndpoint()->GetBucket()),
|
||||
LogInfo);
|
||||
m_version++;
|
||||
Aws::String awsError;
|
||||
QJsonObject manifestObject;
|
||||
Write(manifestObject);
|
||||
QJsonDocument doc(manifestObject);
|
||||
auto ss = Aws::MakeShared<Aws::StringStream>(
|
||||
S3Connector::ALLOCATION_TAG,
|
||||
std::ios::in | std::ios::out | std::ios::binary);
|
||||
*ss << QString(doc.toJson(QJsonDocument::Compact)).toStdString();
|
||||
Aws::String url;
|
||||
if (!m_s3Connector->PutObject("resourceManifest", ss, url, awsError))
|
||||
{
|
||||
m_syncUpdateCallback(QObject::tr(awsError.c_str()), LogError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuilderResourceManifest::InitS3Connector() const
|
||||
{
|
||||
auto awsProfileName =
|
||||
m_endpointManager->GetSelectedEndpoint()->GetAwsProfile();
|
||||
auto bucketName =
|
||||
m_endpointManager->GetSelectedEndpoint()->GetBucket();
|
||||
Aws::String awsError;
|
||||
if (!m_s3Connector->Init(
|
||||
awsProfileName.toStdString().c_str(),
|
||||
bucketName.toStdString().c_str(),
|
||||
awsError))
|
||||
{
|
||||
m_syncUpdateCallback(QObject::tr(awsError.c_str()), LogError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "NewsShared/ResourceManagement/ResourceManifest.h"
|
||||
|
||||
#include <QStack>
|
||||
|
||||
class QJsonObject;
|
||||
|
||||
namespace News
|
||||
{
|
||||
class EndpointManager;
|
||||
class ArticleDescriptor;
|
||||
class UidGenerator;
|
||||
class S3Connector;
|
||||
class QtDownloadManager;
|
||||
class Descriptor;
|
||||
class DownloadDescriptor;
|
||||
class Resource;
|
||||
|
||||
//! Type of sync behavior
|
||||
enum class SyncType
|
||||
{
|
||||
Merge, // merge resources from both endpoints, i.e. replacing outdated and appending missing (also normal sync behavior)
|
||||
Overwrite, // overwrite resources on new endpoint with old endpoint
|
||||
Verify // attempt to publish changes but abort if out of sync
|
||||
};
|
||||
|
||||
//! Adds news-builder functionality layer to resource manager
|
||||
class BuilderResourceManifest
|
||||
: public ResourceManifest
|
||||
{
|
||||
public:
|
||||
explicit BuilderResourceManifest(
|
||||
std::function<void()> syncSuccessCallback,
|
||||
std::function<void(ErrorCode)> syncFailCallback,
|
||||
std::function<void(QString, LogType)> syncUpdateCallback);
|
||||
|
||||
//! Create new article resource
|
||||
/*!
|
||||
Create new article with default parameters,
|
||||
Add it to resource collection,
|
||||
Mark it for upload.
|
||||
|
||||
\retval Resource * - a pointer to an article Resource
|
||||
*/
|
||||
Resource* AddArticle();
|
||||
|
||||
//! Create new image resource
|
||||
/*!
|
||||
Create new image from file,
|
||||
add it to resource collection,
|
||||
mark it for upload.
|
||||
|
||||
\param filename - path to an image on hard drive
|
||||
\retval Resource * - a pointer to an image Resource
|
||||
*/
|
||||
Resource* AddImage(const QString& filename);
|
||||
|
||||
//! If resource was modified, add it to upload list and increment its version
|
||||
void UpdateResource(Resource* resource);
|
||||
|
||||
//! When resource is used by several other resources, this function is called
|
||||
//! to increment its ref count
|
||||
void UseResource(const QString& id);
|
||||
|
||||
//! When resource is no longer used by another resource
|
||||
//! decrement refCount,
|
||||
//! if nothing else is using it, then mark for delete
|
||||
void FreeResource(const QString& id);
|
||||
|
||||
//! Move article either up or down in order queue
|
||||
bool UpdateArticleOrder(const QString& id, bool direction, ErrorCode& error);
|
||||
|
||||
EndpointManager* GetEndpointManager() const;
|
||||
|
||||
void Sync() override;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
//! When switching endpoints Merge allows to persist resources to another endpoint,
|
||||
//! thus copying news from one location to another upon next Sync
|
||||
void PersistLocalResources();
|
||||
|
||||
void SetSyncType(SyncType syncType);
|
||||
|
||||
//! Are there local changes
|
||||
bool HasChanges() const;
|
||||
|
||||
protected:
|
||||
void AppendResource(Resource* pResource) override;
|
||||
void RemoveResource(Resource* pResource) override;
|
||||
void OnDownloadFail() override;
|
||||
void FinishSync() override;
|
||||
|
||||
private:
|
||||
S3Connector* m_s3Connector = nullptr;
|
||||
UidGenerator* m_uidGenerator = nullptr;
|
||||
EndpointManager* m_endpointManager = nullptr;
|
||||
SyncType m_syncType = SyncType::Merge;
|
||||
|
||||
QStack<Resource*> m_toUpload;
|
||||
QStack<Resource*> m_toDelete;
|
||||
|
||||
ErrorCode Read(const QJsonObject& json) override;
|
||||
void Write(QJsonObject& json) const;
|
||||
|
||||
void PrepareForSync() override;
|
||||
void SyncResources() override;
|
||||
|
||||
void UploadResources();
|
||||
void DeleteResources();
|
||||
|
||||
bool UploadManifest();
|
||||
|
||||
//! Initializes S3 connector with selected endpoint
|
||||
bool InitS3Connector() const;
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "DeleteDescriptor.h"
|
||||
#include "NewsBuilder/S3Connector.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
DeleteDescriptor::DeleteDescriptor(Resource& resource)
|
||||
: Descriptor(resource) {}
|
||||
|
||||
void DeleteDescriptor::Delete(S3Connector& s3Connector,
|
||||
std::function<void()> deleteSuccessCallback,
|
||||
std::function<void(QString)> deleteFailCallback) const
|
||||
{
|
||||
Aws::String error;
|
||||
if (!s3Connector.DeleteObject(
|
||||
m_resource.GetId().toStdString().c_str(),
|
||||
error))
|
||||
{
|
||||
deleteFailCallback(QString("Error deleting resource %1: %2")
|
||||
.arg(m_resource.GetId())
|
||||
.arg(error.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
deleteSuccessCallback();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "NewsShared/ResourceManagement/Descriptor.h"
|
||||
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
namespace News
|
||||
{
|
||||
class S3Connector;
|
||||
|
||||
class DeleteDescriptor
|
||||
: public Descriptor
|
||||
{
|
||||
public:
|
||||
explicit DeleteDescriptor(Resource& resource);
|
||||
|
||||
void Delete(S3Connector& s3Connector,
|
||||
std::function<void()> deleteSuccessCallback,
|
||||
std::function<void(QString)> deleteFailCallback) const;
|
||||
};
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ImageDescriptor.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
|
||||
#include <QImageReader>
|
||||
#include <QBuffer>
|
||||
#include <QPixmap>
|
||||
#include <QVariant>
|
||||
#include <QFile>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
ImageDescriptor::ImageDescriptor(
|
||||
Resource& resource)
|
||||
: Descriptor(resource)
|
||||
{
|
||||
}
|
||||
|
||||
bool ImageDescriptor::Read(const QString& filename, QString& error) const
|
||||
{
|
||||
QImageReader reader(filename);
|
||||
if (!reader.canRead())
|
||||
{
|
||||
error = reader.errorString();
|
||||
return false;
|
||||
}
|
||||
QImage image = reader.read();
|
||||
|
||||
QPixmap pixmap(filename);
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
QFile test("test.png");
|
||||
if (pixmap.save(&buffer, "PNG"))
|
||||
{
|
||||
m_resource.SetData(data);
|
||||
return true;
|
||||
}
|
||||
error = QString("failed to save image %1").arg(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NewsShared/ResourceManagement/Descriptor.h>
|
||||
|
||||
class QString;
|
||||
|
||||
namespace News
|
||||
{
|
||||
class ImageDescriptor
|
||||
: public Descriptor
|
||||
{
|
||||
public:
|
||||
explicit ImageDescriptor(Resource& resource);
|
||||
|
||||
bool Read(const QString& filename, QString& error) const;
|
||||
};
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "NewsBuilder/S3Connector.h"
|
||||
#include "UploadDescriptor.h"
|
||||
#include "NewsShared/ResourceManagement/Resource.h"
|
||||
|
||||
#include <functional>
|
||||
#include <aws/core/utils/memory/stl/AwsStringStream.h>
|
||||
#include <aws/core/utils/memory/stl/AWSStreamFwd.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
UploadDescriptor::UploadDescriptor(Resource& resource)
|
||||
: Descriptor(resource) {}
|
||||
|
||||
void UploadDescriptor::Upload(S3Connector& s3Connector,
|
||||
std::function<void(QString)> uploadSuccessCallback,
|
||||
std::function<void(QString)> uploadFailCallback) const
|
||||
{
|
||||
Aws::String error;
|
||||
|
||||
auto ss =
|
||||
Aws::MakeShared<Aws::StringStream>(S3Connector::ALLOCATION_TAG,
|
||||
std::ios::in | std::ios::out | std::ios::binary);
|
||||
auto* pbuf = ss->rdbuf();
|
||||
pbuf->sputn(m_resource.GetData().data(), m_resource.GetData().size());
|
||||
Aws::String awsUrl;
|
||||
|
||||
if (!s3Connector.PutObject(
|
||||
m_resource.GetId().toStdString().c_str(),
|
||||
ss,
|
||||
m_resource.GetData().size(),
|
||||
awsUrl,
|
||||
error))
|
||||
{
|
||||
uploadFailCallback(QObject::tr("Error uploading resource %1: %2")
|
||||
.arg(m_resource.GetId())
|
||||
.arg(error.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
uploadSuccessCallback(QString(awsUrl.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "NewsShared/ResourceManagement/Descriptor.h"
|
||||
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
namespace News
|
||||
{
|
||||
class S3Connector;
|
||||
|
||||
class UploadDescriptor
|
||||
: public Descriptor
|
||||
{
|
||||
public:
|
||||
explicit UploadDescriptor(Resource& resource);
|
||||
|
||||
void Upload(S3Connector& s3Connector,
|
||||
std::function<void(QString)> uploadSuccessCallback,
|
||||
std::function<void(QString)> uploadFailCallback) const;
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
QLabel
|
||||
{
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
line-height: 20px;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
QLabel#titleLabel
|
||||
{
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
QLabel#bodyLabel
|
||||
{
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
QFrame#viewContainer[articleStyle="pinned"]
|
||||
{
|
||||
background: rgba(180,139,255,5%);
|
||||
border: 1px solid #B48BFF;
|
||||
box-shadow: 0 0 4px 0 rgba(0,0,0,50%);
|
||||
}
|
||||
|
||||
QWidget#articleViewContainerRoot
|
||||
{
|
||||
background: #222222;
|
||||
}
|
||||
|
||||
QScrollArea#previewArea,
|
||||
QWidget#articleViewContents,
|
||||
QFrame#imageFrame
|
||||
{
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
News--ArticleView.SelectedArticle > QWidget
|
||||
{
|
||||
background: #333333;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4255a25636d77a54809592bc98bef47fa9044be03cd65d73daa821711489e00f
|
||||
size 7379
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "S3Connector.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <AzFramework/AzFramework_Traits_Platform.h>
|
||||
|
||||
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4819, "-Wunknown-warning-option") // Invalid character not in default code page
|
||||
#include <aws/core/auth/AWSCredentialsProviderChain.h>
|
||||
#include <aws/core/utils/Outcome.h>
|
||||
#include <aws/s3/model/PutObjectRequest.h>
|
||||
#include <aws/s3/model/GetObjectRequest.h>
|
||||
#include <aws/s3/model/DeleteObjectRequest.h>
|
||||
#include <aws/core/utils/memory/stl/AwsStringStream.h>
|
||||
#include <aws/core/utils/HashingUtils.h>
|
||||
#include <aws/core/Aws.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace News
|
||||
{
|
||||
const char* S3Connector::ALLOCATION_TAG = "NewsBuilder";
|
||||
|
||||
S3Connector::S3Connector()
|
||||
: m_s3Client(nullptr)
|
||||
, m_limiter(nullptr)
|
||||
, m_valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
S3Connector::~S3Connector() {}
|
||||
|
||||
bool S3Connector::Init(const char* awsProfileName, const char* bucket, Aws::String& error)
|
||||
{
|
||||
Aws::SDKOptions options;
|
||||
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Trace;
|
||||
Aws::InitAPI(options);
|
||||
|
||||
Aws::Client::ClientConfiguration config;
|
||||
config.enableTcpKeepAlive = AZ_TRAIT_AZFRAMEWORK_AWS_ENABLE_TCP_KEEP_ALIVE_SUPPORTED;
|
||||
config.scheme = Aws::Http::Scheme::HTTPS;
|
||||
config.connectTimeoutMs = 30000;
|
||||
config.requestTimeoutMs = 30000;
|
||||
config.readRateLimiter = m_limiter;
|
||||
config.writeRateLimiter = m_limiter;
|
||||
|
||||
auto provider =
|
||||
Aws::MakeShared<Aws::Auth::ProfileConfigFileAWSCredentialsProvider>(
|
||||
ALLOCATION_TAG,
|
||||
awsProfileName);
|
||||
|
||||
auto accessKeyId = provider->GetAWSCredentials().GetAWSAccessKeyId();
|
||||
|
||||
//! verify that credential file exists
|
||||
if (accessKeyId.empty())
|
||||
{
|
||||
error = "LY_NEWS_DEVELOPER AWS credentials not found. Add credentials in LY Editor AWS->ClientManager";
|
||||
m_valid = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bucket = Aws::String(bucket);
|
||||
m_s3Client = Aws::MakeShared<Aws::S3::S3Client>(
|
||||
ALLOCATION_TAG,
|
||||
provider,
|
||||
config);
|
||||
|
||||
m_valid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool S3Connector::GetObject(const char* key,
|
||||
Aws::String& data,
|
||||
Aws::String& url,
|
||||
Aws::String& error) const
|
||||
{
|
||||
if (!m_valid)
|
||||
{
|
||||
error = "Client not initialized";
|
||||
return false;
|
||||
}
|
||||
|
||||
Aws::S3::Model::GetObjectRequest getObjectRequest;
|
||||
getObjectRequest.SetBucket(m_bucket);
|
||||
getObjectRequest.SetKey(key);
|
||||
auto outcome = m_s3Client->GetObject(getObjectRequest);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
error = outcome.GetError().GetMessage();
|
||||
return false;
|
||||
}
|
||||
url = m_s3Client->GeneratePresignedUrl(m_bucket, key, Aws::Http::HttpMethod::HTTP_GET);
|
||||
Aws::StringStream ss;
|
||||
ss << outcome.GetResult().GetBody().rdbuf();
|
||||
data = ss.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool S3Connector::PutObject(const char* key,
|
||||
STREAM_PTR stream,
|
||||
Aws::String& url,
|
||||
Aws::String& error) const
|
||||
{
|
||||
return PutObject(key, stream, GetStreamLength(stream), url, error);
|
||||
}
|
||||
|
||||
bool S3Connector::PutObject(const char* key,
|
||||
STREAM_PTR stream,
|
||||
int length,
|
||||
Aws::String& url,
|
||||
Aws::String& error) const
|
||||
{
|
||||
if (!m_valid)
|
||||
{
|
||||
error = "Client not initialized";
|
||||
return false;
|
||||
}
|
||||
|
||||
Aws::S3::Model::PutObjectRequest putObjectRequest;
|
||||
putObjectRequest.SetBucket(m_bucket);
|
||||
putObjectRequest.SetBody(stream);
|
||||
putObjectRequest.SetContentLength(length);
|
||||
putObjectRequest.SetContentMD5(
|
||||
Aws::Utils::HashingUtils::Base64Encode(
|
||||
Aws::Utils::HashingUtils::CalculateMD5(*putObjectRequest.GetBody())));
|
||||
putObjectRequest.SetContentType(Aws::String("binary/octet-stream"));
|
||||
putObjectRequest.SetKey(key);
|
||||
putObjectRequest.SetACL(Aws::S3::Model::ObjectCannedACL::public_read);
|
||||
auto outcome = m_s3Client->PutObject(putObjectRequest);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
error = outcome.GetError().GetMessage();
|
||||
return false;
|
||||
}
|
||||
url = m_s3Client->GeneratePresignedUrl(m_bucket, key, Aws::Http::HttpMethod::HTTP_GET);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool S3Connector::DeleteObject(const char* key, Aws::String& error) const
|
||||
{
|
||||
if (!m_valid)
|
||||
{
|
||||
error = "Client not initialized";
|
||||
return false;
|
||||
}
|
||||
|
||||
Aws::S3::Model::DeleteObjectRequest deleteObjectRequest;
|
||||
deleteObjectRequest.SetBucket(m_bucket);
|
||||
deleteObjectRequest.SetKey(key);
|
||||
auto outcome = m_s3Client->DeleteObject(deleteObjectRequest);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
error = outcome.GetError().GetMessage();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int S3Connector::GetStreamLength(STREAM_PTR stream)
|
||||
{
|
||||
stream->seekg(0, std::ios::end);
|
||||
auto length = stream->tellg();
|
||||
stream->seekg(0, std::ios::beg);
|
||||
return static_cast<int>(length);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/PlatformDef.h>
|
||||
#include <memory>
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4355 4996, "-Wunknown-warning-option") // <future> includes ppltasks.h which throws a C4355 warning: 'this' used in base member initializer list
|
||||
#include <aws/s3/S3Client.h>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
typedef std::shared_ptr<Aws::IOStream> STREAM_PTR;
|
||||
|
||||
namespace News
|
||||
{
|
||||
//! A light wrapper around AWS SDK
|
||||
class S3Connector
|
||||
{
|
||||
public:
|
||||
static const char* ALLOCATION_TAG;
|
||||
|
||||
S3Connector();
|
||||
~S3Connector();
|
||||
|
||||
//! Make s3 client using credentials stored in [user]/.aws/credentials file
|
||||
/*!
|
||||
\param awsProfileName - name of AWS credentials
|
||||
\param bucket - name of s3 bucket to use for AWS operations
|
||||
\param error - error string
|
||||
\retval bool - true if success else false
|
||||
*/
|
||||
bool Init(const char* awsProfileName, const char* bucket, Aws::String& error);
|
||||
|
||||
bool GetObject(const char* key,
|
||||
Aws::String& data,
|
||||
Aws::String& url,
|
||||
Aws::String& error) const;
|
||||
|
||||
bool PutObject(const char* key,
|
||||
STREAM_PTR stream,
|
||||
Aws::String& url,
|
||||
Aws::String& error) const;
|
||||
|
||||
bool PutObject(const char* key,
|
||||
STREAM_PTR stream,
|
||||
int length,
|
||||
Aws::String& url,
|
||||
Aws::String& error) const;
|
||||
|
||||
bool DeleteObject(const char* key,
|
||||
Aws::String& error) const;
|
||||
|
||||
private:
|
||||
Aws::String m_bucket;
|
||||
std::shared_ptr<Aws::S3::S3Client> m_s3Client;
|
||||
std::shared_ptr<Aws::Utils::RateLimits::RateLimiterInterface> m_limiter;
|
||||
bool m_valid;
|
||||
|
||||
static int GetStreamLength(STREAM_PTR stream);
|
||||
};
|
||||
} // namespace News
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "UidGenerator.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
namespace News
|
||||
{
|
||||
|
||||
UidGenerator::UidGenerator()
|
||||
{
|
||||
srand(static_cast<int>(time(nullptr)));
|
||||
}
|
||||
|
||||
int UidGenerator::GenerateUid()
|
||||
{
|
||||
int uid;
|
||||
do
|
||||
{
|
||||
uid = rand();
|
||||
}
|
||||
while (std::find(m_uids.begin(), m_uids.end(), uid) != m_uids.end());
|
||||
m_uids.push_back(uid);
|
||||
return uid;
|
||||
}
|
||||
|
||||
int UidGenerator::AddUid(int uid)
|
||||
{
|
||||
if (std::find(m_uids.begin(), m_uids.end(), uid) == m_uids.end())
|
||||
{
|
||||
m_uids.push_back(uid);
|
||||
}
|
||||
return uid;
|
||||
}
|
||||
|
||||
void UidGenerator::RemoveUid(int uid)
|
||||
{
|
||||
auto it = std::find(m_uids.begin(), m_uids.end(), uid);
|
||||
if (it != m_uids.end())
|
||||
{
|
||||
m_uids.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void UidGenerator::Clear()
|
||||
{
|
||||
m_uids.clear();
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user