Audacity 3.2.0
WhatsNewDialog.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 WhatsNewDialog.cpp
7
8 Vitaly Sverchinsky
9
10**********************************************************************/
11
12#include "WhatsNewDialog.h"
13
14#include <wx/fs_mem.h>
15#include <wx/settings.h>
16#include <wx/mstream.h>
17#include <wx/sstream.h>
18#include <wx/txtstrm.h>
19#include <wx/hyperlink.h>
20#include <wx/checkbox.h>
21#include <wx/frame.h>
22#include <wx/statbmp.h>
23#include <wx/stattext.h>
24
25#include "HelpSystem.h"
26#include "HelpText.h"
27#include "ProjectWindows.h"
28#include "ShuttleGui.h"
29#include "Theme.h"
30#include "AllThemeResources.h"
31
32#include "../images/WhatsNewBtn.jpeg.h"
33#include "../images/MuseHub.jpeg.h"
34
35namespace
36{
37
38#if defined (__WXOSX__) || defined(__WXMSW__)
39# define SHOW_MUSEHUB
40#endif
41
42const char* WhatsNewURL = "https://audacityteam.org/3.7.0-video";
43const char* ChangeLogURL = "https://support.audacityteam.org/additional-resources/changelog";
44const char* MuseHubURL = "https://www.musehub.com";
45const char* PromoURL = "https://audacityteam.org/audacitypromo";
46
47#if defined(SHOW_MUSEHUB)
48 constexpr auto WindowWidth = 860;
49#else
50 constexpr auto WindowWidth = 440;
51#endif
52
53constexpr auto WindowHeight = 460;
54
55}
56AttachedWindows::RegisteredFactory sWhatsNewWindow{
57 []( AudacityProject &project ) -> wxWeakRef< wxWindow > {
58 auto &window = GetProjectFrame(project);
59 return safenew WhatsNewDialog(&window, wxID_ANY);
60 }
61};
62
63
64namespace
65{
66
67struct FSHelper final
68{
70 : mMemoryFSHandler(std::make_unique<wxMemoryFSHandler>())
71 {
72 wxFileSystem::AddHandler(mMemoryFSHandler.get());
73
74 wxMemoryFSHandler::AddFile(
75 "whats_new_btn.jpeg", bin2c_whats_new_btn_jpeg,
76 sizeof(bin2c_whats_new_btn_jpeg));
77 wxMemoryFSHandler::AddFile(
78 "musehub.jpeg", bin2c_musehub_jpeg,
79 sizeof(bin2c_musehub_jpeg));
80 }
81
83 {
84 wxMemoryFSHandler::RemoveFile("whats_new_btn.jpeg");
85 wxMemoryFSHandler::RemoveFile("musehub.jpeg");
86 wxFileSystem::RemoveHandler(mMemoryFSHandler.get());
87 }
88
89private:
90 std::unique_ptr<wxMemoryFSHandler> mMemoryFSHandler;
91};
92
94{
95 wxStringOutputStream o;
96 wxTextOutputStream s(o);
97 s
98 << wxT("<body>")
99 << wxT("<p><center>")
100 << wxT(R"(<p><a href=")") << WhatsNewURL << wxT(R"(">)")
101 // Bug: (Windows) specified width and height should match exactly to the size of the image
102 << wxT(R"(<img src="memory:whats_new_btn.jpeg" width="352" height="198" /><br></a></p>)")
103 << wxT("<h3>") << XO("What's new in Audacity %s").Format(AUDACITY_VERSION_STRING) << wxT("</h3>")
104 << wxT("<p>")
105 << XO("Watch the [[%s|release video]] or read the [[%s|changelog]] to learn more about what we have included in the latest release!</p>").Format(WhatsNewURL, ChangeLogURL);
106
107 return FormatHtmlText(o.GetString());
108}
109
111{
112 wxStringOutputStream o;
113 wxTextOutputStream s(o);
114 s
115 << wxT("<body>")
116 << wxT("<p><center>")
117 << wxT(R"(<p><a href=")") << PromoURL << wxT(R"(">)")
118 // Bug: (Windows) specified width and height should match exactly to the size of the image
119 << wxT(R"(<img src="memory:musehub.jpeg" width="352" height="198" /><br></a></p>)")
120#if 0
121 //we want to keep these strings, but not display them at the moment
122 << wxT("<h3>") << XO("Get free plugins & sounds")<< wxT("</h3>")
123 << XO("<p>Check out our [[%s|Muse Hub app]] for a wide range of audio plugins for Audacity users</p>").Format(MuseHubURL);
124
125 //we also may need these strings in the future. Adding them to the catalogue now so we don't have to send out multiple translation CTAs
126
127 << wxT("<h3>") << wxT("VocalStrip - Solid State Logic")<< wxT("</h3>")
128 << wxT("<p>") << XO("A vocal processing effect that enhances vocal clarity and depth.") << wxT(" ")
129 << wxT("<h3>") << wxT("Crystalline Next-gen Reverb")<< wxT("</h3>")
130 << wxT("<p>") << XO("A multipurpose reverb plugin for spacious, natural-sounding effects.") << wxT(" ")
131 << wxT("<h3>") << wxT("Ampkit Guitar Modeller")<< wxT("</h3>")
132 << wxT("<p>") << XO("A guitar amp and effects modelling plugin for realistic tones and customizable sounds.") << wxT(" ")
133 << wxT("<h3>") << wxT("BOREALIS Dynamic Reverb")<< wxT("</h3>")
134 << wxT("<p>") << XO("A responsive reverb plugin that adapts to track dynamics for immersive soundscapes.") << wxT(" ")
135 << wxT("<h3>") << wxT("LANDR FX Voice")<< wxT("</h3>")
136 << wxT("<p>") << XO("A vocal multi-effect plugin that enhances vocal tracks for professional results.") << wxT(" ")
137 << wxT("<h3>") << wxT("LANDR FX Bass")<< wxT("</h3>")
138 << wxT("<p>") << XO("A bass effect plugin designed to deliver punchy, clear low-end sound.") << wxT(" ")
139 << wxT("<h3>") << wxT("LANDR FX Acoustic:")<< wxT("</h3>")
140 << wxT("<p>") << XO("A plugin for acoustic sound perfection, enhancing warmth and clarity.") << wxT(" ")
141 << wxT("<h3>") << wxT("Pristine Voice")<< wxT("</h3>")
142 << wxT("<p>") << XO("An amazing voice enhancement plugin for crystal-clear, professional vocal effects.") << wxT(" ")
143 << wxT("<h3>") << wxT("Remix Source Separation")<< wxT("</h3>")
144 << wxT("<p>") << XO("A real-time stem separation tool to isolate vocals, drums, and instruments.") << wxT(" ")
145 << wxT("<h3>") << wxT("Recommended effects plugins for Audacity")<< wxT("</h3>")
146 << wxT("<p>") << XO("Check out a variety of plugins by well known developers available on [[%s|MuseHub]].").Format(MuseHubURL)
147
148#endif
149
150 << wxT("<h3>") << wxT("Polyspectral Multiband Compressor")<< wxT("</h3>")
151 << wxT("<p>") << XO("A multiband compressor offering precise control over frequencies.") << wxT(" ")
152 /*i18n-hint: MuseHub is a name of a product, see musehub.com. */
153 << XO("Available on [[%s|MuseHub]].").Format(MuseHubURL) << wxT("</p>");
154
155 return FormatHtmlText(o.GetString());
156}
157}
158
159BEGIN_EVENT_TABLE(WhatsNewDialog, wxDialogWrapper)
162
163WhatsNewDialog::WhatsNewDialog(wxWindow* parent, wxWindowID id)
164 : wxDialogWrapper(parent, id, XO("Welcome to Audacity!"))
165{
166
167 SetSize(FromDIP(wxSize(WindowWidth, WindowHeight)));
168
169#if defined(__WXMSW__)
170 //On Windows UI controls doesn't use same theme preference
171 //as per application, we should use the latter one to get
172 //match with LinkingHtmlWindow's theme
173 SetBackgroundColour(theTheme.Colour(clrMedium));
174#endif
175 SetName();
176 ShuttleGui S( this, eIsCreating );
177 Populate( S );
178 Centre();
179}
180
182
184{
185 auto dialog = &GetAttachedWindows(project)
187 dialog->CenterOnParent();
188 dialog->wxDialogWrapper::Show();
189}
190
192{
193 bool showSplashScreen;
194 gPrefs->Read(wxT("/GUI/ShowSplashScreen"), &showSplashScreen, true );
195
196 FSHelper helper;
197
198 S.StartHorizontalLay(wxEXPAND);
199 {
200 S.SetBorder(20);
201 const auto whatsnew = safenew LinkingHtmlWindow(S.GetParent());
202 whatsnew->SetPage(MakeWhatsNewText());
203 whatsnew->SetBackgroundColour(S.GetParent()->GetBackgroundColour());
204 S
205 .Prop(1)
206#if defined(SHOW_MUSEHUB)
207 .Position(wxEXPAND | wxLEFT | wxTOP | wxBOTTOM)
208#else
209 .Position(wxEXPAND | wxALL)
210#endif
211 .AddWindow(whatsnew);
212
213#if defined(SHOW_MUSEHUB)
214 S.AddSpace(20);
215
216 const auto getplugins = safenew LinkingHtmlWindow(S.GetParent());
217 getplugins->SetPage(MakeGetPluginsText());
218 getplugins->SetBackgroundColour(S.GetParent()->GetBackgroundColour());
219 S
220 .Prop(1)
221 .Position(wxEXPAND | wxTOP | wxRIGHT | wxBOTTOM)
222 .AddWindow(getplugins);
223#endif
224 }
225 S.EndHorizontalLay();
226
227 const auto line = safenew wxWindow(S.GetParent(), wxID_ANY);
228 line->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW));
229 line->SetSize(-1, 1);
230
231 S
232 .Prop(0)
233 .Position(wxEXPAND)
234 .AddWindow(line);
235
236 S.StartHorizontalLay(wxALIGN_CENTRE, 0);
237 {
238 S.SetBorder(10);
239 const auto tutorialsLink = safenew wxHyperlinkCtrl(
240 S.GetParent(),
241 wxID_ANY,
242 _("View tutorials"),
243 "https://support.audacityteam.org/");
244 S
245 .Position(wxTOP | wxBOTTOM)
246 .AddWindow(tutorialsLink);
247
248 S.AddSpace(25);
249
250 const auto forumLink = safenew wxHyperlinkCtrl(
251 S.GetParent(),
252 wxID_ANY,
253 _("Visit our forum"),
254 "https://forum.audacityteam.org/");
255 S
256 .Position(wxTOP | wxBOTTOM)
257 .AddWindow(forumLink);
258 }
259 S.EndHorizontalLay();
260
261 S.Position(wxEXPAND).StartPanel(2);
262 {
263 S.StartHorizontalLay(wxEXPAND);
264 {
265 S.SetBorder(4);
267 .Position(wxALL | wxALIGN_CENTRE)
268 .AddCheckBox( XXO("Don't show this again at start up"), !showSplashScreen);
269
270 S.AddSpace(1,1,1);
271
272 S
273 .Id(wxID_OK)
274 .AddButton(XXO("OK"), wxALL, true);
275 }
276 S.EndHorizontalLay();
277 }
278 S.EndPanel();
279}
280
281void WhatsNewDialog::OnOK(wxCommandEvent& evt)
282{
283 gPrefs->Write(wxT("/GUI/ShowSplashScreen"), !mDontShowAgain->IsChecked() );
284 gPrefs->Flush();
286}
wxT("CloseDown"))
END_EVENT_TABLE()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
wxString FormatHtmlText(const wxString &Text)
Definition: HelpText.cpp:258
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
AUDACITY_DLL_API AttachedWindows & GetAttachedWindows(AudacityProject &project)
accessors for certain important windows associated with each project
@ eIsCreating
Definition: ShuttleGui.h:37
const auto project
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
AttachedWindows::RegisteredFactory sWhatsNewWindow
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:318
An HtmlWindow that handles linked clicked - usually the link will go to our own local copy of the man...
Definition: HelpSystem.h:126
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
wxColour & Colour(int iIndex)
wxCheckBox * mDontShowAgain
void Populate(ShuttleGui &S)
static void Show(AudacityProject &project)
void OnOK(wxCommandEvent &)
~WhatsNewDialog() override
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
IMPORT_EXPORT_API ExportResult Show(ExportTask exportTask)
STL namespace.
std::unique_ptr< wxMemoryFSHandler > mMemoryFSHandler