mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-01 16:19:43 +02:00
Break various dependency cycles
This commit is contained in:
commit
7677638ded
@ -39,6 +39,7 @@ hold information about one contributor to Audacity.
|
||||
#include <wx/intl.h>
|
||||
|
||||
#include "FileNames.h"
|
||||
#include "HelpText.h"
|
||||
#include "ShuttleGui.h"
|
||||
#include "widgets/LinkingHtmlWindow.h"
|
||||
|
||||
@ -69,39 +70,6 @@ hold information about one contributor to Audacity.
|
||||
|
||||
extern wxString FormatHtmlText( const wxString & Text );
|
||||
|
||||
// Function to give the xtra arguments to put on the version check string.
|
||||
const wxString VerCheckArgs(){
|
||||
wxString result = wxString("from_ver=") + AUDACITY_VERSION_STRING;
|
||||
#ifdef REV_LONG
|
||||
result += wxString("&CommitId=")+wxString(REV_LONG).Left(6);
|
||||
#endif
|
||||
result += wxString("&Time=") + wxString( __DATE__ ) + wxString( __TIME__ );
|
||||
result.Replace(" ","");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Url with Version check args attached.
|
||||
const wxString VerCheckUrl(){
|
||||
//The version we intend to use for live Audacity.
|
||||
#define VER_CHECK_URL "https://www.audacityteam.org/download/?"
|
||||
//For testing of our scriptlet.
|
||||
//#define VER_CHECK_URL "http://www.audacityteam.org/slug/?"
|
||||
//For testing locally
|
||||
//#define VER_CHECK_URL "http://localhost:63342/WorkingDocs/demos/download.html?"
|
||||
|
||||
return wxString( wxT(VER_CHECK_URL)) +VerCheckArgs();
|
||||
}
|
||||
|
||||
// Text of htperlink to check versions.
|
||||
const wxString VerCheckHtml(){
|
||||
|
||||
wxString result = "<center>[[";
|
||||
result += VerCheckUrl() + "|" + _("Check Online");
|
||||
result += "]]</center>\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void AboutDialog::CreateCreditsList()
|
||||
{
|
||||
// The Audacity Team: developers and support
|
||||
|
@ -14,10 +14,6 @@
|
||||
#include <vector>
|
||||
#include "widgets/wxPanelWrapper.h" // to inherit
|
||||
|
||||
extern const wxString VerCheckArgs();
|
||||
extern const wxString VerCheckUrl();
|
||||
extern const wxString VerCheckHtml();
|
||||
|
||||
class wxStaticBitmap;
|
||||
|
||||
class ShuttleGui;
|
||||
|
@ -98,6 +98,7 @@ It handles initialization and termination by subclassing wxApp.
|
||||
#include "ondemand/ODManager.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
#include "prefs/DirectoriesPrefs.h"
|
||||
#include "prefs/GUIPrefs.h"
|
||||
#include "tracks/ui/Scrubbing.h"
|
||||
#include "widgets/FileHistory.h"
|
||||
|
||||
@ -263,6 +264,191 @@ static void wxOnAssert(const wxChar *fileName, int lineNumber, const wxChar *msg
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
void PopulatePreferences()
|
||||
{
|
||||
bool resetPrefs = false;
|
||||
wxString langCode = gPrefs->Read(wxT("/Locale/Language"), wxEmptyString);
|
||||
bool writeLang = false;
|
||||
|
||||
const wxFileName fn(
|
||||
FileNames::ResourcesDir(),
|
||||
wxT("FirstTime.ini"));
|
||||
if (fn.FileExists()) // it will exist if the (win) installer put it there
|
||||
{
|
||||
const wxString fullPath{fn.GetFullPath()};
|
||||
|
||||
wxFileConfig ini(wxEmptyString,
|
||||
wxEmptyString,
|
||||
fullPath,
|
||||
wxEmptyString,
|
||||
wxCONFIG_USE_LOCAL_FILE);
|
||||
|
||||
wxString lang;
|
||||
if (ini.Read(wxT("/FromInno/Language"), &lang))
|
||||
{
|
||||
// Only change "langCode" if the language was actually specified in the ini file.
|
||||
langCode = lang;
|
||||
writeLang = true;
|
||||
|
||||
// Inno Setup doesn't allow special characters in the Name values, so "0" is used
|
||||
// to represent the "@" character.
|
||||
langCode.Replace(wxT("0"), wxT("@"));
|
||||
}
|
||||
|
||||
ini.Read(wxT("/FromInno/ResetPrefs"), &resetPrefs, false);
|
||||
|
||||
bool gone = wxRemoveFile(fullPath); // remove FirstTime.ini
|
||||
if (!gone)
|
||||
{
|
||||
AudacityMessageBox(wxString::Format(_("Failed to remove %s"), fullPath), _("Failed!"));
|
||||
}
|
||||
}
|
||||
|
||||
langCode = GUIPrefs::InitLang( langCode );
|
||||
|
||||
// User requested that the preferences be completely reset
|
||||
if (resetPrefs)
|
||||
{
|
||||
// pop up a dialogue
|
||||
wxString prompt = _("Reset Preferences?\n\nThis is a one-time question, after an 'install' where you asked to have the Preferences reset.");
|
||||
int action = AudacityMessageBox(prompt, _("Reset Audacity Preferences"),
|
||||
wxYES_NO, NULL);
|
||||
if (action == wxYES) // reset
|
||||
{
|
||||
gPrefs->DeleteAll();
|
||||
writeLang = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the specified language
|
||||
if (writeLang)
|
||||
{
|
||||
gPrefs->Write(wxT("/Locale/Language"), langCode);
|
||||
}
|
||||
|
||||
// In AUdacity 2.1.0 support for the legacy 1.2.x preferences (depreciated since Audacity
|
||||
// 1.3.1) is dropped. As a result we can drop the import flag
|
||||
// first time this version of Audacity is run we try to migrate
|
||||
// old preferences.
|
||||
bool newPrefsInitialized = false;
|
||||
gPrefs->Read(wxT("/NewPrefsInitialized"), &newPrefsInitialized, false);
|
||||
if (newPrefsInitialized) {
|
||||
gPrefs->DeleteEntry(wxT("/NewPrefsInitialized"), true); // take group as well if empty
|
||||
}
|
||||
|
||||
// record the Prefs version for future checking (this has not been used for a very
|
||||
// long time).
|
||||
gPrefs->Write(wxT("/PrefsVersion"), wxString(wxT(AUDACITY_PREFS_VERSION_STRING)));
|
||||
|
||||
// Check if some prefs updates need to happen based on audacity version.
|
||||
// Unfortunately we can't use the PrefsVersion prefs key because that resets things.
|
||||
// In the future we may want to integrate that better.
|
||||
// these are done on a case-by-case basis for now so they must be backwards compatible
|
||||
// (meaning the changes won't mess audacity up if the user goes back to an earlier version)
|
||||
int vMajor = gPrefs->Read(wxT("/Version/Major"), (long) 0);
|
||||
int vMinor = gPrefs->Read(wxT("/Version/Minor"), (long) 0);
|
||||
int vMicro = gPrefs->Read(wxT("/Version/Micro"), (long) 0);
|
||||
|
||||
gPrefs->SetVersionKeysInit(vMajor, vMinor, vMicro); // make a note of these initial values
|
||||
// for use by ToolManager::ReadConfig()
|
||||
|
||||
// These integer version keys were introduced april 4 2011 for 1.3.13
|
||||
// The device toolbar needs to be enabled due to removal of source selection features in
|
||||
// the mixer toolbar.
|
||||
if ((vMajor < 1) ||
|
||||
(vMajor == 1 && vMinor < 3) ||
|
||||
(vMajor == 1 && vMinor == 3 && vMicro < 13)) {
|
||||
|
||||
|
||||
// Do a full reset of the Device Toolbar to get it on the screen.
|
||||
if (gPrefs->Exists(wxT("/GUI/ToolBars/Device")))
|
||||
gPrefs->DeleteGroup(wxT("/GUI/ToolBars/Device"));
|
||||
|
||||
// We keep the mixer toolbar prefs (shown/not shown)
|
||||
// the width of the mixer toolbar may have shrunk, the prefs will keep the larger value
|
||||
// if the user had a device that had more than one source.
|
||||
if (gPrefs->Exists(wxT("/GUI/ToolBars/Mixer"))) {
|
||||
// Use the default width
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/Mixer/W"), -1);
|
||||
}
|
||||
}
|
||||
|
||||
// In 2.1.0, the Meter toolbar was split and lengthened, but strange arrangements happen
|
||||
// if upgrading due to the extra length. So, if a user is upgrading, use the pre-2.1.0
|
||||
// lengths, but still use the NEW split versions.
|
||||
if (gPrefs->Exists(wxT("/GUI/ToolBars/Meter")) &&
|
||||
!gPrefs->Exists(wxT("/GUI/ToolBars/CombinedMeter"))) {
|
||||
|
||||
// Read in all of the existing values
|
||||
long dock, order, show, x, y, w, h;
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Dock"), &dock, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Order"), &order, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Show"), &show, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/X"), &x, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Y"), &y, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/W"), &w, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/H"), &h, -1);
|
||||
|
||||
// "Order" must be adjusted since we're inserting two NEW toolbars
|
||||
if (dock > 0) {
|
||||
wxString oldPath = gPrefs->GetPath();
|
||||
gPrefs->SetPath(wxT("/GUI/ToolBars"));
|
||||
|
||||
wxString bar;
|
||||
long ndx = 0;
|
||||
bool cont = gPrefs->GetFirstGroup(bar, ndx);
|
||||
while (cont) {
|
||||
long o;
|
||||
if (gPrefs->Read(bar + wxT("/Order"), &o) && o >= order) {
|
||||
gPrefs->Write(bar + wxT("/Order"), o + 2);
|
||||
}
|
||||
cont = gPrefs->GetNextGroup(bar, ndx);
|
||||
}
|
||||
gPrefs->SetPath(oldPath);
|
||||
|
||||
// And override the height
|
||||
h = 27;
|
||||
}
|
||||
|
||||
// Write the split meter bar values
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Dock"), dock);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Order"), order);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Show"), show);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/X"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Y"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/W"), w);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/H"), h);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Dock"), dock);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Order"), order + 1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Show"), show);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/X"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Y"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/W"), w);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/H"), h);
|
||||
|
||||
// And hide the old combined meter bar
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/Meter/Dock"), -1);
|
||||
}
|
||||
|
||||
// Upgrading pre 2.2.0 configs we assume extended set of defaults.
|
||||
if ((0<vMajor && vMajor < 2) ||
|
||||
(vMajor == 2 && vMinor < 2))
|
||||
{
|
||||
gPrefs->Write(wxT("/GUI/Shortcuts/FullDefaults"),1);
|
||||
}
|
||||
|
||||
// write out the version numbers to the prefs file for future checking
|
||||
gPrefs->Write(wxT("/Version/Major"), AUDACITY_VERSION);
|
||||
gPrefs->Write(wxT("/Version/Minor"), AUDACITY_RELEASE);
|
||||
gPrefs->Write(wxT("/Version/Micro"), AUDACITY_REVISION);
|
||||
|
||||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool gInited = false;
|
||||
static bool gIsQuitting = false;
|
||||
|
||||
@ -1154,6 +1340,7 @@ bool AudacityApp::OnInit()
|
||||
|
||||
// Initialize preferences and language
|
||||
InitPreferences();
|
||||
PopulatePreferences();
|
||||
|
||||
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) && !defined(__CYGWIN__)
|
||||
this->AssociateFileTypes();
|
||||
|
@ -461,6 +461,7 @@ TimeTrack and AudioIOListener and whether the playback is looped.
|
||||
|
||||
#include "effects/EffectManager.h"
|
||||
#include "prefs/QualityPrefs.h"
|
||||
#include "prefs/RecordingPrefs.h"
|
||||
#include "toolbars/ControlToolBar.h"
|
||||
#include "widgets/Meter.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
|
@ -84,15 +84,6 @@ class AudioIOListener;
|
||||
#define MAX_MIDI_BUFFER_SIZE 5000
|
||||
#define DEFAULT_SYNTH_LATENCY 5
|
||||
|
||||
#define DEFAULT_LATENCY_DURATION 100.0
|
||||
#define DEFAULT_LATENCY_CORRECTION -130.0
|
||||
|
||||
#define AUDIO_PRE_ROLL_KEY (wxT("/AudioIO/PreRoll"))
|
||||
#define DEFAULT_PRE_ROLL_SECONDS 5.0
|
||||
|
||||
#define AUDIO_ROLL_CROSSFADE_KEY (wxT("/AudioIO/Crossfade"))
|
||||
#define DEFAULT_ROLL_CROSSFADE_MS 10.0
|
||||
|
||||
#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
|
||||
#define AILA_DEF_TARGET_PEAK 92
|
||||
#define AILA_DEF_DELTA_PEAK 2
|
||||
|
@ -37,6 +37,9 @@ and get deterministic behaviour.
|
||||
|
||||
#include "Dither.h"
|
||||
|
||||
#include "Internat.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
// Erik de Castro Lopo's header file that
|
||||
// makes sure that we have lrint and lrintf
|
||||
// (Note: this file should be included first)
|
||||
@ -393,3 +396,50 @@ inline float Dither::ShapedDither(float sample)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const EnumValueSymbol choicesDither[] = {
|
||||
{ XO("None") },
|
||||
{ XO("Rectangle") },
|
||||
{ XO("Triangle") },
|
||||
{ XO("Shaped") },
|
||||
};
|
||||
static const size_t nChoicesDither = WXSIZEOF( choicesDither );
|
||||
static const int intChoicesDither[] = {
|
||||
(int) DitherType::none,
|
||||
(int) DitherType::rectangle,
|
||||
(int) DitherType::triangle,
|
||||
(int) DitherType::shaped,
|
||||
};
|
||||
static_assert(
|
||||
nChoicesDither == WXSIZEOF( intChoicesDither ),
|
||||
"size mismatch"
|
||||
);
|
||||
|
||||
static const size_t defaultFastDither = 0; // none
|
||||
|
||||
EnumSetting Dither::FastSetting{
|
||||
wxT("Quality/DitherAlgorithmChoice"),
|
||||
choicesDither, nChoicesDither, defaultFastDither,
|
||||
intChoicesDither,
|
||||
wxT("Quality/DitherAlgorithm")
|
||||
};
|
||||
|
||||
static const size_t defaultBestDither = 3; // shaped
|
||||
|
||||
EnumSetting Dither::BestSetting{
|
||||
wxT("Quality/HQDitherAlgorithmChoice"),
|
||||
choicesDither, nChoicesDither, defaultBestDither,
|
||||
|
||||
intChoicesDither,
|
||||
wxT("Quality/HQDitherAlgorithm")
|
||||
};
|
||||
|
||||
DitherType Dither::FastDitherChoice()
|
||||
{
|
||||
return (DitherType) FastSetting.ReadInt();
|
||||
}
|
||||
|
||||
DitherType Dither::BestDitherChoice()
|
||||
{
|
||||
return (DitherType) BestSetting.ReadInt();
|
||||
}
|
||||
|
@ -10,7 +10,9 @@
|
||||
#ifndef __AUDACITY_DITHER_H__
|
||||
#define __AUDACITY_DITHER_H__
|
||||
|
||||
#include "SampleFormat.h"
|
||||
#include "audacity/Types.h" // for samplePtr
|
||||
|
||||
class EnumSetting;
|
||||
|
||||
|
||||
/// These ditherers are currently available:
|
||||
@ -20,6 +22,11 @@ enum DitherType : unsigned {
|
||||
class Dither
|
||||
{
|
||||
public:
|
||||
static DitherType FastDitherChoice();
|
||||
static DitherType BestDitherChoice();
|
||||
|
||||
static EnumSetting FastSetting, BestSetting;
|
||||
|
||||
/// Default constructor
|
||||
Dither();
|
||||
|
||||
|
@ -581,3 +581,43 @@ void FileNames::FindFilesInPathList(const wxString & pattern,
|
||||
wxDir::GetAllFiles(ff.GetPath(), &results, ff.GetFullName(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
//
|
||||
// On Windows, wxString::mb_str() can return a NULL pointer if the
|
||||
// conversion to multi-byte fails. So, based on direction intent,
|
||||
// returns a pointer to an empty string or prompts for a NEW name.
|
||||
//
|
||||
char *FileNames::VerifyFilename(const wxString &s, bool input)
|
||||
{
|
||||
static wxCharBuffer buf;
|
||||
wxString name = s;
|
||||
|
||||
if (input) {
|
||||
if ((char *) (const char *)name.mb_str() == NULL) {
|
||||
name = wxEmptyString;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wxFileName ff(name);
|
||||
wxString ext;
|
||||
while ((char *) (const char *)name.mb_str() == NULL) {
|
||||
AudacityMessageBox(_("The specified filename could not be converted due to Unicode character use."));
|
||||
|
||||
ext = ff.GetExt();
|
||||
name = FileNames::SelectFile(FileNames::Operation::_None,
|
||||
_("Specify New Filename:"),
|
||||
wxEmptyString,
|
||||
name,
|
||||
ext,
|
||||
wxT("*.") + ext,
|
||||
wxFD_SAVE | wxRESIZE_BORDER,
|
||||
wxGetTopLevelParent(NULL));
|
||||
}
|
||||
}
|
||||
|
||||
mFilename = name.mb_str();
|
||||
|
||||
return (char *) (const char *) mFilename;
|
||||
}
|
||||
#endif
|
||||
|
@ -145,6 +145,12 @@ public:
|
||||
FilePaths &results,
|
||||
int flags = wxDIR_FILES);
|
||||
|
||||
/** \brief Protect against Unicode to multi-byte conversion failures
|
||||
* on Windows */
|
||||
#if defined(__WXMSW__)
|
||||
static char *VerifyFilename(const wxString &s, bool input = true);
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Private constructors: No one is ever going to instantiate it.
|
||||
//
|
||||
@ -152,4 +158,22 @@ private:
|
||||
~FileNames(){;};
|
||||
};
|
||||
|
||||
// Use this macro to wrap all filenames and pathnames that get
|
||||
// passed directly to a system call, like opening a file, creating
|
||||
// a directory, checking to see that a file exists, etc...
|
||||
#if defined(__WXMSW__)
|
||||
// Note, on Windows we don't define an OSFILENAME() to prevent accidental use.
|
||||
// See VerifyFilename() for an explanation.
|
||||
#define OSINPUT(X) FileNames::VerifyFilename(X, true)
|
||||
#define OSOUTPUT(X) FileNames::VerifyFilename(X, false)
|
||||
#elif defined(__WXMAC__)
|
||||
#define OSFILENAME(X) ((char *) (const char *)(X).fn_str())
|
||||
#define OSINPUT(X) OSFILENAME(X)
|
||||
#define OSOUTPUT(X) OSFILENAME(X)
|
||||
#else
|
||||
#define OSFILENAME(X) ((char *) (const char *)(X).mb_str())
|
||||
#define OSINPUT(X) OSFILENAME(X)
|
||||
#define OSOUTPUT(X) OSFILENAME(X)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <wx/intl.h>
|
||||
|
||||
#include "FileNames.h"
|
||||
#include "AboutDialog.h"
|
||||
#include "Internat.h"
|
||||
#include "AllThemeResources.h"
|
||||
|
||||
|
||||
@ -328,3 +328,35 @@ wxString FormatHtmlText( const wxString & Text ){
|
||||
WrapText( LinkExpand( Text ))+
|
||||
wxT("</html>");
|
||||
}
|
||||
|
||||
// Function to give the extra arguments to put on the version check string.
|
||||
const wxString VerCheckArgs(){
|
||||
wxString result = wxString("from_ver=") + AUDACITY_VERSION_STRING;
|
||||
#ifdef REV_LONG
|
||||
result += wxString("&CommitId=")+wxString(REV_LONG).Left(6);
|
||||
#endif
|
||||
result += wxString("&Time=") + wxString( __DATE__ ) + wxString( __TIME__ );
|
||||
result.Replace(" ","");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Text of hyperlink to check versions.
|
||||
const wxString VerCheckHtml(){
|
||||
|
||||
wxString result = "<center>[[";
|
||||
result += VerCheckUrl() + "|" + _("Check Online");
|
||||
result += "]]</center>\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
// Url with Version check args attached.
|
||||
const wxString VerCheckUrl(){
|
||||
//The version we intend to use for live Audacity.
|
||||
#define VER_CHECK_URL "https://www.audacityteam.org/download/?"
|
||||
//For testing of our scriptlet.
|
||||
//#define VER_CHECK_URL "http://www.audacityteam.org/slug/?"
|
||||
//For testing locally
|
||||
//#define VER_CHECK_URL "http://localhost:63342/WorkingDocs/demos/download.html?"
|
||||
|
||||
return wxString( wxT(VER_CHECK_URL)) +VerCheckArgs();
|
||||
}
|
||||
|
@ -16,4 +16,8 @@ class wxString;
|
||||
wxString HelpText( const wxString & Key );
|
||||
wxString TitleText( const wxString & Key );
|
||||
|
||||
extern const wxString VerCheckArgs();
|
||||
extern const wxString VerCheckUrl();
|
||||
extern const wxString VerCheckHtml();
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@ and on Mac OS X for the filesystem.
|
||||
#include "Internat.h"
|
||||
|
||||
#include "Experimental.h"
|
||||
#include "MemoryX.h"
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/intl.h>
|
||||
@ -31,8 +32,6 @@ and on Mac OS X for the filesystem.
|
||||
#include <locale.h>
|
||||
#include <math.h> // for pow()
|
||||
|
||||
#include "FileNames.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
#include "../include/audacity/ComponentInterface.h"
|
||||
|
||||
// in order for the static member variables to exist, they must appear here
|
||||
@ -226,46 +225,6 @@ wxString Internat::FormatSize(double size)
|
||||
return sizeStr;
|
||||
}
|
||||
|
||||
#if defined(__WXMSW__)
|
||||
//
|
||||
// On Windows, wxString::mb_str() can return a NULL pointer if the
|
||||
// conversion to multi-byte fails. So, based on direction intent,
|
||||
// returns a pointer to an empty string or prompts for a NEW name.
|
||||
//
|
||||
char *Internat::VerifyFilename(const wxString &s, bool input)
|
||||
{
|
||||
static wxCharBuffer buf;
|
||||
wxString name = s;
|
||||
|
||||
if (input) {
|
||||
if ((char *) (const char *)name.mb_str() == NULL) {
|
||||
name = wxEmptyString;
|
||||
}
|
||||
}
|
||||
else {
|
||||
wxFileName ff(name);
|
||||
wxString ext;
|
||||
while ((char *) (const char *)name.mb_str() == NULL) {
|
||||
AudacityMessageBox(_("The specified filename could not be converted due to Unicode character use."));
|
||||
|
||||
ext = ff.GetExt();
|
||||
name = FileNames::SelectFile(FileNames::Operation::_None,
|
||||
_("Specify New Filename:"),
|
||||
wxEmptyString,
|
||||
name,
|
||||
ext,
|
||||
wxT("*.") + ext,
|
||||
wxFD_SAVE | wxRESIZE_BORDER,
|
||||
wxGetTopLevelParent(NULL));
|
||||
}
|
||||
}
|
||||
|
||||
mFilename = name.mb_str();
|
||||
|
||||
return (char *) (const char *) mFilename;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Internat::SanitiseFilename(wxString &name, const wxString &sub)
|
||||
{
|
||||
bool result = false;
|
||||
|
@ -120,12 +120,6 @@ public:
|
||||
static wxString FormatSize(wxLongLong size);
|
||||
static wxString FormatSize(double size);
|
||||
|
||||
/** \brief Protect against Unicode to multi-byte conversion failures
|
||||
* on Windows */
|
||||
#if defined(__WXMSW__)
|
||||
static char *VerifyFilename(const wxString &s, bool input = true);
|
||||
#endif
|
||||
|
||||
/** \brief Check a proposed file name string for illegal characters and
|
||||
* remove them
|
||||
* return true iff name is "visibly" changed (not necessarily equivalent to
|
||||
@ -156,24 +150,6 @@ private:
|
||||
|
||||
#define _NoAcc(X) Internat::StripAccelerators(_(X))
|
||||
|
||||
// Use this macro to wrap all filenames and pathnames that get
|
||||
// passed directly to a system call, like opening a file, creating
|
||||
// a directory, checking to see that a file exists, etc...
|
||||
#if defined(__WXMSW__)
|
||||
// Note, on Windows we don't define an OSFILENAME() to prevent accidental use.
|
||||
// See VerifyFilename() for an explanation.
|
||||
#define OSINPUT(X) Internat::VerifyFilename(X, true)
|
||||
#define OSOUTPUT(X) Internat::VerifyFilename(X, false)
|
||||
#elif defined(__WXMAC__)
|
||||
#define OSFILENAME(X) ((char *) (const char *)(X).fn_str())
|
||||
#define OSINPUT(X) OSFILENAME(X)
|
||||
#define OSOUTPUT(X) OSFILENAME(X)
|
||||
#else
|
||||
#define OSFILENAME(X) ((char *) (const char *)(X).mb_str())
|
||||
#define OSINPUT(X) OSFILENAME(X)
|
||||
#define OSOUTPUT(X) OSFILENAME(X)
|
||||
#endif
|
||||
|
||||
// Convert C strings to wxString
|
||||
#define UTF8CTOWX(X) wxString((X), wxConvUTF8)
|
||||
#define LAT1CTOWX(X) wxString((X), wxConvISO8859_1)
|
||||
|
182
src/Prefs.cpp
182
src/Prefs.cpp
@ -61,11 +61,9 @@
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
#include "FileNames.h"
|
||||
#include "MemoryX.h"
|
||||
#include "Languages.h"
|
||||
|
||||
#include "prefs/GUIPrefs.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
|
||||
std::unique_ptr<AudacityPrefs> ugPrefs {};
|
||||
|
||||
AudacityPrefs *gPrefs = NULL;
|
||||
@ -177,184 +175,6 @@ void InitPreferences()
|
||||
gPrefs = ugPrefs.get();
|
||||
|
||||
wxConfigBase::Set(gPrefs);
|
||||
|
||||
bool resetPrefs = false;
|
||||
wxString langCode = gPrefs->Read(wxT("/Locale/Language"), wxEmptyString);
|
||||
bool writeLang = false;
|
||||
|
||||
const wxFileName fn(
|
||||
FileNames::ResourcesDir(),
|
||||
wxT("FirstTime.ini"));
|
||||
if (fn.FileExists()) // it will exist if the (win) installer put it there
|
||||
{
|
||||
const wxString fullPath{fn.GetFullPath()};
|
||||
|
||||
wxFileConfig ini(wxEmptyString,
|
||||
wxEmptyString,
|
||||
fullPath,
|
||||
wxEmptyString,
|
||||
wxCONFIG_USE_LOCAL_FILE);
|
||||
|
||||
wxString lang;
|
||||
if (ini.Read(wxT("/FromInno/Language"), &lang))
|
||||
{
|
||||
// Only change "langCode" if the language was actually specified in the ini file.
|
||||
langCode = lang;
|
||||
writeLang = true;
|
||||
|
||||
// Inno Setup doesn't allow special characters in the Name values, so "0" is used
|
||||
// to represent the "@" character.
|
||||
langCode.Replace(wxT("0"), wxT("@"));
|
||||
}
|
||||
|
||||
ini.Read(wxT("/FromInno/ResetPrefs"), &resetPrefs, false);
|
||||
|
||||
bool gone = wxRemoveFile(fullPath); // remove FirstTime.ini
|
||||
if (!gone)
|
||||
{
|
||||
AudacityMessageBox(wxString::Format(_("Failed to remove %s"), fullPath), _("Failed!"));
|
||||
}
|
||||
}
|
||||
|
||||
langCode = GUIPrefs::InitLang( langCode );
|
||||
|
||||
// User requested that the preferences be completely reset
|
||||
if (resetPrefs)
|
||||
{
|
||||
// pop up a dialogue
|
||||
wxString prompt = _("Reset Preferences?\n\nThis is a one-time question, after an 'install' where you asked to have the Preferences reset.");
|
||||
int action = AudacityMessageBox(prompt, _("Reset Audacity Preferences"),
|
||||
wxYES_NO, NULL);
|
||||
if (action == wxYES) // reset
|
||||
{
|
||||
gPrefs->DeleteAll();
|
||||
writeLang = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the specified language
|
||||
if (writeLang)
|
||||
{
|
||||
gPrefs->Write(wxT("/Locale/Language"), langCode);
|
||||
}
|
||||
|
||||
// In AUdacity 2.1.0 support for the legacy 1.2.x preferences (depreciated since Audacity
|
||||
// 1.3.1) is dropped. As a result we can drop the import flag
|
||||
// first time this version of Audacity is run we try to migrate
|
||||
// old preferences.
|
||||
bool newPrefsInitialized = false;
|
||||
gPrefs->Read(wxT("/NewPrefsInitialized"), &newPrefsInitialized, false);
|
||||
if (newPrefsInitialized) {
|
||||
gPrefs->DeleteEntry(wxT("/NewPrefsInitialized"), true); // take group as well if empty
|
||||
}
|
||||
|
||||
// record the Prefs version for future checking (this has not been used for a very
|
||||
// long time).
|
||||
gPrefs->Write(wxT("/PrefsVersion"), wxString(wxT(AUDACITY_PREFS_VERSION_STRING)));
|
||||
|
||||
// Check if some prefs updates need to happen based on audacity version.
|
||||
// Unfortunately we can't use the PrefsVersion prefs key because that resets things.
|
||||
// In the future we may want to integrate that better.
|
||||
// these are done on a case-by-case basis for now so they must be backwards compatible
|
||||
// (meaning the changes won't mess audacity up if the user goes back to an earlier version)
|
||||
int vMajor = gPrefs->Read(wxT("/Version/Major"), (long) 0);
|
||||
int vMinor = gPrefs->Read(wxT("/Version/Minor"), (long) 0);
|
||||
int vMicro = gPrefs->Read(wxT("/Version/Micro"), (long) 0);
|
||||
|
||||
gPrefs->SetVersionKeysInit(vMajor, vMinor, vMicro); // make a note of these initial values
|
||||
// for use by ToolManager::ReadConfig()
|
||||
|
||||
// These integer version keys were introduced april 4 2011 for 1.3.13
|
||||
// The device toolbar needs to be enabled due to removal of source selection features in
|
||||
// the mixer toolbar.
|
||||
if ((vMajor < 1) ||
|
||||
(vMajor == 1 && vMinor < 3) ||
|
||||
(vMajor == 1 && vMinor == 3 && vMicro < 13)) {
|
||||
|
||||
|
||||
// Do a full reset of the Device Toolbar to get it on the screen.
|
||||
if (gPrefs->Exists(wxT("/GUI/ToolBars/Device")))
|
||||
gPrefs->DeleteGroup(wxT("/GUI/ToolBars/Device"));
|
||||
|
||||
// We keep the mixer toolbar prefs (shown/not shown)
|
||||
// the width of the mixer toolbar may have shrunk, the prefs will keep the larger value
|
||||
// if the user had a device that had more than one source.
|
||||
if (gPrefs->Exists(wxT("/GUI/ToolBars/Mixer"))) {
|
||||
// Use the default width
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/Mixer/W"), -1);
|
||||
}
|
||||
}
|
||||
|
||||
// In 2.1.0, the Meter toolbar was split and lengthened, but strange arrangements happen
|
||||
// if upgrading due to the extra length. So, if a user is upgrading, use the pre-2.1.0
|
||||
// lengths, but still use the NEW split versions.
|
||||
if (gPrefs->Exists(wxT("/GUI/ToolBars/Meter")) &&
|
||||
!gPrefs->Exists(wxT("/GUI/ToolBars/CombinedMeter"))) {
|
||||
|
||||
// Read in all of the existing values
|
||||
long dock, order, show, x, y, w, h;
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Dock"), &dock, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Order"), &order, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Show"), &show, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/X"), &x, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/Y"), &y, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/W"), &w, -1);
|
||||
gPrefs->Read(wxT("/GUI/ToolBars/Meter/H"), &h, -1);
|
||||
|
||||
// "Order" must be adjusted since we're inserting two NEW toolbars
|
||||
if (dock > 0) {
|
||||
wxString oldPath = gPrefs->GetPath();
|
||||
gPrefs->SetPath(wxT("/GUI/ToolBars"));
|
||||
|
||||
wxString bar;
|
||||
long ndx = 0;
|
||||
bool cont = gPrefs->GetFirstGroup(bar, ndx);
|
||||
while (cont) {
|
||||
long o;
|
||||
if (gPrefs->Read(bar + wxT("/Order"), &o) && o >= order) {
|
||||
gPrefs->Write(bar + wxT("/Order"), o + 2);
|
||||
}
|
||||
cont = gPrefs->GetNextGroup(bar, ndx);
|
||||
}
|
||||
gPrefs->SetPath(oldPath);
|
||||
|
||||
// And override the height
|
||||
h = 27;
|
||||
}
|
||||
|
||||
// Write the split meter bar values
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Dock"), dock);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Order"), order);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Show"), show);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/X"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/Y"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/W"), w);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/RecordMeter/H"), h);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Dock"), dock);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Order"), order + 1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Show"), show);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/X"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/Y"), -1);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/W"), w);
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/PlayMeter/H"), h);
|
||||
|
||||
// And hide the old combined meter bar
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/Meter/Dock"), -1);
|
||||
}
|
||||
|
||||
// Upgrading pre 2.2.0 configs we assume extended set of defaults.
|
||||
if ((0<vMajor && vMajor < 2) ||
|
||||
(vMajor == 2 && vMinor < 2))
|
||||
{
|
||||
gPrefs->Write(wxT("/GUI/Shortcuts/FullDefaults"),1);
|
||||
}
|
||||
|
||||
// write out the version numbers to the prefs file for future checking
|
||||
gPrefs->Write(wxT("/Version/Major"), AUDACITY_VERSION);
|
||||
gPrefs->Write(wxT("/Version/Minor"), AUDACITY_RELEASE);
|
||||
gPrefs->Write(wxT("/Version/Micro"), AUDACITY_REVISION);
|
||||
|
||||
gPrefs->Flush();
|
||||
}
|
||||
|
||||
void FinishPreferences()
|
||||
|
@ -165,6 +165,7 @@ scroll information. It also has some status flags.
|
||||
#include "commands/CommandTargets.h"
|
||||
#include "commands/CommandType.h"
|
||||
|
||||
#include "prefs/ThemePrefs.h"
|
||||
#include "prefs/QualityPrefs.h"
|
||||
#include "prefs/TracksPrefs.h"
|
||||
|
||||
@ -1425,6 +1426,8 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id,
|
||||
&AudacityProject::OnCapture,
|
||||
this);
|
||||
|
||||
wxTheApp->Bind(EVT_THEME_CHANGE, &AudacityProject::OnThemeChange, this);
|
||||
|
||||
#ifdef EXPERIMENTAL_DA2
|
||||
ClearBackground();// For wxGTK.
|
||||
#endif
|
||||
@ -1473,12 +1476,6 @@ void AudacityProject::UpdatePrefsVariables()
|
||||
gPrefs->Read(wxT("/AudioFiles/NormalizeOnLoad"),&mNormalizeOnLoad, false);
|
||||
gPrefs->Read(wxT("/GUI/AutoScroll"), &mViewInfo.bUpdateTrackIndicator, true);
|
||||
gPrefs->Read(wxT("/GUI/EmptyCanBeDirty"), &mEmptyCanBeDirty, true );
|
||||
// DA: Default for DA is manual from internet.
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
gPrefs->Read(wxT("/GUI/Help"), &mHelpPref, wxT("FromInternet") );
|
||||
#else
|
||||
gPrefs->Read(wxT("/GUI/Help"), &mHelpPref, wxT("Local") );
|
||||
#endif
|
||||
gPrefs->Read(wxT("/GUI/ShowSplashScreen"), &mShowSplashScreen, true);
|
||||
gPrefs->Read(wxT("/GUI/Solo"), &mSoloPref, wxT("Simple"));
|
||||
// Update the old default to the NEW default.
|
||||
@ -1572,6 +1569,19 @@ void AudacityProject::OnCapture(wxCommandEvent& evt)
|
||||
mIsCapturing = false;
|
||||
}
|
||||
|
||||
void AudacityProject::OnThemeChange(wxCommandEvent& evt)
|
||||
{
|
||||
evt.Skip();
|
||||
ApplyUpdatedTheme();
|
||||
for( int ii = 0; ii < ToolBarCount; ++ii )
|
||||
{
|
||||
ToolBar *pToolBar = GetToolManager()->GetToolBar(ii);
|
||||
if( pToolBar )
|
||||
pToolBar->ReCreateButtons();
|
||||
}
|
||||
GetRulerPanel()->ReCreateButtons();
|
||||
}
|
||||
|
||||
|
||||
const std::shared_ptr<DirManager> &AudacityProject::GetDirManager()
|
||||
{
|
||||
|
@ -541,6 +541,7 @@ public:
|
||||
private:
|
||||
|
||||
void OnCapture(wxCommandEvent & evt);
|
||||
void OnThemeChange(wxCommandEvent & evt);
|
||||
void InitialState();
|
||||
|
||||
public:
|
||||
@ -647,7 +648,6 @@ private:
|
||||
public:
|
||||
ToolManager *GetToolManager() { return mToolManager.get(); }
|
||||
bool mShowSplashScreen;
|
||||
wxString mHelpPref;
|
||||
wxString mSoloPref;
|
||||
bool mbBusyImporting{ false }; // used to fix bug 584
|
||||
int mBatchMode{ 0 };// 0 means not, >0 means in batch mode.
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
#include "Prefs.h"
|
||||
#include "Dither.h"
|
||||
#include "prefs/QualityPrefs.h"
|
||||
#include "Internat.h"
|
||||
|
||||
static DitherType gLowQualityDither = DitherType::none;
|
||||
static DitherType gHighQualityDither = DitherType::none;
|
||||
@ -53,8 +53,8 @@ static Dither gDitherAlgorithm;
|
||||
void InitDitherers()
|
||||
{
|
||||
// Read dither preferences
|
||||
gLowQualityDither = QualityPrefs::FastDitherChoice();
|
||||
gHighQualityDither = QualityPrefs::BestDitherChoice();
|
||||
gLowQualityDither = Dither::FastDitherChoice();
|
||||
gHighQualityDither = Dither::BestDitherChoice();
|
||||
}
|
||||
|
||||
const wxChar *GetSampleFormatStr(sampleFormat format)
|
||||
|
@ -2124,7 +2124,6 @@ void SetIfCreated( wxStaticText *&Var, wxStaticText * Val )
|
||||
// two files at some later date.
|
||||
#include "../extnpanel-src/GuiWaveTrack.h"
|
||||
#endif
|
||||
#include "./widgets/AttachableScrollBar.h"
|
||||
|
||||
ShuttleGui::ShuttleGui(wxWindow * pParent, teShuttleMode ShuttleMode) :
|
||||
ShuttleGuiBase( pParent, ShuttleMode )
|
||||
@ -2184,6 +2183,8 @@ GuiWaveTrack * ShuttleGui::AddGuiWaveTrack( const wxString & WXUNUSED(Name))
|
||||
#endif
|
||||
}
|
||||
|
||||
//#include "./widgets/AttachableScrollBar.h"
|
||||
#if 0
|
||||
AttachableScrollBar * ShuttleGui::AddAttachableScrollBar( long style )
|
||||
{
|
||||
UseUpId();
|
||||
@ -2203,6 +2204,7 @@ AttachableScrollBar * ShuttleGui::AddAttachableScrollBar( long style )
|
||||
UpdateSizers();
|
||||
return pAttachableScrollBar;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<wxSizer> CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
|
||||
{
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include <wx/defs.h>
|
||||
|
||||
#include "Project.h"
|
||||
#include "WrappedType.h"
|
||||
#include "Prefs.h"
|
||||
|
||||
|
@ -72,13 +72,9 @@ can't be.
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/settings.h>
|
||||
|
||||
#include "Project.h"
|
||||
#include "toolbars/ToolManager.h"
|
||||
#include "AllThemeResources.h" // can remove this later, only needed for 'XPMS_RETIRED'.
|
||||
#include "FileNames.h"
|
||||
#include "Prefs.h"
|
||||
#include "AColor.h"
|
||||
#include "AdornedRulerPanel.h"
|
||||
#include "ImageManipulation.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
|
||||
@ -247,23 +243,6 @@ bool ThemeBase::LoadPreferredTheme()
|
||||
return true;
|
||||
}
|
||||
|
||||
void Theme::ApplyUpdatedImages()
|
||||
{
|
||||
AColor::ReInit();
|
||||
|
||||
for (size_t i = 0; i < gAudacityProjects.size(); i++) {
|
||||
AudacityProject *p = gAudacityProjects[i].get();
|
||||
p->ApplyUpdatedTheme();
|
||||
for( int ii = 0; ii < ToolBarCount; ++ii )
|
||||
{
|
||||
ToolBar *pToolBar = p->GetToolManager()->GetToolBar(ii);
|
||||
if( pToolBar )
|
||||
pToolBar->ReCreateButtons();
|
||||
}
|
||||
p->GetRulerPanel()->ReCreateButtons();
|
||||
}
|
||||
}
|
||||
|
||||
void Theme::RegisterImages()
|
||||
{
|
||||
if( mbInitialised )
|
||||
|
@ -102,7 +102,6 @@ public:
|
||||
|
||||
public:
|
||||
virtual void EnsureInitialised()=0;
|
||||
virtual void ApplyUpdatedImages()=0;
|
||||
void LoadTheme( teThemeType Theme );
|
||||
void RegisterImage( int &iIndex,char const** pXpm, const wxString & Name);
|
||||
void RegisterImage( int &iIndex, const wxImage &Image, const wxString & Name );
|
||||
@ -165,7 +164,6 @@ public:
|
||||
~Theme(void);
|
||||
public:
|
||||
void EnsureInitialised() override;
|
||||
void ApplyUpdatedImages() override;
|
||||
void RegisterImages();
|
||||
void RegisterColours();
|
||||
bool mbInitialised;
|
||||
|
11
src/Track.h
11
src/Track.h
@ -213,12 +213,11 @@ class AUDACITY_DLL_API Track /* not final */
|
||||
|
||||
public:
|
||||
|
||||
enum ChannelType
|
||||
{
|
||||
LeftChannel = 0,
|
||||
RightChannel = 1,
|
||||
MonoChannel = 2
|
||||
};
|
||||
using ChannelType = XMLValueChecker::ChannelType;
|
||||
|
||||
static const auto LeftChannel = XMLValueChecker::LeftChannel;
|
||||
static const auto RightChannel = XMLValueChecker::RightChannel;
|
||||
static const auto MonoChannel = XMLValueChecker::MonoChannel;
|
||||
|
||||
TrackId GetId() const { return mId; }
|
||||
private:
|
||||
|
@ -1,17 +1,23 @@
|
||||
#include "../Audacity.h"
|
||||
#include "../Experimental.h"
|
||||
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
#include "../AboutDialog.h"
|
||||
#include "../AllThemeResources.h"
|
||||
#include "../AudacityLogger.h"
|
||||
#include "../AudioIO.h"
|
||||
#include "../CrashReport.h"
|
||||
#include "../Dependencies.h"
|
||||
#include "../FileNames.h"
|
||||
#include "../HelpText.h"
|
||||
#include "../Menus.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../Project.h"
|
||||
#include "../ShuttleGui.h"
|
||||
#include "../SplashDialog.h"
|
||||
#include "../Theme.h"
|
||||
#include "../commands/CommandContext.h"
|
||||
#include "../commands/CommandManager.h"
|
||||
#include "../widgets/ErrorDialog.h"
|
||||
@ -69,6 +75,203 @@ void ShowDiagnostics(
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Class which makes a dialog for displaying quick fixes to common issues.
|
||||
*
|
||||
* This class originated with the 'Stuck in a mode' problem, where far too many
|
||||
* users get into a mode without realising, and don't know how to get out.
|
||||
* It is a band-aid, and we should do more towards a full and proper solution
|
||||
* where there are fewer special modes, and they don't persisit.
|
||||
*/
|
||||
class QuickFixDialog : public wxDialogWrapper
|
||||
{
|
||||
public:
|
||||
QuickFixDialog(wxWindow * pParent);
|
||||
void Populate();
|
||||
void PopulateOrExchange(ShuttleGui & S);
|
||||
void AddStuck( ShuttleGui & S, bool & bBool, wxString Pref, wxString Prompt, wxString Help );
|
||||
|
||||
void OnOk(wxCommandEvent &event);
|
||||
void OnCancel(wxCommandEvent &event);
|
||||
void OnHelp(wxCommandEvent &event);
|
||||
void OnFix(wxCommandEvent &event);
|
||||
|
||||
wxString StringFromEvent( wxCommandEvent &event );
|
||||
|
||||
int mItem;
|
||||
bool mbSyncLocked;
|
||||
bool mbInSnapTo;
|
||||
bool mbSoundActivated;
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#define FixButtonID 7001
|
||||
#define HelpButtonID 7011
|
||||
#define FakeButtonID 7021
|
||||
|
||||
BEGIN_EVENT_TABLE(QuickFixDialog, wxDialogWrapper)
|
||||
EVT_BUTTON(wxID_OK, QuickFixDialog::OnOk)
|
||||
EVT_BUTTON(wxID_CANCEL, QuickFixDialog::OnCancel)
|
||||
EVT_BUTTON(wxID_HELP, QuickFixDialog::OnHelp)
|
||||
EVT_COMMAND_RANGE(FixButtonID, HelpButtonID-1, wxEVT_BUTTON, QuickFixDialog::OnFix)
|
||||
EVT_COMMAND_RANGE(HelpButtonID, FakeButtonID-1, wxEVT_BUTTON, QuickFixDialog::OnHelp)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
QuickFixDialog::QuickFixDialog(wxWindow * pParent) :
|
||||
wxDialogWrapper(pParent, wxID_ANY, _("Do you have these problems?"),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE )
|
||||
{
|
||||
const long SNAP_OFF = 0;
|
||||
|
||||
gPrefs->Read(wxT("/GUI/SyncLockTracks"), &mbSyncLocked, false);
|
||||
mbInSnapTo = gPrefs->Read(wxT("/SnapTo"), SNAP_OFF) !=0;
|
||||
gPrefs->Read(wxT("/AudioIO/SoundActivatedRecord"), &mbSoundActivated, false);
|
||||
|
||||
ShuttleGui S(this, eIsCreating);
|
||||
PopulateOrExchange(S);
|
||||
|
||||
Fit();
|
||||
auto sz = GetSize();
|
||||
SetMinSize( sz );
|
||||
SetMaxSize( sz );
|
||||
|
||||
// The close button has the cancel id and acts exactly the same as cancel.
|
||||
wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
|
||||
if( pWin )
|
||||
pWin->SetFocus( );
|
||||
Center();
|
||||
}
|
||||
|
||||
void QuickFixDialog::AddStuck( ShuttleGui & S, bool & bBool, wxString Pref, wxString Prompt, wxString Help )
|
||||
{
|
||||
mItem++;
|
||||
if( !bBool)
|
||||
return;
|
||||
S.AddFixedText( Prompt );
|
||||
S.Id(FixButtonID + mItem).AddButton( _("Fix") )->SetClientObject(
|
||||
safenew wxStringClientData(Pref));
|
||||
|
||||
{
|
||||
// Replace standard Help button with smaller icon button.
|
||||
// bs->AddButton(safenew wxButton(parent, wxID_HELP));
|
||||
auto b = safenew wxBitmapButton(S.GetParent(), HelpButtonID+mItem, theTheme.Bitmap( bmpHelpIcon ));
|
||||
b->SetToolTip( _("Help") );
|
||||
b->SetLabel(_("Help")); // for screen readers
|
||||
b->SetClientObject( safenew wxStringClientData( Help ));
|
||||
S.AddWindow( b );
|
||||
}
|
||||
}
|
||||
|
||||
void QuickFixDialog::PopulateOrExchange(ShuttleGui & S)
|
||||
{
|
||||
|
||||
S.StartVerticalLay(1);
|
||||
S.StartStatic( _("Quick Fixes"));
|
||||
|
||||
// These aren't all possible modes one can be stuck in, but they are some of them.
|
||||
bool bStuckInMode = mbSyncLocked || mbInSnapTo || mbSoundActivated;
|
||||
|
||||
if( !bStuckInMode ){
|
||||
SetLabel(_("Nothing to do"));
|
||||
S.AddFixedText(_("No quick, easily fixed problems were found"));
|
||||
}
|
||||
else {
|
||||
S.StartMultiColumn(3, wxALIGN_CENTER);
|
||||
{
|
||||
mItem = -1;
|
||||
|
||||
// Use # in the URLs to ensure we go to the online version of help.
|
||||
// Local help may well not be installed.
|
||||
AddStuck( S, mbSyncLocked, "/GUI/SyncLockTracks", _("Clocks on the Tracks"), "Quick_Fix#sync_lock" );
|
||||
AddStuck( S, mbInSnapTo, "/SnapTo", _("Can't select precisely"), "Quick_Fix#snap_to" );
|
||||
AddStuck( S, mbSoundActivated, "/AudioIO/SoundActivatedRecord", _("Recording stops and starts"), "Quick_Fix#sound_activated_recording" );
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
S.EndStatic();
|
||||
|
||||
S.StartHorizontalLay(wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
S.AddStandardButtons(eCloseButton + (bStuckInMode ? 0 : eHelpButton));
|
||||
S.EndHorizontalLay();
|
||||
|
||||
S.EndVerticalLay();
|
||||
|
||||
wxButton * pBtn = (wxButton*)FindWindowById( wxID_HELP );
|
||||
if( pBtn )
|
||||
pBtn->SetClientObject( safenew wxStringClientData( "Quick_Fix#" ));
|
||||
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnOk(wxCommandEvent &event)
|
||||
{
|
||||
(void)event;// Compiler food
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnCancel(wxCommandEvent &event)
|
||||
{
|
||||
(void)event;// Compiler food
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
wxString QuickFixDialog::StringFromEvent( wxCommandEvent &event )
|
||||
{
|
||||
wxButton * pBtn = (wxButton*)event.GetEventObject();
|
||||
if( !pBtn ){
|
||||
wxFAIL_MSG( "Event Object not found");
|
||||
return "";
|
||||
}
|
||||
wxStringClientData * pStrCd = (wxStringClientData*)(pBtn->GetClientObject());
|
||||
if( !pStrCd ){
|
||||
wxFAIL_MSG( "Client Data not found");
|
||||
return "";
|
||||
}
|
||||
wxString Str = pStrCd->GetData();
|
||||
if( Str.empty()){
|
||||
wxFAIL_MSG( "String data empty");
|
||||
return "";
|
||||
}
|
||||
return Str;
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnHelp(wxCommandEvent &event)
|
||||
{
|
||||
HelpSystem::ShowHelp(this, StringFromEvent( event ), true);
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnFix(wxCommandEvent &event)
|
||||
{
|
||||
wxString Str = StringFromEvent( event );
|
||||
gPrefs->Write( Str, 0);
|
||||
gPrefs->Flush();
|
||||
|
||||
if ( auto pProject = GetActiveProject() ) {
|
||||
// Sadly SnapTo has to be handled specially, as it is not part of the standard
|
||||
// preference dialogs.
|
||||
if( Str == "/SnapTo" )
|
||||
{
|
||||
pProject->SetSnapTo( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is overkill (aka slow), as all preferences are reloaded and all
|
||||
// toolbars recreated.
|
||||
// Overkill probably doesn't matter, as this command is infrequently used.
|
||||
EditActions::DoReloadPreferences( *pProject );
|
||||
}
|
||||
}
|
||||
|
||||
// Change the label after doing the fix, as the fix may take a second or two.
|
||||
wxButton * pBtn = (wxButton*)event.GetEventObject();
|
||||
if( pBtn )
|
||||
pBtn->SetLabel( _("Fixed") );
|
||||
|
||||
// The close button has the cancel id and acts exactly the same as cancel.
|
||||
wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
|
||||
if( pWin )
|
||||
pWin->SetFocus( );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace HelpActions {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "../TrackPanel.h"
|
||||
#include "../UndoManager.h"
|
||||
#include "../WaveClip.h"
|
||||
#include "../prefs/RecordingPrefs.h"
|
||||
#include "../prefs/TracksPrefs.h"
|
||||
#include "../toolbars/ControlToolBar.h"
|
||||
#include "../toolbars/TranscriptionToolBar.h"
|
||||
|
@ -26,6 +26,110 @@ ODTask requests and internals.
|
||||
#include <wx/thread.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
// On Mac OS X, it's better not to use the wxThread class.
|
||||
// We use our own implementation based on pthreads instead.
|
||||
|
||||
class ODTaskThread {
|
||||
public:
|
||||
typedef int ExitCode;
|
||||
ODTaskThread(ODTask* task);
|
||||
/*ExitCode*/ void Entry();
|
||||
void Create() {}
|
||||
void Delete() {
|
||||
mDestroy = true;
|
||||
pthread_join(mThread, NULL);
|
||||
}
|
||||
bool TestDestroy() { return mDestroy; }
|
||||
void Sleep(int ms) {
|
||||
struct timespec spec;
|
||||
spec.tv_sec = 0;
|
||||
spec.tv_nsec = ms * 1000 * 1000;
|
||||
nanosleep(&spec, NULL);
|
||||
}
|
||||
static void *callback(void *p) {
|
||||
ODTaskThread *th = (ODTaskThread *)p;
|
||||
#if defined(__WXMAC__)
|
||||
/*return (void *)*/ th->Entry();
|
||||
return NULL;
|
||||
#else
|
||||
return (void *) th->Entry();
|
||||
#endif
|
||||
}
|
||||
void Run() {
|
||||
pthread_create(&mThread, NULL, callback, this);
|
||||
}
|
||||
|
||||
///Specifies the priority the thread will run at. Currently doesn't work.
|
||||
///@param priority value from 0 (min priority) to 100 (max priority)
|
||||
void SetPriority(int priority)
|
||||
{
|
||||
mPriority=priority;
|
||||
}
|
||||
|
||||
private:
|
||||
int mPriority;
|
||||
bool mDestroy;
|
||||
pthread_t mThread;
|
||||
|
||||
ODTask* mTask;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class ODTaskThread final : public wxThread
|
||||
{
|
||||
public:
|
||||
///Constructs a ODTaskThread
|
||||
///@param task the task to be launched as an
|
||||
ODTaskThread(ODTask* task);
|
||||
|
||||
|
||||
protected:
|
||||
///Executes a part of the task
|
||||
void* Entry() override;
|
||||
ODTask* mTask;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
ODTaskThread::ODTaskThread(ODTask* task)
|
||||
#ifndef __WXMAC__
|
||||
: wxThread()
|
||||
#endif
|
||||
{
|
||||
mTask=task;
|
||||
#ifdef __WXMAC__
|
||||
mDestroy = false;
|
||||
mThread = NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
void ODTaskThread::Entry()
|
||||
#else
|
||||
void *ODTaskThread::Entry()
|
||||
|
||||
#endif
|
||||
{
|
||||
//TODO: Figure out why this has no effect at all.
|
||||
//wxThread::This()->SetPriority( 40);
|
||||
//Do at least 5 percent of the task
|
||||
mTask->DoSome(0.05f);
|
||||
|
||||
//release the thread count so that the ODManager knows how many active threads are alive.
|
||||
ODManager::Instance()->DecrementCurrentThreads();
|
||||
|
||||
|
||||
#ifndef __WXMAC__
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static ODLock gODInitedMutex;
|
||||
static bool gManagerCreated=false;
|
||||
static bool gPause=false; //to be loaded in and used with Pause/Resume before ODMan init.
|
||||
|
@ -18,44 +18,6 @@
|
||||
|
||||
#include "ODTaskThread.h"
|
||||
|
||||
#include "ODTask.h"
|
||||
#include "ODManager.h"
|
||||
|
||||
|
||||
ODTaskThread::ODTaskThread(ODTask* task)
|
||||
#ifndef __WXMAC__
|
||||
: wxThread()
|
||||
#endif
|
||||
{
|
||||
mTask=task;
|
||||
#ifdef __WXMAC__
|
||||
mDestroy = false;
|
||||
mThread = NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
void ODTaskThread::Entry()
|
||||
#else
|
||||
void *ODTaskThread::Entry()
|
||||
|
||||
#endif
|
||||
{
|
||||
//TODO: Figure out why this has no effect at all.
|
||||
//wxThread::This()->SetPriority( 40);
|
||||
//Do at least 5 percent of the task
|
||||
mTask->DoSome(0.05f);
|
||||
|
||||
//release the thread count so that the ODManager knows how many active threads are alive.
|
||||
ODManager::Instance()->DecrementCurrentThreads();
|
||||
|
||||
|
||||
#ifndef __WXMAC__
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
ODCondition::ODCondition(ODLock *lock)
|
||||
|
@ -32,57 +32,9 @@ class ODTask;
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
||||
// On Mac OS X, it's better not to use the wxThread class.
|
||||
// We use our own implementation based on pthreads instead.
|
||||
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
class ODTaskThread {
|
||||
public:
|
||||
typedef int ExitCode;
|
||||
ODTaskThread(ODTask* task);
|
||||
/*ExitCode*/ void Entry();
|
||||
void Create() {}
|
||||
void Delete() {
|
||||
mDestroy = true;
|
||||
pthread_join(mThread, NULL);
|
||||
}
|
||||
bool TestDestroy() { return mDestroy; }
|
||||
void Sleep(int ms) {
|
||||
struct timespec spec;
|
||||
spec.tv_sec = 0;
|
||||
spec.tv_nsec = ms * 1000 * 1000;
|
||||
nanosleep(&spec, NULL);
|
||||
}
|
||||
static void *callback(void *p) {
|
||||
ODTaskThread *th = (ODTaskThread *)p;
|
||||
#if defined(__WXMAC__)
|
||||
/*return (void *)*/ th->Entry();
|
||||
return NULL;
|
||||
#else
|
||||
return (void *) th->Entry();
|
||||
#endif
|
||||
}
|
||||
void Run() {
|
||||
pthread_create(&mThread, NULL, callback, this);
|
||||
}
|
||||
|
||||
///Specifies the priority the thread will run at. Currently doesn't work.
|
||||
///@param priority value from 0 (min priority) to 100 (max priority)
|
||||
void SetPriority(int priority)
|
||||
{
|
||||
mPriority=priority;
|
||||
}
|
||||
|
||||
private:
|
||||
int mPriority;
|
||||
bool mDestroy;
|
||||
pthread_t mThread;
|
||||
|
||||
ODTask* mTask;
|
||||
};
|
||||
|
||||
class ODLock {
|
||||
public:
|
||||
ODLock(){
|
||||
@ -132,22 +84,6 @@ protected:
|
||||
#else
|
||||
|
||||
|
||||
class ODTaskThread final : public wxThread
|
||||
{
|
||||
public:
|
||||
///Constructs a ODTaskThread
|
||||
///@param task the task to be launched as an
|
||||
ODTaskThread(ODTask* task);
|
||||
|
||||
|
||||
protected:
|
||||
///Executes a part of the task
|
||||
void* Entry() override;
|
||||
ODTask* mTask;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//a wrapper for wxMutex.
|
||||
class AUDACITY_DLL_API ODLock final : public wxMutex
|
||||
{
|
||||
|
@ -25,6 +25,8 @@ other settings.
|
||||
#include "../Audacity.h"
|
||||
#include "DevicePrefs.h"
|
||||
|
||||
#include "RecordingPrefs.h"
|
||||
|
||||
#include <wx/defs.h>
|
||||
|
||||
#include <wx/choice.h>
|
||||
|
@ -815,7 +815,7 @@ void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
// Reads preference /GUI/Theme
|
||||
theTheme.LoadPreferredTheme();
|
||||
theTheme.ApplyUpdatedImages();
|
||||
ThemePrefs::ApplyUpdatedImages();
|
||||
|
||||
SavePreferredPage();
|
||||
|
||||
|
@ -55,44 +55,6 @@ static EnumSetting formatSetting{
|
||||
wxT("/SamplingRate/DefaultProjectSampleFormat"),
|
||||
};
|
||||
|
||||
//////////
|
||||
static const EnumValueSymbol choicesDither[] = {
|
||||
{ XO("None") },
|
||||
{ XO("Rectangle") },
|
||||
{ XO("Triangle") },
|
||||
{ XO("Shaped") },
|
||||
};
|
||||
static const size_t nChoicesDither = WXSIZEOF( choicesDither );
|
||||
static const int intChoicesDither[] = {
|
||||
(int) DitherType::none,
|
||||
(int) DitherType::rectangle,
|
||||
(int) DitherType::triangle,
|
||||
(int) DitherType::shaped,
|
||||
};
|
||||
static_assert(
|
||||
nChoicesDither == WXSIZEOF( intChoicesDither ),
|
||||
"size mismatch"
|
||||
);
|
||||
|
||||
static const size_t defaultFastDither = 0; // none
|
||||
|
||||
static EnumSetting fastDitherSetting{
|
||||
wxT("Quality/DitherAlgorithmChoice"),
|
||||
choicesDither, nChoicesDither, defaultFastDither,
|
||||
intChoicesDither,
|
||||
wxT("Quality/DitherAlgorithm")
|
||||
};
|
||||
|
||||
static const size_t defaultBestDither = 3; // shaped
|
||||
|
||||
static EnumSetting bestDitherSetting{
|
||||
wxT("Quality/HQDitherAlgorithmChoice"),
|
||||
choicesDither, nChoicesDither, defaultBestDither,
|
||||
|
||||
intChoicesDither,
|
||||
wxT("Quality/HQDitherAlgorithm")
|
||||
};
|
||||
|
||||
//////////
|
||||
BEGIN_EVENT_TABLE(QualityPrefs, PrefsPanel)
|
||||
EVT_CHOICE(ID_SAMPLE_RATE_CHOICE, QualityPrefs::OnSampleRateChoice)
|
||||
@ -225,7 +187,7 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
||||
|
||||
/* i18n-hint: technical term for randomization to reduce undesirable resampling artifacts */
|
||||
S.TieChoice(_("&Dither:"),
|
||||
fastDitherSetting);
|
||||
Dither::FastSetting);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
@ -240,7 +202,7 @@ void QualityPrefs::PopulateOrExchange(ShuttleGui & S)
|
||||
|
||||
/* i18n-hint: technical term for randomization to reduce undesirable resampling artifacts */
|
||||
S.TieChoice(_("Dit&her:"),
|
||||
bestDitherSetting);
|
||||
Dither::BestSetting);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
@ -287,13 +249,3 @@ sampleFormat QualityPrefs::SampleFormatChoice()
|
||||
return (sampleFormat)formatSetting.ReadInt();
|
||||
}
|
||||
|
||||
DitherType QualityPrefs::FastDitherChoice()
|
||||
{
|
||||
return (DitherType) fastDitherSetting.ReadInt();
|
||||
}
|
||||
|
||||
DitherType QualityPrefs::BestDitherChoice()
|
||||
{
|
||||
return (DitherType) bestDitherSetting.ReadInt();
|
||||
}
|
||||
|
||||
|
@ -41,9 +41,6 @@ class QualityPrefs final : public PrefsPanel
|
||||
|
||||
static sampleFormat SampleFormatChoice();
|
||||
|
||||
static DitherType FastDitherChoice();
|
||||
static DitherType BestDitherChoice();
|
||||
|
||||
private:
|
||||
void Populate();
|
||||
void GetNamesAndLabels();
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <wx/textctrl.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../AudioIO.h"
|
||||
#include "../prefs/GUISettings.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../ShuttleGui.h"
|
||||
|
@ -21,6 +21,15 @@ class ShuttleGui;
|
||||
|
||||
#define RECORDING_PREFS_PLUGIN_SYMBOL ComponentInterfaceSymbol{ XO("Recording") }
|
||||
|
||||
#define DEFAULT_LATENCY_DURATION 100.0
|
||||
#define DEFAULT_LATENCY_CORRECTION -130.0
|
||||
|
||||
#define AUDIO_PRE_ROLL_KEY (wxT("/AudioIO/PreRoll"))
|
||||
#define DEFAULT_PRE_ROLL_SECONDS 5.0
|
||||
|
||||
#define AUDIO_ROLL_CROSSFADE_KEY (wxT("/AudioIO/Crossfade"))
|
||||
#define DEFAULT_ROLL_CROSSFADE_MS 10.0
|
||||
|
||||
class RecordingPrefs final : public PrefsPanel
|
||||
{
|
||||
public:
|
||||
|
@ -31,13 +31,15 @@ Provides:
|
||||
#include "../Audacity.h"
|
||||
#include "ThemePrefs.h"
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/wxprec.h>
|
||||
#include "../Prefs.h"
|
||||
#include "../Theme.h"
|
||||
#include "../Project.h"
|
||||
#include "../ShuttleGui.h"
|
||||
#include "../AColor.h"
|
||||
|
||||
wxDEFINE_EVENT(EVT_THEME_CHANGE, wxCommandEvent);
|
||||
|
||||
enum eThemePrefsIds {
|
||||
idLoadThemeCache=7000,
|
||||
idSaveThemeCache,
|
||||
@ -170,7 +172,7 @@ void ThemePrefs::PopulateOrExchange(ShuttleGui & S)
|
||||
void ThemePrefs::OnLoadThemeComponents(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
theTheme.LoadComponents();
|
||||
theTheme.ApplyUpdatedImages();
|
||||
ApplyUpdatedImages();
|
||||
}
|
||||
|
||||
/// Save Theme to multiple png files.
|
||||
@ -183,7 +185,7 @@ void ThemePrefs::OnSaveThemeComponents(wxCommandEvent & WXUNUSED(event))
|
||||
void ThemePrefs::OnLoadThemeCache(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
theTheme.ReadImageCache();
|
||||
theTheme.ApplyUpdatedImages();
|
||||
ApplyUpdatedImages();
|
||||
}
|
||||
|
||||
/// Save Theme to single png file.
|
||||
@ -197,7 +199,7 @@ void ThemePrefs::OnSaveThemeCache(wxCommandEvent & WXUNUSED(event))
|
||||
void ThemePrefs::OnReadThemeInternal(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
theTheme.ReadImageCache( theTheme.GetFallbackThemeType() );
|
||||
theTheme.ApplyUpdatedImages();
|
||||
ApplyUpdatedImages();
|
||||
}
|
||||
|
||||
/// Save Theme as C source code.
|
||||
@ -207,6 +209,14 @@ void ThemePrefs::OnSaveThemeAsCode(wxCommandEvent & WXUNUSED(event))
|
||||
theTheme.WriteImageDefs();// bonus - give them the Defs too.
|
||||
}
|
||||
|
||||
void ThemePrefs::ApplyUpdatedImages()
|
||||
{
|
||||
AColor::ReInit();
|
||||
|
||||
wxCommandEvent e{ EVT_THEME_CHANGE };
|
||||
wxTheApp->SafelyProcessEvent( e );
|
||||
}
|
||||
|
||||
/// Update the preferences stored on disk.
|
||||
bool ThemePrefs::Commit()
|
||||
{
|
||||
|
@ -15,11 +15,16 @@
|
||||
#define __AUDACITY_THEME_PREFS__
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include <wx/event.h> // to declare a custom event type
|
||||
|
||||
#include "PrefsPanel.h"
|
||||
|
||||
class ShuttleGui;
|
||||
|
||||
// An event sent to the application when the user changes choice of theme
|
||||
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_THEME_CHANGE, wxCommandEvent);
|
||||
|
||||
#define THEME_PREFS_PLUGIN_SYMBOL ComponentInterfaceSymbol{ XO("Theme") }
|
||||
|
||||
class ThemePrefs final : public PrefsPanel
|
||||
@ -33,6 +38,8 @@ class ThemePrefs final : public PrefsPanel
|
||||
bool Commit() override;
|
||||
wxString HelpPageName() override;
|
||||
|
||||
static void ApplyUpdatedImages();
|
||||
|
||||
private:
|
||||
void Populate();
|
||||
void PopulateOrExchange(ShuttleGui & S) override;
|
||||
|
@ -16,10 +16,12 @@
|
||||
#include "../Experimental.h"
|
||||
|
||||
#include <wx/setup.h> // for wxUSE_* macros
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/intl.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
@ -34,8 +36,8 @@
|
||||
#include "../AllThemeResources.h"
|
||||
#include "../ShuttleGui.h"
|
||||
#include "../HelpText.h"
|
||||
#include "../Project.h"
|
||||
#include "../Prefs.h"
|
||||
#include "../wxFileNameWrapper.h"
|
||||
|
||||
#ifdef USE_ALPHA_MANUAL
|
||||
const wxString HelpSystem::HelpHostname = wxT("alphamanual.audacityteam.org");
|
||||
@ -225,17 +227,20 @@ void HelpSystem::ShowHelp(wxWindow *parent,
|
||||
bool alwaysDefaultBrowser)
|
||||
{
|
||||
wxASSERT(parent); // to justify safenew
|
||||
AudacityProject * pProj = GetActiveProject();
|
||||
wxString HelpMode = wxT("Local");
|
||||
|
||||
if( pProj )
|
||||
// DA: Default for DA is manual from internet.
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
gPrefs->Read(wxT("/GUI/Help"), &HelpMode, wxT("FromInternet") );
|
||||
#else
|
||||
gPrefs->Read(wxT("/GUI/Help"), &HelpMode, wxT("Local") );
|
||||
#endif
|
||||
|
||||
{
|
||||
HelpMode = pProj->mHelpPref;
|
||||
// these next lines are for legacy cfg files (pre 2.0) where we had different modes
|
||||
if( (HelpMode == wxT("Standard")) || (HelpMode == wxT("InBrowser")) )
|
||||
{
|
||||
HelpMode = wxT("Local");
|
||||
pProj->mHelpPref = HelpMode;
|
||||
gPrefs->Write(wxT("/GUI/Help"), HelpMode);
|
||||
gPrefs->Flush();
|
||||
}
|
||||
@ -394,177 +399,3 @@ void HelpSystem::ShowHelp(wxWindow *parent,
|
||||
bModal
|
||||
);
|
||||
}
|
||||
|
||||
#include "../ShuttleGui.h"
|
||||
// These three are all for the OnReloadPreferences command.
|
||||
#include "../Project.h"
|
||||
#include "../commands/CommandContext.h"
|
||||
#include "../Menus.h"
|
||||
|
||||
#define FixButtonID 7001
|
||||
#define HelpButtonID 7011
|
||||
#define FakeButtonID 7021
|
||||
|
||||
BEGIN_EVENT_TABLE(QuickFixDialog, wxDialogWrapper)
|
||||
EVT_BUTTON(wxID_OK, QuickFixDialog::OnOk)
|
||||
EVT_BUTTON(wxID_CANCEL, QuickFixDialog::OnCancel)
|
||||
EVT_BUTTON(wxID_HELP, QuickFixDialog::OnHelp)
|
||||
EVT_COMMAND_RANGE(FixButtonID, HelpButtonID-1, wxEVT_BUTTON, QuickFixDialog::OnFix)
|
||||
EVT_COMMAND_RANGE(HelpButtonID, FakeButtonID-1, wxEVT_BUTTON, QuickFixDialog::OnHelp)
|
||||
END_EVENT_TABLE();
|
||||
|
||||
QuickFixDialog::QuickFixDialog(wxWindow * pParent) :
|
||||
wxDialogWrapper(pParent, wxID_ANY, _("Do you have these problems?"),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE )
|
||||
{
|
||||
const long SNAP_OFF = 0;
|
||||
|
||||
gPrefs->Read(wxT("/GUI/SyncLockTracks"), &mbSyncLocked, false);
|
||||
mbInSnapTo = gPrefs->Read(wxT("/SnapTo"), SNAP_OFF) !=0;
|
||||
gPrefs->Read(wxT("/AudioIO/SoundActivatedRecord"), &mbSoundActivated, false);
|
||||
|
||||
ShuttleGui S(this, eIsCreating);
|
||||
PopulateOrExchange(S);
|
||||
|
||||
Fit();
|
||||
auto sz = GetSize();
|
||||
SetMinSize( sz );
|
||||
SetMaxSize( sz );
|
||||
|
||||
// The close button has the cancel id and acts exactly the same as cancel.
|
||||
wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
|
||||
if( pWin )
|
||||
pWin->SetFocus( );
|
||||
Center();
|
||||
}
|
||||
|
||||
void QuickFixDialog::AddStuck( ShuttleGui & S, bool & bBool, wxString Pref, wxString Prompt, wxString Help )
|
||||
{
|
||||
mItem++;
|
||||
if( !bBool)
|
||||
return;
|
||||
S.AddFixedText( Prompt );
|
||||
S.Id(FixButtonID + mItem).AddButton( _("Fix") )->SetClientObject(
|
||||
safenew wxStringClientData(Pref));
|
||||
|
||||
{
|
||||
// Replace standard Help button with smaller icon button.
|
||||
// bs->AddButton(safenew wxButton(parent, wxID_HELP));
|
||||
auto b = safenew wxBitmapButton(S.GetParent(), HelpButtonID+mItem, theTheme.Bitmap( bmpHelpIcon ));
|
||||
b->SetToolTip( _("Help") );
|
||||
b->SetLabel(_("Help")); // for screen readers
|
||||
b->SetClientObject( safenew wxStringClientData( Help ));
|
||||
S.AddWindow( b );
|
||||
}
|
||||
}
|
||||
|
||||
void QuickFixDialog::PopulateOrExchange(ShuttleGui & S)
|
||||
{
|
||||
|
||||
S.StartVerticalLay(1);
|
||||
S.StartStatic( _("Quick Fixes"));
|
||||
|
||||
// These aren't all possible modes one can be stuck in, but they are some of them.
|
||||
bool bStuckInMode = mbSyncLocked || mbInSnapTo || mbSoundActivated;
|
||||
|
||||
if( !bStuckInMode ){
|
||||
SetLabel(_("Nothing to do"));
|
||||
S.AddFixedText(_("No quick, easily fixed problems were found"));
|
||||
}
|
||||
else {
|
||||
S.StartMultiColumn(3, wxALIGN_CENTER);
|
||||
{
|
||||
mItem = -1;
|
||||
|
||||
// Use # in the URLs to ensure we go to the online version of help.
|
||||
// Local help may well not be installed.
|
||||
AddStuck( S, mbSyncLocked, "/GUI/SyncLockTracks", _("Clocks on the Tracks"), "Quick_Fix#sync_lock" );
|
||||
AddStuck( S, mbInSnapTo, "/SnapTo", _("Can't select precisely"), "Quick_Fix#snap_to" );
|
||||
AddStuck( S, mbSoundActivated, "/AudioIO/SoundActivatedRecord", _("Recording stops and starts"), "Quick_Fix#sound_activated_recording" );
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
}
|
||||
S.EndStatic();
|
||||
|
||||
S.StartHorizontalLay(wxALIGN_CENTER_HORIZONTAL, 0);
|
||||
S.AddStandardButtons(eCloseButton + (bStuckInMode ? 0 : eHelpButton));
|
||||
S.EndHorizontalLay();
|
||||
|
||||
S.EndVerticalLay();
|
||||
|
||||
wxButton * pBtn = (wxButton*)FindWindowById( wxID_HELP );
|
||||
if( pBtn )
|
||||
pBtn->SetClientObject( safenew wxStringClientData( "Quick_Fix#" ));
|
||||
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnOk(wxCommandEvent &event)
|
||||
{
|
||||
(void)event;// Compiler food
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnCancel(wxCommandEvent &event)
|
||||
{
|
||||
(void)event;// Compiler food
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
wxString QuickFixDialog::StringFromEvent( wxCommandEvent &event )
|
||||
{
|
||||
wxButton * pBtn = (wxButton*)event.GetEventObject();
|
||||
if( !pBtn ){
|
||||
wxFAIL_MSG( "Event Object not found");
|
||||
return "";
|
||||
}
|
||||
wxStringClientData * pStrCd = (wxStringClientData*)(pBtn->GetClientObject());
|
||||
if( !pStrCd ){
|
||||
wxFAIL_MSG( "Client Data not found");
|
||||
return "";
|
||||
}
|
||||
wxString Str = pStrCd->GetData();
|
||||
if( Str.empty()){
|
||||
wxFAIL_MSG( "String data empty");
|
||||
return "";
|
||||
}
|
||||
return Str;
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnHelp(wxCommandEvent &event)
|
||||
{
|
||||
HelpSystem::ShowHelp(this, StringFromEvent( event ), true);
|
||||
}
|
||||
|
||||
void QuickFixDialog::OnFix(wxCommandEvent &event)
|
||||
{
|
||||
wxString Str = StringFromEvent( event );
|
||||
gPrefs->Write( Str, 0);
|
||||
gPrefs->Flush();
|
||||
|
||||
if ( auto pProject = GetActiveProject() ) {
|
||||
// Sadly SnapTo has to be handled specially, as it is not part of the standard
|
||||
// preference dialogs.
|
||||
if( Str == "/SnapTo" )
|
||||
{
|
||||
pProject->SetSnapTo( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is overkill (aka slow), as all preferences are reloaded and all
|
||||
// toolbars recreated.
|
||||
// Overkill probably doesn't matter, as this command is infrequently used.
|
||||
EditActions::DoReloadPreferences( *pProject );
|
||||
}
|
||||
}
|
||||
|
||||
// Change the label after doing the fix, as the fix may take a second or two.
|
||||
wxButton * pBtn = (wxButton*)event.GetEventObject();
|
||||
if( pBtn )
|
||||
pBtn->SetLabel( _("Fixed") );
|
||||
|
||||
// The close button has the cancel id and acts exactly the same as cancel.
|
||||
wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
|
||||
if( pWin )
|
||||
pWin->SetFocus( );
|
||||
}
|
||||
|
@ -104,33 +104,4 @@ public:
|
||||
|
||||
class ShuttleGui;
|
||||
|
||||
/** @brief Class which makes a dialog for displaying quick fixes to common issues.
|
||||
*
|
||||
* This class originated with the 'Stuck in a mode' problem, where far too many
|
||||
* users get into a mode without realising, and don't know how to get out.
|
||||
* It is a band-aid, and we should do more towards a full and proper solution
|
||||
* where there are fewer special modes, and they don't persisit.
|
||||
*/
|
||||
class QuickFixDialog : public wxDialogWrapper
|
||||
{
|
||||
public:
|
||||
QuickFixDialog(wxWindow * pParent);
|
||||
void Populate();
|
||||
void PopulateOrExchange(ShuttleGui & S);
|
||||
void AddStuck( ShuttleGui & S, bool & bBool, wxString Pref, wxString Prompt, wxString Help );
|
||||
|
||||
void OnOk(wxCommandEvent &event);
|
||||
void OnCancel(wxCommandEvent &event);
|
||||
void OnHelp(wxCommandEvent &event);
|
||||
void OnFix(wxCommandEvent &event);
|
||||
|
||||
wxString StringFromEvent( wxCommandEvent &event );
|
||||
|
||||
int mItem;
|
||||
bool mbSyncLocked;
|
||||
bool mbInSnapTo;
|
||||
bool mbSoundActivated;
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
#endif // __AUDACITY_HELPSYSTEM__
|
||||
|
@ -33,8 +33,6 @@
|
||||
#include <wx/arrstr.h>
|
||||
#include <wx/filename.h>
|
||||
|
||||
#include "../Track.h"
|
||||
|
||||
// Length check. Is in part about not supplying malicious strings to file functions.
|
||||
bool XMLValueChecker::IsGoodString(const wxString & str)
|
||||
{
|
||||
@ -168,7 +166,7 @@ bool XMLValueChecker::IsGoodInt64(const wxString & strInt)
|
||||
|
||||
bool XMLValueChecker::IsValidChannel(const int nValue)
|
||||
{
|
||||
return (nValue >= Track::LeftChannel) && (nValue <= Track::MonoChannel);
|
||||
return (nValue >= LeftChannel) && (nValue <= MonoChannel);
|
||||
}
|
||||
|
||||
#ifdef USE_MIDI
|
||||
|
@ -63,6 +63,12 @@ public:
|
||||
static bool IsGoodInt64(const wxString & strInt);
|
||||
static bool IsGoodIntForRange(const wxString & strInt, const wxString & strMAXABS);
|
||||
|
||||
enum ChannelType
|
||||
{
|
||||
LeftChannel = 0,
|
||||
RightChannel = 1,
|
||||
MonoChannel = 2
|
||||
};
|
||||
static bool IsValidChannel(const int nValue);
|
||||
#ifdef USE_MIDI
|
||||
static bool IsValidVisibleChannels(const int nValue);
|
||||
|
Loading…
x
Reference in New Issue
Block a user