1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-02 17:09:26 +02:00

Add code from merging.

This brings more of the code from DarkAudacity into Audacity, though not yet enabled.  This will make cherry picking later easier.
- Changing colour of html displays now possible, as colour links are visible for substitution.  (Can't use css as wxHTML is very limited).
- Export can now be preset to a particular format independent of preferences.
- SnapTo reversion on zoom now a DA controlled option.
- Caching of pinning preference for faster repaint because preferences are slow.
- Record Append now has sensible limit on number of tracks, rather than giving an error, and flipping the meaning of shift is now DA controlled.
This commit is contained in:
James Crook 2016-09-10 21:34:14 +01:00
parent 796b98de8b
commit 923eefaf90
8 changed files with 110 additions and 46 deletions

View File

@ -46,6 +46,8 @@ hold information about one contributor to Audacity.
#include "../images/AudacityLogoWithName.xpm" #include "../images/AudacityLogoWithName.xpm"
extern wxString FormatHtmlText( const wxString & Text );
void AboutDialog::CreateCreditsList() void AboutDialog::CreateCreditsList()
{ {
// The Audacity Team: developers and support // The Audacity Team: developers and support
@ -173,23 +175,23 @@ void AboutDialog::CreateCreditsList()
// Libraries // Libraries
AddCredit(wxT("<a href=\"http://www.jclark.com/xml/expat.html\">expat</a>"), roleLibrary); AddCredit(wxT("[[http://www.jclark.com/xml/expat.html|expat]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://xiph.org/flac/\">FLAC</a>"), roleLibrary); AddCredit(wxT("[[http://xiph.org/flac/|FLAC]]"), roleLibrary);
AddCredit(wxT("iAVC</a>"), roleLibrary); AddCredit(wxT("iAVC"), roleLibrary);
AddCredit(wxT("<a href=\"http://lame.sourceforge.net/\">LAME</a>"), roleLibrary); AddCredit(wxT("[[http://lame.sourceforge.net/|LAME]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://www.underbit.com/products/mad/\">libmad</a>"), roleLibrary); AddCredit(wxT("[[http://www.underbit.com/products/mad/|libmad]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://www.mega-nerd.com/libsndfile/\">libsndfile</a>"), roleLibrary); AddCredit(wxT("[[http://www.mega-nerd.com/libsndfile/|libsndfile]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://sourceforge.net/p/soxr/wiki/Home/\">libsoxr</a>"), roleLibrary); AddCredit(wxT("[[http://sourceforge.net/p/soxr/wiki/Home/|libsoxr]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://lv2plug.in/\">lv2</a> (") + _("incorporating") + wxT(" lilv, msinttypes, serd, sord and sratom)"), roleLibrary); AddCredit(wxT("[[http://lv2plug.in/|lv2]] (") + _("incorporating") + wxT(" lilv, msinttypes, serd, sord and sratom)"), roleLibrary);
AddCredit(wxT("<a href=\"https://www.cs.cmu.edu/~music/nyquist/\">Nyquist</a>"), roleLibrary); AddCredit(wxT("[[https://www.cs.cmu.edu/~music/nyquist/|Nyquist]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://vorbis.com/\">Ogg Vorbis</a>"), roleLibrary); AddCredit(wxT("[[http://vorbis.com/|Ogg Vorbis]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://www.portaudio.com/\">PortAudio</a>"), roleLibrary); AddCredit(wxT("[[http://www.portaudio.com/|PortAudio]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://sourceforge.net/apps/trac/portmedia/wiki/portsmf/\">portsmf</a>"), roleLibrary); AddCredit(wxT("[[http://sourceforge.net/apps/trac/portmedia/wiki/portsmf/|portsmf]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://sbsms.sourceforge.net/\">sbsms</a>"), roleLibrary); AddCredit(wxT("[[http://sbsms.sourceforge.net/|sbsms]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://www.surina.net/soundtouch/\">SoundTouch</a>"), roleLibrary); AddCredit(wxT("[[http://www.surina.net/soundtouch/|SoundTouch]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://www.twolame.org/\">TwoLAME</a>"), roleLibrary); AddCredit(wxT("[[http://www.twolame.org/|TwoLAME]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://www.vamp-plugins.org/\">Vamp</a>"), roleLibrary); AddCredit(wxT("[[http://www.vamp-plugins.org/|Vamp]]"), roleLibrary);
AddCredit(wxT("<a href=\"http://wxwidgets.org/\">wxWidgets</a>"), roleLibrary); AddCredit(wxT("[[http://wxwidgets.org/|wxWidgets]]"), roleLibrary);
// Thanks // Thanks
@ -296,11 +298,8 @@ visit our <a href=\"http://forum.audacityteam.org/\">forum</a>.");
} }
wxString localeStr = wxLocale::GetSystemEncodingName(); wxString localeStr = wxLocale::GetSystemEncodingName();
wxString creditStr = wxString creditStr = FormatHtmlText(
wxT("<html><head><META http-equiv=\"Content-Type\" content=\"text/html; charset=") + wxString( wxT("<center>")) +
localeStr +
wxT("\"></head>") +
wxT("<body bgcolor=\"#ffffff\"><center>") +
wxT("<h3>Audacity ") + wxString(AUDACITY_VERSION_STRING) + wxT("</center></h3>") + wxT("<h3>Audacity ") + wxString(AUDACITY_VERSION_STRING) + wxT("</center></h3>") +
_("Free, open source, cross-platform software for recording and editing sounds.") + _("Free, open source, cross-platform software for recording and editing sounds.") +
wxT(" <a href=\"http://audacityteam.org/\">http://audacityteam.org/</a>") + wxT(" <a href=\"http://audacityteam.org/\">http://audacityteam.org/</a>") +
@ -332,7 +331,7 @@ visit our <a href=\"http://forum.audacityteam.org/\">forum</a>.");
wxT("<p><br>") + _("<b>Audacity&reg;</b> software is copyright")+ wxT("<p><br>") + _("<b>Audacity&reg;</b> software is copyright")+
wxT("&copy; 1999-2016 Audacity Team.<br>") + wxT("&copy; 1999-2016 Audacity Team.<br>") +
_("The name <b>Audacity&reg;</b> is a registered trademark of Dominic Mazzoni.") + _("The name <b>Audacity&reg;</b> is a registered trademark of Dominic Mazzoni.") +
wxT("</center></font></body></html>"); wxT("</center>"));
this->SetBackgroundColour(theTheme.Colour( clrAboutBoxBackground )); this->SetBackgroundColour(theTheme.Colour( clrAboutBoxBackground ));
@ -605,6 +604,8 @@ void AboutDialog::PopulateInformationPage( ShuttleGui & S )
// end of table // end of table
informationStr += wxT("</table>\n"); informationStr += wxT("</table>\n");
informationStr = FormatHtmlText( informationStr );
html->SetPage(informationStr); // push the page into the html renderer html->SetPage(informationStr); // push the page into the html renderer
S.Prop(2).AddWindow( html, wxEXPAND ); // make it fill the page S.Prop(2).AddWindow( html, wxEXPAND ); // make it fill the page
// I think the 2 here goes with the StartVerticalLay() call above? // I think the 2 here goes with the StartVerticalLay() call above?
@ -628,7 +629,7 @@ void AboutDialog::PopulateLicensePage( ShuttleGui & S )
// better proportionally spaced. // better proportionally spaced.
// //
// The GPL is not to be translated.... // The GPL is not to be translated....
wxString PageText= wxString PageText= FormatHtmlText(
wxT(" <center>GNU GENERAL PUBLIC LICENSE\n</center>") wxT(" <center>GNU GENERAL PUBLIC LICENSE\n</center>")
wxT(" <center>Version 2, June 1991\n</center>") wxT(" <center>Version 2, June 1991\n</center>")
wxT("<p><p>") wxT("<p><p>")
@ -910,7 +911,7 @@ wxT("OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n
wxT("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n") wxT("TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n")
wxT("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n") wxT("YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n")
wxT("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n") wxT("PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n")
wxT("POSSIBILITY OF SUCH DAMAGES.\n"); wxT("POSSIBILITY OF SUCH DAMAGES.\n"));
html->SetPage( PageText ); html->SetPage( PageText );

View File

@ -62,11 +62,10 @@ static wxString FileLink( const wxString &Key, const wxString& Text )
wxT("</a>"); wxT("</a>");
} }
static wxString HttpLink( const wxString &Key, const wxString& Text ) static wxString TypedLink( const wxString &Key, const wxString& Text )
{ {
return wxString(wxT("")) + return wxString(wxT("")) +
wxT("<a href='") + wxT("<a href='") +
wxT("http:") +
Key + Key +
wxT("'>") + wxT("'>") +
Text + Text +
@ -101,7 +100,15 @@ static wxString LinkExpand( const wxString & Text )
} }
else if( Key.StartsWith( wxT("http:") )) else if( Key.StartsWith( wxT("http:") ))
{ {
Replacement = HttpLink( Key.Mid( 5 ), LinkText ); Replacement = TypedLink( Key, LinkText );
}
else if( Key.StartsWith( wxT("mailto:") ))
{
Replacement = TypedLink( Key, LinkText );
}
else if( Key.StartsWith( wxT("*URL*") ))
{
Replacement = TypedLink( Key, LinkText );
} }
else else
{ {
@ -189,9 +196,9 @@ static wxString HelpTextBuiltIn( const wxString & Key )
wxT("<center><h3>Audacity ") + AUDACITY_VERSION_STRING + wxT("</h3><h3>") + wxT("<center><h3>Audacity ") + AUDACITY_VERSION_STRING + wxT("</h3><h3>") +
_("How to get help") + wxT("</h3></center>") + _("How to get help") + wxT("</h3></center>") +
_("These are our support methods:") + wxT("<p><ul><li>") + _("These are our support methods:") + wxT("<p><ul><li>") +
_(" [[file:quick_help.html|Quick Help]] - if not installed locally, <a href=\"http://manual.audacityteam.org/quick_help.html\">view online</a>") + wxT("</li><li>") + _(" [[file:quick_help.html|Quick Help]] - if not installed locally, [[http://manual.audacityteam.org/quick_help.html|view online]]") + wxT("</li><li>") +
_(" [[file:index.html|Manual]] - if not installed locally, <a href=\"http://manual.audacityteam.org/\">view online</a>") + wxT("</li><li>") + _(" [[file:index.html|Manual]] - if not installed locally, [[http://manual.audacityteam.org/|view online]]") + wxT("</li><li>") +
_(" <a href=\"http://forum.audacityteam.org/\">Forum</a> - ask your question directly, online.") + wxT("</li></ul></p><p>") + wxT("<b>") + _(" [[http://forum.audacityteam.org/|Forum]] - ask your question directly, online.") + wxT("</li></ul></p><p>") + wxT("<b>") +
_("More:</b> Visit our [[http://wiki.audacityteam.org/index.php|Wiki]] for tips, tricks, extra tutorials and effects plug-ins.") + wxT("</p>") _("More:</b> Visit our [[http://wiki.audacityteam.org/index.php|Wiki]] for tips, tricks, extra tutorials and effects plug-ins.") + wxT("</p>")
); );
} }
@ -201,12 +208,12 @@ static wxString HelpTextBuiltIn( const wxString & Key )
wxString(wxT("<p>"))+ wxString(wxT("<p>"))+
_("Audacity can import unprotected files in many other formats (such as M4A and WMA, \ _("Audacity can import unprotected files in many other formats (such as M4A and WMA, \
compressed WAV files from portable recorders and audio from video files) if you download and install \ compressed WAV files from portable recorders and audio from video files) if you download and install \
the optional <a href=\"http://manual.audacityteam.org/man/faq_opening_and_saving_files.html#foreign\"> \ the optional [[http://manual.audacityteam.org/man/faq_opening_and_saving_files.html#foreign| \
FFmpeg library</a> to your computer.") + wxT("</p><p>") + FFmpeg library]] to your computer.") + wxT("</p><p>") +
_("You can also read our help on importing \ _("You can also read our help on importing \
<a href=\"http://manual.audacityteam.org/man/faq_opening_and_saving_files.html#midi\">MIDI files</a> \ [[http://manual.audacityteam.org/man/faq_opening_and_saving_files.html#midi|MIDI files]] \
and tracks from <a href=\"http://manual.audacityteam.org/man/faq_opening_and_saving_files.html#fromcd\"> \ and tracks from [[http://manual.audacityteam.org/man/faq_opening_and_saving_files.html#fromcd| \
audio CDs</a>.") + wxT("</p>") audio CDs]].") + wxT("</p>")
); );
} }
@ -217,9 +224,9 @@ audio CDs</a>.") + wxT("</p>")
{ {
// *URL* will be replaced by whatever URL we are looking for. // *URL* will be replaced by whatever URL we are looking for.
return WrapText(_("The Manual does not appear to be installed. \ return WrapText(_("The Manual does not appear to be installed. \
Please <a href=\"*URL*\">view the Manual online</a> or \ Please [[*URL*|view the Manual online]] or \
<a href=\"http://manual.audacityteam.org/man/unzipping_the_manual.html\"> \ [[http://manual.audacityteam.org/man/unzipping_the_manual.html| \
download the Manual</a>.<br><br>\ download the Manual]].<br><br>\
To always view the Manual online, change \"Location of Manual\" in \ To always view the Manual online, change \"Location of Manual\" in \
Interface Preferences to \"From Internet\".") Interface Preferences to \"From Internet\".")
); );
@ -245,3 +252,15 @@ wxString HelpText( const wxString & Key )
// Perhaps useful for debugging - we'll return key that we didn't find. // Perhaps useful for debugging - we'll return key that we didn't find.
return WrapText( Key ); return WrapText( Key );
} }
wxString FormatHtmlText( const wxString & Text ){
wxString localeStr = wxLocale::GetSystemEncodingName();
return
wxT("<html><head><META http-equiv=\"Content-Type\" content=\"text/html; charset=") +
localeStr +
wxT("\"></head>") +
WrapText( LinkExpand( Text ))+
wxT("</html>");
}

