1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #pragma once
9 
10 #include "ui/rp_widget.h"
11 #include "base/object_ptr.h"
12 
13 namespace Ui {
14 class InputField;
15 class ScrollArea;
16 class FadeShadow;
17 class PlainShadow;
18 class FlatLabel;
19 class RoundButton;
20 class VerticalLayout;
21 class SettingsButton;
22 class BoxContent;
23 template <typename Widget>
24 class SlideWrap;
25 } // namespace Ui
26 
27 namespace Passport::Ui {
28 using namespace ::Ui;
29 enum class PanelDetailsType;
30 class PanelDetailsRow;
31 } // namespace Passport::Ui
32 
33 namespace Passport {
34 
35 class PanelController;
36 struct ValueMap;
37 struct ScanInfo;
38 class EditScans;
39 enum class FileType;
40 struct ScanListData;
41 
42 struct EditDocumentCountry {
43 	QString countryCode;
44 	QString languageCode;
45 };
46 
47 struct EditDocumentScheme {
48 	enum class ValueClass {
49 		Fields,
50 		Additional,
51 		Scans,
52 	};
53 	enum class AdditionalVisibility {
54 		Hidden,
55 		OnlyIfError,
56 		Shown,
57 	};
58 	using CountryInfo = EditDocumentCountry;
59 	struct Row {
60 		using Validator = Fn<std::optional<QString>(const QString &value)>;
61 		using Formatter = Fn<QString(const QString &value)>;
62 		ValueClass valueClass = ValueClass::Fields;
63 		Ui::PanelDetailsType inputType = Ui::PanelDetailsType();
64 		QString key;
65 		QString label;
66 		Validator error;
67 		Formatter format;
68 		int lengthLimit = 0;
69 		QString keyForAttachmentTo; // Attach [last|middle]_name to first_*.
70 		QString additionalFallbackKey; // *_name_native from *_name.
71 	};
72 	std::vector<Row> rows;
73 	QString fieldsHeader;
74 	QString detailsHeader;
75 	QString scansHeader;
76 
77 	QString additionalDependencyKey;
78 	Fn<AdditionalVisibility(const CountryInfo &dependency)> additionalShown;
79 	Fn<QString(const CountryInfo &dependency)> additionalHeader;
80 	Fn<QString(const CountryInfo &dependency)> additionalDescription;
81 	Fn<rpl::producer<CountryInfo>(const QString &)> preferredLanguage;
82 
83 };
84 
85 class PanelEditDocument : public Ui::RpWidget {
86 public:
87 	using Scheme = EditDocumentScheme;
88 
89 	PanelEditDocument(
90 		QWidget *parent,
91 		not_null<PanelController*> controller,
92 		Scheme scheme,
93 		const QString &error,
94 		const ValueMap &data,
95 		const QString &scansError,
96 		const ValueMap &scansData,
97 		ScanListData &&scans,
98 		std::optional<ScanListData> &&translations,
99 		std::map<FileType, ScanInfo> &&specialFiles);
100 	PanelEditDocument(
101 		QWidget *parent,
102 		not_null<PanelController*> controller,
103 		Scheme scheme,
104 		const QString &scansError,
105 		const ValueMap &scansData,
106 		ScanListData &&scans,
107 		std::optional<ScanListData> &&translations,
108 		std::map<FileType, ScanInfo> &&specialFiles);
109 	PanelEditDocument(
110 		QWidget *parent,
111 		not_null<PanelController*> controller,
112 		Scheme scheme,
113 		const QString &error,
114 		const ValueMap &data);
115 
116 	bool hasUnsavedChanges() const;
117 
118 protected:
119 	void focusInEvent(QFocusEvent *e) override;
120 	void resizeEvent(QResizeEvent *e) override;
121 
122 private:
123 	struct Result;
124 	void setupControls(
125 		const QString *error,
126 		const ValueMap *data,
127 		const QString *scansError,
128 		const ValueMap *scansData,
129 		ScanListData &&scans,
130 		std::optional<ScanListData> &&translations,
131 		std::map<FileType, ScanInfo> &&specialFiles);
132 	not_null<Ui::RpWidget*> setupContent(
133 		const QString *error,
134 		const ValueMap *data,
135 		const QString *scansError,
136 		const ValueMap *scansData,
137 		ScanListData &&scans,
138 		std::optional<ScanListData> &&translations,
139 		std::map<FileType, ScanInfo> &&specialFiles);
140 	void updateControlsGeometry();
141 	void updateCommonError();
142 
143 	Result collect() const;
144 	void fillAdditionalFromFallbacks(Result &result) const;
145 	bool validate();
146 	void save();
147 
148 	void createDetailsRow(
149 		not_null<Ui::VerticalLayout*> container,
150 		int i,
151 		const Scheme::Row &row,
152 		const ValueMap &fields,
153 		int maxLabelWidth);
154 	not_null<Ui::PanelDetailsRow*> findRow(const QString &key) const;
155 
156 	not_null<PanelController*> _controller;
157 	Scheme _scheme;
158 
159 	object_ptr<Ui::ScrollArea> _scroll;
160 	object_ptr<Ui::FadeShadow> _topShadow;
161 	object_ptr<Ui::PlainShadow> _bottomShadow;
162 
163 	QPointer<EditScans> _editScans;
164 	QPointer<Ui::SlideWrap<Ui::FlatLabel>> _commonError;
165 	std::map<int, QPointer<Ui::PanelDetailsRow>> _details;
166 	bool _fieldsChanged = false;
167 	bool _additionalShown = false;
168 
169 	QPointer<Ui::SettingsButton> _delete;
170 
171 	object_ptr<Ui::RoundButton> _done;
172 
173 };
174 
175 object_ptr<Ui::BoxContent> RequestIdentityType(
176 	Fn<void(int index)> submit,
177 	std::vector<QString> labels);
178 object_ptr<Ui::BoxContent> RequestAddressType(
179 	Fn<void(int index)> submit,
180 	std::vector<QString> labels);
181 
182 object_ptr<Ui::BoxContent> ConfirmDeleteDocument(
183 	Fn<void(bool withDetails)> submit,
184 	const QString &text,
185 	const QString &detailsCheckbox = QString());
186 
187 } // namespace Passport
188