Merge branch 'development' into LYN-3705-2
commit
4c627405f2
@ -1,73 +0,0 @@
|
||||
---
|
||||
name: RFC Feature request
|
||||
about: Create Feature RFC for this project
|
||||
title: Proposed RFC Feature =description=
|
||||
labels: 'rfc-feature'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# O3DE RFC Feature Template
|
||||
|
||||
### When using this template, you do not have to fill out every question below. The questions are there for guidance.
|
||||
|
||||
This RFC feature template should be used for any feature that is not a bug or a substantial reorganization of the O3DE product.
|
||||
|
||||
If you submit a pull request to implement a new feature without going through the RFC process, it may be closed with a polite request to submit an RFC first.
|
||||
|
||||
A hastily proposed RFC can hurt its chances of acceptance. Low-quality proposals, proposals for previously-rejected features, or those that don't fit into the near-term roadmap may be quickly rejected, demotivating the unprepared contributor. Laying some groundwork ahead of the RFC can make the process smoother.
|
||||
|
||||
Although there is no single way to prepare for submitting an RFC, it is generally a good idea to pursue feedback from other project developers beforehand to ascertain that the RFC may be desirable; having a consistent impact on the project requires concerted effort toward consensus-building.
|
||||
|
||||
The most common preparations for writing and submitting an RFC include:
|
||||
- Talking the idea over on our Discord server.
|
||||
- Discussing the topic on our GitHub RFCs discussions page.
|
||||
- Occasionally posting "pre-RFCs" on the GitHub RFCs discussion page.
|
||||
You may file issues in the RFCs repo for discussion, but these are not actively looked at by the teams.
|
||||
|
||||
As a rule of thumb, receiving encouraging feedback from long-standing project developers, and particularly members of the relevant sub-team, is a good indication that the RFC is worth pursuing.
|
||||
|
||||
# ----- DELETE EVERYTHING FROM THE TOP TO THE SUMMARY LINE BELOW WHEN USING TEMPLATE ----- #
|
||||
|
||||
### Summary:
|
||||
Single paragraph explanation of the feature
|
||||
|
||||
### What is the relevance of this feature?
|
||||
Why is this important? What are the use cases? What will it do once completed?
|
||||
|
||||
### Feature design description:
|
||||
- Explain the design of the feature with enough detail that someone familiar with the environment and framework can understand the concept and explain it to others.
|
||||
- It should include at least one end-to-end example of how a developer will use it along with specific details, including outlying use cases.
|
||||
|
||||
- If there is any new terminology, it should be defined here.
|
||||
|
||||
### Technical design description:
|
||||
- Explain the technical portion of the work in enough detail that members can implement the feature.
|
||||
|
||||
- Explain any API or process changes required to implement this feature
|
||||
|
||||
- This section should relate to the feature design description by reference and explain in greater detail how it makes the feature design examples work.
|
||||
|
||||
- This should also provide detailed information on compatibility with different hardware platforms.
|
||||
|
||||
|
||||
### What are the advantages of the feature?
|
||||
- Explain the advantages for someone to use this feature
|
||||
|
||||
### What are the disadvantages of the feature?
|
||||
- Explain any disadvantages for someone to use this feature
|
||||
|
||||
### How will this be implemented or integrated into the O3DE environment?
|
||||
- Explain how a developer will integrate this into the codebase of O3DE and provide any specific library or technical stack requirements.
|
||||
|
||||
### Are there any alternatives to this feature?
|
||||
- Provide any other designs that have been considered. Explain what the impact might be of not doing this.
|
||||
- If there is any prior art or approaches with other frameworks in the same domain, explain how they may have solved this problem or implemented this feature.
|
||||
|
||||
### How will users learn this feature?
|
||||
- Detail how it can be best presented and how it is used as an extension or a standalone tool used with O3DE.
|
||||
- Explain if and how it may change how individuals would use the platform and if any documentation must be changed or reorganized.
|
||||
- Explain how it would be taught to new and existing O3DE users.
|
||||
|
||||
### Are there any open questions?
|
||||
- What are some of the open questions and potential scenarios that should be considered?
|
||||
@ -1,61 +0,0 @@
|
||||
---
|
||||
name: RFC Suggestion request
|
||||
about: Create Suggestion RFC for this project
|
||||
title: Proposed RFC Suggestion =description=
|
||||
labels: 'rfc-suggestion'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# O3DE Suggestion RFC Template
|
||||
|
||||
### When using this template, you do not have to fill out every question below. The questions are there for guidance.
|
||||
|
||||
This RFC template should be used for any suggestion that is not based upon code or content related to the O3DE product itself. This template is for proposing new process models, approaches, or ideas to improve the O3DE community.
|
||||
|
||||
A hastily proposed RFC can hurt its chances of acceptance. Low-quality proposals, proposals for previously rejected features, or those that do not have any substantive value to the project may be quickly rejected, demotivating the unprepared contributor. Laying some groundwork with others in the community ahead of the RFC can make the process much smoother.
|
||||
|
||||
Although there is no single way to prepare for submitting an RFC, it is generally a good idea to pursue feedback from other project members beforehand. Keep in mind that you want other members to contribute and back your suggestion, which can drastically improve the chances of implementation.
|
||||
|
||||
The most common preparations for writing and submitting an RFC include:
|
||||
- Talking the idea over on our Discord server.
|
||||
- Creating a discussion on our GitHub RFCs discussions page.
|
||||
- Occasionally posting "pre-RFCs" on the GitHub RFCs discussion page.
|
||||
You may file issues in the RFCs repo for discussion, but these are not actively looked at by the teams.
|
||||
|
||||
As a rule of thumb, receiving encouraging feedback from long-standing community members is a good indication that the RFC is worth pursuing.
|
||||
|
||||
# ----- DELETE EVERYTHING FROM THE TOP TO THE SUMMARY LINE BELOW WHEN USING TEMPLATE ----- #
|
||||
|
||||
### Summary:
|
||||
Single paragraph explanation of the suggestion
|
||||
|
||||
### What is the motivation for this suggestion?
|
||||
Why is this important?
|
||||
What are the use cases for this suggestion?
|
||||
What should the outcome be if this suggestion is implemented?
|
||||
|
||||
### Suggestion design description:
|
||||
- Explain the suggestion with enough detail that someone familiar with the process and environment of the project can understand the suggestion and explain it to others.
|
||||
- It should include at least one end-to-end example of how the community will use it along with the specific details with outlying use cases.
|
||||
|
||||
- If there is any new terminology, it should be defined here.
|
||||
|
||||
### What are the advantages of the suggestion?
|
||||
- Explain the advantages of using this suggestion
|
||||
|
||||
### What are the disadvantages of the suggestion?
|
||||
- Explain any disadvantages or trade-offs to using this suggestion
|
||||
|
||||
### How will this be work within the O3DE project?
|
||||
- Explain how this suggestion will be work within the O3DE project.
|
||||
|
||||
### Are there any alternatives to this suggestion?
|
||||
- Provide any other alternative ways that have been considered.
|
||||
- Explain what the impact might be of not implementing this suggestion.
|
||||
- If there are other similar suggestions previously used, list them and explain which parts may have solved some or all of this problem.
|
||||
|
||||
### What is the strategy for adoption?
|
||||
- Explain how new and existing users will adopt this suggestion.
|
||||
- Point out any efforts needed if it requires coordination with multiple SIGs or other projects.
|
||||
- Explain how it would be taught to new and existing O3DE users.
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,284 +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>
|
||||
#include <QTreeView>
|
||||
#include <QStandardItemModel>
|
||||
#include <QHeaderView>
|
||||
|
||||
#include <AzQtComponents/Components/Widgets/SpinBox.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/any.h>
|
||||
|
||||
#include <ISystem.h>
|
||||
#endif
|
||||
|
||||
class QGridLayout;
|
||||
class QLabel;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class GraphicsSettingsDialog;
|
||||
}
|
||||
|
||||
// Description:
|
||||
// Status of cvar for a specifc platform and spec level
|
||||
// editedValue - current setting within Graphics Settings Dialog box
|
||||
// overwrittenValue - original setting from platform config file (set to originalValue if not found)
|
||||
// originalValue - original settings from sys_spec config file index
|
||||
|
||||
struct CVarFileStatus
|
||||
{
|
||||
AZStd::any editedValue;
|
||||
AZStd::any overwrittenValue;
|
||||
AZStd::any originalValue;
|
||||
CVarFileStatus(AZStd::any edit, AZStd::any over, AZStd::any orig) : editedValue(edit), overwrittenValue(over), originalValue(orig) {}
|
||||
};
|
||||
|
||||
// Description:
|
||||
// Status of specific cvar for Editor mapping
|
||||
// type - CVAR_INT / CVAR_FLOAT / CVAR_STRING
|
||||
// cvarGroup - source of cvar (sys_spec_particles, sys_spec_physics, etc.) or "miscellaneous" if only specified in platform config file
|
||||
// fileVals = CVarFileStatus for each spec level of a specific platform
|
||||
|
||||
struct CVarInfo
|
||||
{
|
||||
int type;
|
||||
AZStd::string cvarGroup;
|
||||
AZStd::vector<CVarFileStatus> fileVals;
|
||||
};
|
||||
|
||||
enum class GraphicsSettings
|
||||
{
|
||||
GameEffects,
|
||||
Light,
|
||||
ObjectDetail,
|
||||
Particles,
|
||||
Physics,
|
||||
PostProcessing,
|
||||
Quality,
|
||||
Shading,
|
||||
Shadows,
|
||||
Sound,
|
||||
Texture,
|
||||
TextureResolution,
|
||||
VolumetricEffects,
|
||||
Water,
|
||||
Miscellaneous,
|
||||
numSettings
|
||||
};
|
||||
|
||||
class GraphicsSettingsHeaderView;
|
||||
|
||||
class GraphicsSettingsTreeView
|
||||
: public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GraphicsSettingsTreeView(QWidget* parent = nullptr);
|
||||
|
||||
};
|
||||
|
||||
class GraphicsSettingsModel
|
||||
: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GraphicsSettingsModel(QObject* parent = 0);
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
};
|
||||
|
||||
class GraphicsSettingsDialog
|
||||
: public QDialog,
|
||||
public ILoadConfigurationEntrySink
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit GraphicsSettingsDialog(QWidget* parent = nullptr);
|
||||
virtual ~GraphicsSettingsDialog();
|
||||
|
||||
bool IsCustom(void) { return m_showCustomSpec; }
|
||||
void UnloadCustomSpec(int specLevel);
|
||||
|
||||
// ILoadConfigurationEntrySink
|
||||
void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) override;
|
||||
|
||||
public slots:
|
||||
//Accept and reject
|
||||
void reject() override;
|
||||
void accept() override;
|
||||
|
||||
private slots:
|
||||
//Update UIs
|
||||
void PlatformChanged(const QString& platform);
|
||||
bool CVarChanged(AZStd::any val, const char* cvarName, int specLevel);
|
||||
void CVarChanged(int i);
|
||||
void CVarChanged(double d);
|
||||
void CVarChanged(const QString& s);
|
||||
|
||||
private:
|
||||
|
||||
// The struct ParameterWidget is used to store the parameter widget
|
||||
// m_parameterName will be the name of the parameter the widget represent.
|
||||
struct ParameterWidget
|
||||
{
|
||||
ParameterWidget(QWidget* widget, QString parameterName = "");
|
||||
|
||||
QString GetToolTip() const;
|
||||
|
||||
const char* PARAMETER_TOOLTIP = "The variable will update render parameter \"%1\".";
|
||||
QWidget* m_widget;
|
||||
QString m_parameterName;
|
||||
};
|
||||
|
||||
struct CollapseGroup
|
||||
{
|
||||
QString m_groupName;
|
||||
QStandardItem* m_groupRow;
|
||||
QTreeView* m_treeView;
|
||||
bool m_isCollapsed;
|
||||
|
||||
CollapseGroup(QTreeView* treeView);
|
||||
|
||||
void ToggleCollapsed();
|
||||
};
|
||||
|
||||
void OpenCustomSpecDialog();
|
||||
void ApplyCustomSpec(const QString& customFilePath);
|
||||
bool IsCustomSpecAlreadyLoaded(const AZStd::string& filename) const;
|
||||
void SetSettingsTree(int numColumns);
|
||||
void SetCollapsed(const QModelIndex& index, bool flag);
|
||||
|
||||
enum CVarStateComparison
|
||||
{
|
||||
EDITED_OVERWRITTEN_COMPARE = 1,
|
||||
EDITED_ORIGINAL_COMPARE = 2,
|
||||
OVERWRITTEN_ORIGINAL_COMPARE = 3,
|
||||
|
||||
END_CVARSTATE_COMPARE,
|
||||
};
|
||||
|
||||
bool CheckCVarStatesForDiff(AZStd::pair<AZStd::string, CVarInfo>* it, int cfgFileIndex, CVarStateComparison cmp);
|
||||
|
||||
// Save out settings into project-level cfg files
|
||||
void SaveSystemSettings();
|
||||
|
||||
// Load in project-level cfg files for current platform
|
||||
void LoadPlatformConfigurations();
|
||||
// Build UI column for spec level of current platform
|
||||
void BuildColumn(int specLevel);
|
||||
// Initial UI building
|
||||
void BuildUI();
|
||||
// Cleaning out UI before loading new platform information
|
||||
void CleanUI();
|
||||
// Shows/hides custom spec option
|
||||
void ShowCustomSpecOption(bool show);
|
||||
// Shows/hides category labels and dropdowns
|
||||
void ShowCategories(bool show);
|
||||
// Warns about unsaved changes (returns true if accepted)
|
||||
bool SendUnsavedChangesWarning(bool cancel);
|
||||
|
||||
void LoadCVarGroupDirectory(const AZStd::string& path);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// UI help functions
|
||||
|
||||
// Setup collapsed buttons
|
||||
void SetCollapsedLayout(const QString& groupName, QStandardItem* groupItem);
|
||||
// Sets the platform entry index for the given platform
|
||||
void SetPlatformEntry(ESystemConfigPlatform platform);
|
||||
// Gets the platform enum given the platform name
|
||||
ESystemConfigPlatform GetConfigPlatformFromName(const AZStd::string& platformName);
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Members
|
||||
|
||||
// Qt values
|
||||
const int INPUT_MIN_WIDTH = 100;
|
||||
const int INPUT_MIN_HEIGHT = 20;
|
||||
const int INPUT_ROW_SPAN = 1;
|
||||
const int INPUT_COLUMN_SPAN = 1;
|
||||
const int CVAR_ROW_OFFSET = 2;
|
||||
const int CVAR_VALUE_COLUMN_OFFSET = 1;
|
||||
const int PLATFORM_LABEL_ROW = 1;
|
||||
const int CVAR_LABEL_COLUMN = 1;
|
||||
|
||||
// Tool tips
|
||||
const QString SETTINGS_FILE_PATH = "Config/spec/";
|
||||
const char* CFG_FILEFILTER = "Cfg File(*.cfg);;All files(*)";
|
||||
|
||||
const int m_numSpecLevels = 4;
|
||||
|
||||
bool m_showCustomSpec;
|
||||
bool m_showCategories;
|
||||
GraphicsSettingsModel* m_graphicsSettingsModel;
|
||||
GraphicsSettingsHeaderView* m_headerView;
|
||||
int m_numColumns{ 0 };
|
||||
|
||||
const char* m_cvarGroupsFolder = "Config/CVarGroups";
|
||||
|
||||
QScopedPointer<Ui::GraphicsSettingsDialog> m_ui;
|
||||
|
||||
QVector<CollapseGroup*> m_uiCollapseGroup;
|
||||
|
||||
QVector<ParameterWidget*> m_parameterWidgets;
|
||||
|
||||
AZStd::string m_currentConfigFilename;
|
||||
size_t m_currentSpecIndex;
|
||||
|
||||
// cvar name --> pair(type, CVarStatus for each file)
|
||||
AZStd::unordered_map<AZStd::string, CVarInfo> m_cVarTracker;
|
||||
|
||||
AZStd::unordered_map<ESystemConfigPlatform, AZStd::vector<AZStd::string> > m_cfgFiles;
|
||||
|
||||
AZStd::vector<AZStd::pair<AZStd::string, ESystemConfigPlatform> > m_platformStrings;
|
||||
|
||||
struct CVarGroupInfo
|
||||
{
|
||||
QVector<QLabel*> m_platformLabels;
|
||||
QVector<QLabel*> m_cvarLabels;
|
||||
QVector<AzQtComponents::SpinBox*> m_cvarSpinBoxes;
|
||||
QVector<AzQtComponents::DoubleSpinBox*> m_cvarDoubleSpinBoxes;
|
||||
QVector<QLineEdit*> m_cvarLineEdits;
|
||||
QVector<QToolButton*> m_specFileArea;
|
||||
QVector<QWidget*> m_widgetInsertOrder;
|
||||
QStandardItem* m_treeRowItem;
|
||||
int m_currentRow;
|
||||
};
|
||||
|
||||
AZStd::unordered_map<AZStd::string, CVarGroupInfo> m_cvarGroupData;
|
||||
AZStd::vector<AZStd::string> m_cvarGroupOrder;
|
||||
|
||||
ESystemConfigPlatform m_currentPlatform;
|
||||
|
||||
int m_dirtyCVarCount;
|
||||
};
|
||||
|
||||
class GraphicsSettingsHeaderView
|
||||
: public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GraphicsSettingsHeaderView(GraphicsSettingsDialog* dialog, Qt::Orientation orientation, QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
bool event(QEvent* e) override;
|
||||
void mouseMoveEvent(QMouseEvent* e) override;
|
||||
void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
GraphicsSettingsDialog* m_dialog;
|
||||
int m_index{ -1 };
|
||||
};
|
||||
|
||||
|
||||
@ -1,25 +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
|
||||
*
|
||||
*/
|
||||
|
||||
#GraphicsSettingsDialog QHeaderView::section
|
||||
{
|
||||
background: #2D2D2D;
|
||||
}
|
||||
|
||||
#GraphicsSettingsDialog QHeaderView::down-arrow
|
||||
{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
image: url(:/Gallery/Delete.svg);
|
||||
}
|
||||
|
||||
#GraphicsSettingsDialog QHeaderView::up-arrow
|
||||
{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
image: url(:/Gallery/Delete.svg);
|
||||
}
|
||||
@ -1,270 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GraphicsSettingsDialog</class>
|
||||
<widget class="QDialog" name="GraphicsSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1292</width>
|
||||
<height>565</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>400</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Graphics Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="m_generalLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="3">
|
||||
<widget class="QWidget" name="m_platform" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<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="QComboBox" name="m_platformEntry"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="m_selectCustomSpecButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Resource</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="m_platformLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Platform</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Line" name="m_lineSpacer">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="m_scrollArea">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1272</width>
|
||||
<height>452</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="GraphicsSettingsTreeView" name="m_graphicsSettingsTreeView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="m_horizontalLayout">
|
||||
<item>
|
||||
<spacer name="m_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="QPushButton" name="m_applyButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(233, 118, 17);</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_cancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>line</zorder>
|
||||
<zorder>m_scrollArea</zorder>
|
||||
<zorder>line_2</zorder>
|
||||
<zorder>widget</zorder>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>GraphicsSettingsTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>GraphicsSettingsDialog.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>m_cancelButton</tabstop>
|
||||
<tabstop>m_applyButton</tabstop>
|
||||
<tabstop>m_scrollArea</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue