Audacity 3.2.0
CloudLocationDialog.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 CloudLocationDialog.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
11
12#include "CloudLocationDialog.h"
13
14#include <wx/button.h>
15#include <wx/checkbox.h>
16#include <wx/sizer.h>
17#include <wx/statbmp.h>
18#include <wx/statline.h>
19#include <wx/stattext.h>
20
21#include "AccessibilityUtils.h"
22
23#include "CloudModuleSettings.h"
24
25#include "../images/CloudImages.hpp"
26
28{
29namespace
30{
31enum class ChoiceMode
32{
33 Local,
34 User
35};
37{
39
40 // This pointer to the image is initialized on module load, we have to use a
41 // pointer pointer here
42 wxBitmap** RemoteImage;
46
47 wxBitmap** LocalImage;
51
53
55
57};
58
60 /* i18n-hint: A title that is shown on the first project save that allows the
61 user to select Cloud or local save. */
62 XO("How would you like to save?"),
64 XO("Save to the Cloud (free)"),
65 XO("Your project is backed up privately on audio.com. You can access your work from any device and collaborate on your project with others. Cloud saving is free for a limited number of projects."),
66 XXO("&Save to Cloud"),
68 XO("On your computer"),
69 XO("Files are saved on your device.\nNote: To export MP3 and WAV files, use File > Export Audio instead."),
70 XXO("Save to &computer"),
71 XO("&Remember my choice and don't show again"),
73 ChoiceMode::User,
74};
75
77 /* i18n-hint: A title that is shown on export that allows the user to select
78 Cloud or local export. */
79 XO("How would you like to export?"),
81 XO("Share to audio.com"),
82 XO("Uploads an uncompressed audio file and generates a shareable link. This link allows others to download the file in either .wav or .mp3 format."),
83 XXO("&Share to audio.com"),
85 XO("On your computer"),
86 XO("Export MP3s, WAVs, FLACs and other formats to your computer."),
87 XXO("Export to &computer"),
88 XO("&Don't show again"),
90 ChoiceMode::Local,
91};
92
93constexpr auto leftPadding = 16;
94
96{
97 return bin2c_SaveLocally_png->GetWidth() - leftPadding * 2;
98}
99
100std::unique_ptr<wxBoxSizer> SetupVerticalSizer(
101 wxStaticBitmap* image, wxStaticText* title, wxStaticText* description,
102 wxButton* button)
103{
104 const auto leftPaddingFlags = wxSizerFlags {}.Border(wxLEFT, leftPadding);
105
106 auto sizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
107
108 sizer->Add(image);
109 sizer->AddSpacer(24);
110 sizer->Add(title, leftPaddingFlags);
111 sizer->AddSpacer(12);
112 sizer->Add(description, leftPaddingFlags);
113 sizer->AddSpacer(40);
114 sizer->AddStretchSpacer(1);
115 sizer->Add(button, leftPaddingFlags);
116
117 return sizer;
118}
119
120wxButton* CreateButton(
121 wxWindow* parent, const wxFont& font, const TranslatableString& label)
122{
123 const auto transalatedLabel = label.Translation();
124
125 auto button = safenew wxButton(parent, wxID_ANY, transalatedLabel);
126
127 button->SetFont(font);
128
129 const auto textSize = button->GetTextExtent(transalatedLabel);
130
131 button->SetMinSize({ textSize.x + 12 * 2, 32 });
132
133 return button;
134}
135
136} // namespace
137
139 wxWindow* parent, LocationDialogType type)
140 : wxDialogWrapper { parent, wxID_ANY,
141 XO("Audacity"), wxDefaultPosition,
142 { 442, -1 }, wxDEFAULT_DIALOG_STYLE }
143 , mType { type }
144{
145 auto& description = type == LocationDialogType::Save ?
148
149 wxFont titleFont = GetFont();
150 titleFont.SetWeight(wxFONTWEIGHT_BOLD);
151 titleFont.SetPixelSize({ 0, 18 });
152
153 wxFont descriptionFont = GetFont();
154 descriptionFont.SetPixelSize({ 0, 14 });
155
156 auto title = safenew wxStaticText(
157 this, wxID_ANY, description.DialogTitle.Translation());
158 title->SetFont(titleFont);
159
160 auto saveToCloudImage =
161 safenew wxStaticBitmap(this, wxID_ANY, **description.RemoteImage);
162
163 auto saveToCloudTitle = safenew wxStaticText(
164 this, wxID_ANY, description.RemoteTitle.Translation());
165 saveToCloudTitle->SetFont(titleFont);
166
167 auto saveToCloudDescription = safenew wxStaticText(
168 this, wxID_ANY, description.RemoteDescription.Translation());
169 saveToCloudDescription->SetFont(descriptionFont);
170 saveToCloudDescription->Wrap(GetWrapWidth());
171
172 auto saveToCloudButton =
173 CreateButton(this, descriptionFont, description.RemoteButtonLabel);
174
175 auto saveToComputerImage =
176 safenew wxStaticBitmap(this, wxID_ANY, **description.LocalImage);
177
178 auto saveToComputerTitle = safenew wxStaticText(
179 this, wxID_ANY, description.LocalTitle.Translation());
180 saveToComputerTitle->SetFont(titleFont);
181
182 auto saveToComputerDescription = safenew wxStaticText(
183 this, wxID_ANY, description.LocalDescription.Translation());
184 saveToComputerDescription->SetFont(descriptionFont);
185 saveToComputerDescription->Wrap(GetWrapWidth());
186
187 auto saveToComputerButton =
188 CreateButton(this, descriptionFont, description.LocalButtonTitle);
189
190 auto rememberChoiceCheckbox = safenew wxCheckBox(
191 this, wxID_ANY,
192 description.DoNotShowLabel.Translation());
193
194 mDoNotShow = description.LocationMode.ReadEnum() != CloudLocationMode::Ask;
195 rememberChoiceCheckbox->SetValue(mDoNotShow);
196
197 auto sizer = safenew wxBoxSizer(wxVERTICAL);
198
199 sizer->Add(title, wxSizerFlags {}.CenterHorizontal().Border(wxTOP, 16));
200
201 auto topSizer = safenew wxBoxSizer(wxHORIZONTAL);
202
203 auto cloudSizer = SetupVerticalSizer(
204 saveToCloudImage, saveToCloudTitle, saveToCloudDescription,
205 saveToCloudButton);
206
207 topSizer->Add(cloudSizer.release(), wxSizerFlags {}.Expand());
208
209 auto computerSizer = SetupVerticalSizer(
210 saveToComputerImage, saveToComputerTitle, saveToComputerDescription,
211 saveToComputerButton);
212
213 topSizer->Add(
214 computerSizer.release(), wxSizerFlags {}.Expand().Border(wxLEFT, 8));
215
216 sizer->Add(topSizer, wxSizerFlags {}.Expand().Border(wxALL, 16));
217
218 sizer->Add(safenew wxStaticLine(this), wxSizerFlags {}.Expand());
219
220 sizer->Add(rememberChoiceCheckbox, wxSizerFlags {}.Border(wxALL, 16));
221
222 SetSizerAndFit(sizer);
223 SetupAccessibility(this);
224
225 Center();
226
227 Bind(
228 wxEVT_CHAR_HOOK,
229 [this](auto& evt)
230 {
231 if (!IsEscapeKey(evt))
232 {
233 evt.Skip();
234 return;
235 }
236
237 EndModal(wxID_CANCEL);
238 });
239
240 rememberChoiceCheckbox->Bind(
241 wxEVT_CHECKBOX, [this, rememberChoiceCheckbox](auto)
242 { mDoNotShow = rememberChoiceCheckbox->GetValue(); });
243
244 saveToCloudButton->Bind(wxEVT_BUTTON, [this](auto) { EndModal(wxID_SAVE); });
245 saveToComputerButton->Bind(
246 wxEVT_BUTTON, [this](auto) { EndModal(wxID_OK); });
247}
248
249CloudLocationDialog::~CloudLocationDialog()
250{
251}
252
253LocationDialogResult CloudLocationDialog::ShowDialog()
254{
255 auto& description = mType == LocationDialogType::Save ?
258
259 if (description.LocationMode.ReadEnum() != CloudLocationMode::Ask)
260 return description.LocationMode.ReadEnum() == CloudLocationMode::Cloud ?
261 LocationDialogResult::Cloud :
262 LocationDialogResult::Local;
263
264 const auto result = ShowModal();
265
266 if (result == wxID_OK)
267 {
268 if (mDoNotShow)
269 {
270 description.LocationMode.WriteEnum(CloudLocationMode::Local);
271 gPrefs->Flush();
272 }
273 return LocationDialogResult::Local;
274 }
275
276 if (result == wxID_SAVE)
277 {
278 if (mDoNotShow)
279 {
280 description.LocationMode.WriteEnum(
281 description.RememberChoiceMode == ChoiceMode::User ?
282 CloudLocationMode::Cloud :
283 CloudLocationMode::Local);
284 gPrefs->Flush();
285 }
286
287 return LocationDialogResult::Cloud;
288 }
289
290 return LocationDialogResult::Cancel;
291}
292
293} // namespace audacity::cloud::audiocom::sync
void SetupAccessibility(wxWindow *window)
wxBitmap * bin2c_ExportLocally_png
Definition: CloudImages.cpp:8
wxBitmap * bin2c_SaveRemote_png
Definition: CloudImages.cpp:7
wxBitmap * bin2c_SaveLocally_png
Definition: CloudImages.cpp:6
wxBitmap * bin2c_ExportRemote_png
Definition: CloudImages.cpp:9
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define safenew
Definition: MemoryX.h:10
static const auto title
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
TranslatableString label
Definition: TagsEditor.cpp:165
Enum ReadEnum() const
Definition: Prefs.h:534
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
virtual bool Flush() noexcept=0
CloudLocationDialog(wxWindow *parent, LocationDialogType type)
std::unique_ptr< wxBoxSizer > SetupVerticalSizer(wxStaticBitmap *image, wxStaticText *title, wxStaticText *description, wxButton *button)
wxButton * CreateButton(wxWindow *parent, const wxFont &font, const TranslatableString &label)
EnumSetting< CloudLocationMode > SaveLocationMode
EnumSetting< CloudLocationMode > ExportLocationMode