View File

@ -89,6 +89,18 @@ bool ZoomInfo::ZoomOutAvailable() const
void ZoomInfo::SetZoom(double pixelsPerSecond) void ZoomInfo::SetZoom(double pixelsPerSecond)
{ {
zoom = std::max(gMinZoom, std::min(gMaxZoom, pixelsPerSecond)); zoom = std::max(gMinZoom, std::min(gMaxZoom, pixelsPerSecond));
#ifdef EXPERIMENTAL_DA
// Disable snapping if user zooms in a long way.
// Helps stop users be trapped in snap-to.
// The level chosen is in sample viewing range with samples
// still quite close together.
if( zoom > (gMaxZoom * 0.06 ))
{
AudacityProject * project = GetActiveProject();
if( project )
project->OnSnapToOff();
}
#endif
} }
void ZoomInfo::ZoomBy(double multiplier) void ZoomInfo::ZoomBy(double multiplier)

View File

@ -265,6 +265,7 @@ Exporter::Exporter()
{ {
mMixerSpec = NULL; mMixerSpec = NULL;
mBook = NULL; mBook = NULL;
mFormatName = "";
SetFileDialogTitle( _("Export Audio") ); SetFileDialogTitle( _("Export Audio") );
@ -488,7 +489,9 @@ bool Exporter::GetFilename()
mFormat = -1; mFormat = -1;
wxString maskString; wxString maskString;
wxString defaultFormat = gPrefs->Read(wxT("/Export/Format"), wxString defaultFormat = mFormatName;
if( defaultFormat.IsEmpty() )
defaultFormat = gPrefs->Read(wxT("/Export/Format"),
wxT("WAV")); wxT("WAV"));
mFilterIndex = 0; mFilterIndex = 0;
@ -678,7 +681,8 @@ bool Exporter::CheckFilename()
if (!mProject->GetDirManager()->EnsureSafeFilename(mFilename)) if (!mProject->GetDirManager()->EnsureSafeFilename(mFilename))
return false; return false;
gPrefs->Write(wxT("/Export/Format"), mPlugins[mFormat]->GetFormat(mSubFormat)); if( mFormatName.IsEmpty() )
gPrefs->Write(wxT("/Export/Format"), mPlugins[mFormat]->GetFormat(mSubFormat));
gPrefs->Write(wxT("/Export/Path"), mFilename.GetPath()); gPrefs->Write(wxT("/Export/Path"), mFilename.GetPath());
gPrefs->Flush(); gPrefs->Flush();

View File

@ -144,6 +144,7 @@ public:
virtual ~Exporter(); virtual ~Exporter();
void SetFileDialogTitle( const wxString & DialogTitle ); void SetFileDialogTitle( const wxString & DialogTitle );
void SetDefaultFormat( const wxString & Format ){ mFormatName = Format;};
void RegisterPlugin(movable_ptr<ExportPlugin> &&plugin); void RegisterPlugin(movable_ptr<ExportPlugin> &&plugin);
bool Process(AudacityProject *project, bool selectedOnly, bool Process(AudacityProject *project, bool selectedOnly,
@ -173,7 +174,7 @@ public:
wxFileName GetAutoExportFileName(); wxFileName GetAutoExportFileName();
private: private:
wxString mFormatName;
bool ExamineTracks(); bool ExamineTracks();
bool GetFilename(); bool GetFilename();
bool CheckFilename(); bool CheckFilename();

View File

@ -30,6 +30,7 @@
#include "../Experimental.h" #include "../Experimental.h"
int TracksPrefs::iPreferencePinned = -1;
namespace { namespace {
const wxChar *PinnedHeadPreferenceKey() const wxChar *PinnedHeadPreferenceKey()
@ -179,11 +180,18 @@ void TracksPrefs::PopulateOrExchange(ShuttleGui & S)
bool TracksPrefs::GetPinnedHeadPreference() bool TracksPrefs::GetPinnedHeadPreference()
{ {
return gPrefs->ReadBool(PinnedHeadPreferenceKey(), PinnedHeadPreferenceDefault()); // JKC: Cache this setting as it is read many times during drawing, and otherwise causes screen flicker.
// Correct solution would be to re-write wxFileConfig to be efficient.
if( iPreferencePinned >= 0 )
return iPreferencePinned == 1;
bool bResult = gPrefs->ReadBool(PinnedHeadPreferenceKey(), PinnedHeadPreferenceDefault());
iPreferencePinned = bResult ? 1: 0;
return bResult;
} }
void TracksPrefs::SetPinnedHeadPreference(bool value, bool flush) void TracksPrefs::SetPinnedHeadPreference(bool value, bool flush)
{ {
iPreferencePinned = value ? 1 :0;
gPrefs->Write(PinnedHeadPreferenceKey(), value); gPrefs->Write(PinnedHeadPreferenceKey(), value);
if(flush) if(flush)
gPrefs->Flush(); gPrefs->Flush();

View File

@ -38,6 +38,7 @@ class TracksPrefs final : public PrefsPanel
void Populate(); void Populate();
void PopulateOrExchange(ShuttleGui & S); void PopulateOrExchange(ShuttleGui & S);
static int iPreferencePinned;
wxArrayString mSoloCodes; wxArrayString mSoloCodes;
wxArrayString mSoloChoices; wxArrayString mSoloChoices;
wxArrayInt mViewCodes; wxArrayInt mViewCodes;

View File

@ -223,8 +223,13 @@ void ControlToolBar::RegenerateTooltips()
break; break;
case ID_RECORD_BUTTON: case ID_RECORD_BUTTON:
commands.push_back(wxT("Record")); commands.push_back(wxT("Record"));
#ifndef EXPERIMENTAL_DA
commands.push_back(_("Append Record")); commands.push_back(_("Append Record"));
commands.push_back(wxT("RecordAppend")); commands.push_back(wxT("RecordAppend"));
#else
commands.push_back(_("Record Below"));
commands.push_back(wxT("RecordBelow"));
#endif
break; break;
case ID_PAUSE_BUTTON: case ID_PAUSE_BUTTON:
commands.push_back(wxT("Pause")); commands.push_back(wxT("Pause"));
@ -875,8 +880,14 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
if (p) { if (p) {
TrackList *trackList = p->GetTracks(); TrackList *trackList = p->GetTracks();
TrackListIterator it(trackList); TrackListIterator it(trackList);
bool shifted = mRecord->WasShiftDown();
#ifdef EXPERIMENTAL_DA
shifted = !shifted;
#endif
if(it.First() == NULL) if(it.First() == NULL)
mRecord->SetShift(false); shifted = false;
double t0 = p->GetSel0(); double t0 = p->GetSel0();
double t1 = p->GetSel1(); double t1 = p->GetSel1();
if (t1 == t0) if (t1 == t0)
@ -908,8 +919,9 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
int recordingChannels = 0; int recordingChannels = 0;
TrackList tracksCopy{}; TrackList tracksCopy{};
bool tracksCopied = false; bool tracksCopied = false;
bool shifted = mRecord->WasShiftDown();
if (shifted) { if (shifted) {
recordingChannels = gPrefs->Read(wxT("/AudioIO/RecordChannels"), 2);
bool sel = false; bool sel = false;
double allt0 = t0; double allt0 = t0;
@ -965,6 +977,10 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
wxUnusedVar(bResult); wxUnusedVar(bResult);
} }
newRecordingTracks.push_back(wt); newRecordingTracks.push_back(wt);
// Don't record more channels than configured recording pref.
if( (int)newRecordingTracks.size() >= recordingChannels ){
break;
}
} }
} }
@ -973,6 +989,8 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
else { else {
bool recordingNameCustom, useTrackNumber, useDateStamp, useTimeStamp; bool recordingNameCustom, useTrackNumber, useDateStamp, useTimeStamp;
wxString defaultTrackName, defaultRecordingTrackName; wxString defaultTrackName, defaultRecordingTrackName;
// Count the tracks.
int numTracks = 0; int numTracks = 0;
for (Track *tt = it.First(); tt; tt = it.Next()) { for (Track *tt = it.First(); tt; tt = it.Next()) {
@ -980,7 +998,7 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
numTracks++; numTracks++;
} }
numTracks++; numTracks++;
recordingChannels = gPrefs->Read(wxT("/AudioIO/RecordChannels"), 2); recordingChannels = gPrefs->Read(wxT("/AudioIO/RecordChannels"), 2);
gPrefs->Read(wxT("/GUI/TrackNames/RecordingNameCustom"), &recordingNameCustom, false); gPrefs->Read(wxT("/GUI/TrackNames/RecordingNameCustom"), &recordingNameCustom, false);