... Format arguments are substituted into the translation of the msgid, which
may not be known at the time the format arguments are captured (because locale
may change). This allows TranslatableString with arguments to be constructed
at static initialization time.
There is also a special "verbatim" or null context which makes no translations
of msgids.
There is not yet any use of other contexts besides default or null.
Closing sub trees can leave the wrong item selected.
If a node near the bottom of the tree is closed, the node may move
down, and no longer be under the mouse pointer. If further processing
is allowed, then the line at the mouse position is incorrectly selected.
Fix: Don't allow further processing and call SetFocus() ourselves.
My previous fix for this bug, commit 4b437b8, did not work on Mac.
This bug was introduced by my commit b62ed73. This commit was to ensure that when the keyview was the focus, there was always one item selected. This ensures that the focus is indicated visually, and that the Narrator screen reader reads the keyview.
The failed fix, selected an item if necessary when the keyview became the focus.
The current fix reverts b62ed73 and 4b437b8, and ensures that an item is selected each time the items are updated.
Steps to reproduce:
1. Open preferences
2. Select the keyboard category
3. Scroll down the list by any amount
4. Select an item using the mouse. The list scrolls to the top and the wrong item is selected.
The problem occurs because if the list of shortcuts is currently not the focus, then after a left mouse click, KeyView::OnSetFocus() is called, and setting the selection in that function interferes with the mouse selection.
Fix: In KeyView::OnSetFocus(), if there has been a left down event, don't select anything.
Problem:
NumericTextCtrls act on numeric keys, even when modifier keys are pressed.
This shouldn't be the case, and has the knock on effect that shortcuts like ctrl + 1, don't work when a NumericTextCtrl is the focus.
Fix:
Check that there are no modifier keys pressed.
... New files, but (almost) empty; don't use the global variable gAudioIO,
but use one of two accessor function names (which are the same function for
now).
AudioIOBase will have fewer dependencies than AudioIO -- in particular, no
dependency on tracks.
It won't include StartStream. It will contain functions to query the
present state of streams, and device capabilities.
... as a preparation for splitting up class AudacityProject.
Use ProjectWindow as an alias for AudacityProject, and fetch it from the
project with a static member function, where certain of its services are used;
pretending they are not the same class.
Use global accessor functions to get wxFrame from the project where only
wxFrame's member functions are needed, so there will be less dependency on
ProjectWindow when it becomes a distinct class.
... Rename it as SetStatus; make it part of AudacityProject not
TrackPanelListener; and use a roundabout event signalling to cause the timer
restart.
Because SetStatus will be one of very few things left in AudacityProject, but
the timer handling will be part of another class decoupled from it.
And TrackPanelListener won't really be needed: TrackPanel will not need to
pretend it doesn't know what an AudacityProject is.
... Just one low-level function for each that simply sets; just one high-level
function for each that also pushes notifications; and to make that work,
toolbars need some rewriting to avoid recursion when the notifications they
post come back to them.
... There was no reason to store the help location preferences as per-project
state. Also move the dialog for quick fixes near its only use in
HelpMenus.cpp.
This takes 22 files out of the big strongly connected component, notably
the much used lower level utilities, ErrorDialog and AudacityException.
HelpSystem itself is still in a small cycle with LinkingHtmlWindow.
... and break its compile dependency on CommandManager.h by letting it install
callbacks.
This also removes Objective-C mixed code from CommmandManager.
This also eliminates four inclusions of Project.h!
Capture handler state is also global, not per project, though the
CommandManager's callbacks still do depend on the active project.
Problem: this affects NVDA and Narrator, but not Jaws. If a user moves to the Delete button and presses it to delete a label, a label is incorrectly read as the new focus - the focus remains on the Delete button.
GridAx::SetCurrentCell() can be called when the Grid is not the focus, and send a focus event.
Fix: In GridAx::SetCurrentCell() only send an focus event if the Grid is the focus.
Problem. If an item in the list is selected, then if a different view by radio button is selected, Narrator reads the selected item rather than the radio button.
KeyViewAx::SetCurrentLine(int line) can be called when the KeyView is not the focus, and send a focus event.
Fix: In KeyViewAx::SetCurrentLine(int line), only send focus event if the KeyView is the focus.
... Unnecessary because transitively included.
But each .cpp file still includes its own .h file near the top to ensure
that it compiles indenendently, even if it is reincluded transitively later.
Problem:
If an ASlider in the main window is clicked, then you can't TAB away from the control.
Fix:
Keyboard shortcuts are handled using key down events. However, ASlider was handling char events for reasons unknown. I'm unsure why this was causing a problem, but changing ASlider to handle key down events fixes the bug.
Problem: A user can tab to the list, and none of the items is the focus. The list itself is still the focus. As a result, there is no visual indication of the focus, and an additional keystroke is needed to make any item the focus.
Fix: When the list gains focus, if no items are selected, select the first item, if there is one.
Problem:
Using the Narrator screen reader on Windows 10:
1. Narrator does not read the uneditable cells in the tag column of the Metadata editor.
2. In one or more versions of Windows 10 prior to 1809, Narrator's focus was incorrect after editing a cell.
Fixes:
1. Fixed by adding wxACC_STATE_SYSTEM_FOCUSED to the state.
2. Corrected GridAx::GetFocus().
... as was the intention in the wxWidgets code from which these files were
adapted
More importantly this removes the mischievous #define (added at 08c94d5) from
valnum.h, which made it impossible to #include that header before
<wx/combobox.h>.
Note that (the real type) wxTextEntry is not a kind of wxWindow, but a class
from which wxTextCtrl and wxComboBox both inherit, while they inherit wxWindow
too along other paths.
So in some places, use the protected variable m_ValidatorWindow instead to
access the validator's window.
Problem:
Using the Narrator screen reader on Windows 10, there are a couple of problems:
1. When using the left/right arrow keys, Narrator reads the current field, rather than the digit which is now the focus.
2. Using up/down arrow keys, Narrator is silent.
Fixes:
1. The existing code assumes that NumericTextCtrlAx::GetName() is called only once after left/right arrow is pressed. However, Narrator causes this function to be called more than once. Solution: handle the case where the function is called, and neither the focus or the digits have changed, and use a cached value of the name.
2. If the focus has not changed, then after a focus event, Narrator does not read the name, even if the name has changed. Solution: add a name change event. (The focus event has been retained to keep Window-Eyes happy until we stop supporting it.)
Note:
One of the focus events has been removed from NumericTextCtrl::SetFieldFocus(), as it no longer appears to be necessary.
... except Audacity.h
This forces us to make each header contain all forward declarations or nested
headers that it requires, rather than depend on context.
... except Audacity.h; and in no others.
Do so even if Experimental.h gets multiply included, as in both the .h and
.cpp files.
This makes it easier to do a text scan to be sure there are no unintended quiet
changes of meaning because of omission of Experimental.h when the flag is
an enabled one.
Also move inclusions of Experimental.h earlier.
Also don't require Experimental.h to be preceded by Audacity.h to define
EXPERIMENTAL_MIDI_OUT correctly.
... Make all line drawing go through our AColor which wraps the wxDC
line-drawing functions.
Despite what wxWidgets documentation says, the functions still don't
consistently include the first point and omit the last point of a line. I
observed inclusion of both on Mac, while on Windows, omission sometimes of the
first point instead of the last.
Discrepancies could be observed in 2.3.0 between Windows and Mac, using the
Window magnifier or command+alt+ +, zooming in closely on the ends of the
shadow lines below and right of tracks, or at the bottom-right corners of the
bevels drawn around vertical rulers.
So where there is an observable one-pixel difference of drawing between
platforms, there is the question, which was the intent when the drawing code
was written? Should the coordinates be corrected by one or not?
I reviewed each case and used my judgment.
Most of the calls are in drawing rulers. Major tick lines were drawn five
pixels long, and minor, three, on Mac. I keep this behavior, but you might
argue for making them four and two.
On the other hand the drawing of ruler grid lines, which you can see in
the equalization and frequency analysis windows, did need a one-pixel correction
to avoid straying out of bounds.
... for wxString and wxArrayStringEx, holding file paths (absolute or relative,
directory or plain file); to be replaced later with different types
(not yet using std::vector, becase of some uses of wxArrayString::Index with
two arguments)
... Replacing:
Insert => insert
RemoveAt => erase
Remove => erase
IsSameAs => operator == or operator !=
(but only when second argument was true or default)
... instead use the utility make_iterator_range and its index() or contains()
method. This generic utility works with any container defining begin() and
end().
This further lessens dependency on wxWidgets container idioms.
... which will make it easier to change the types of those containers to
std::vectors of other string-like classes
for wxString,
IsEmpty => empty
Clear => clear
Alloc => reserve
for wxArrayString,
Count => size
GetCount => size
IsEmpty => empty
Add => push_back
Clear => clear
Empty => clear
Sort => std::sort (only with default comparator)
SetCount => resize
Last => back
Item => operator []
Alloc => reserve
It combines the old IdentInterface with the ParamsInterface, providing an identifier and parameters (if needed).
The main purpose of the change is to make the class hierarchy (as viewed via doxygen) much easier to follow.
... Remove mention of obsolete plans for TrackPanel refactor, superseded by a
different refactor now accomplished.
Remove detailed mention of names of functions and data members that implement
drawing.
Move most of Roger's comments about drawing into Overlay.h which is now the
more relevant place.
Commented more correctly what TrackPanelListener is.
Problem: profiled the limiter effect, and found that wxGetLocalTimeMillis() in ProgressDilaog::Update was taking up a lot of time.
The slow down of the nyquist effects and analysers was introduced by the switch to wxWidgets 3.1.1, so presumably there was some change to the implementation of wxGetLocalTimeMillis()
Fix: Use wxGetUTCTimeMillis() instead of wxLocalTimeMillis() in ProgressDialog.cpp. This is much faster on Windows, and wxWidgets recommend its use to due wxGetLocalTimeMillis() being affected by start/end summer time (daylight saving time).
... not the negation of max(), which is wrong for unsigned types, and not
min(), which gives least normalized positive value for floating point types.
lowest() wasn't available before C++11.
... This was motivated by punch and roll recording: it appears most convenient
to pin the head for recording purposes, and drag it near the right, but when
stopping and finding the splice point for the correction, it is better to
scrub unpinned.
Now we show "11:07:29 +" for a time 100 years, 11 hours, 7 mins and 29 seconds in the future, rather than ASSERTing.
The + should probably be mentioned in the manual. "In the countdown, times more than 24 hours ahead aren't shown fully. A '+' sign after the time indicates that it is more than a day ahead."
... also make popup menus at right up, not down, for consistency with other
popup menus in TrackPanel
Base class also does the event propagation "hack" for ScrubPoller
... All updates of position are done in DoGetRectangle(). Ruler need only
expose one function, DrawOverlays().
Don't redraw indicators twice when dragging (hiding and showing again), making
some flicker. Just do one update.
All backing bitmaps (not just the one in track panel) now are set to 24 bits.
Big thanks to David Bailes for tracking down the root cause of slow BitBlts, and the comments at https://trac.wxwidgets.org/ticket/14403 which led to the fix.
In testing the bitmaps, I also fixed the sizer errors reported for Export.cpp that wxWidgets now reports as ASSERTS when running in debug builds.
... Replace some enum constants with the equivalent values from the more
special-purpose enums, as the wx header files recommend, so overloading
selects the ctors with non-int arguments.
In a full rebuild of the debug project on Mac, this reduces the count of
warnings from 264 to 274.
This possible fix is based on the idea that YieldFor is flaky, and is holding up events that we SHOULD process.
Therefore we process ALL events, not just some, and we do two yields, in case we are getting behind on the queue.
We were for example getting many of these:
\audacity\src\widgets\numerictextctrl.h(171): warning C4458: declaration of 'value' hides class member
MSVC2013 didn't warn about these, but MSVC2017 does.
Motivation:
1. The text boxes in the label track are not fully accessible for users of screen readers, and I don't think that they can be made to be fully accessible using the accessibility API used by wxWidgets. When such an edit box becomes the focus, this is not announced, and for NVDA users typed characters are not echoed.
2. Provides a work around for bugs 1778 (cannot type diacritics into text label), and 1804 (Windows: Labels do not accept IME (Chinese/Japanese) input).
Fix: Provide an option for a dialog for entering the name. The text box in the dialog is accessible for screen readers. On windows the text box receives wm_keydown and wm_char messages and so is a work around for bug 1804. Being a standard text box, it will presumably be a work around for bug 1778.
1. There is a new option in track behaviors: "Use dialog for the name of new label", which is off by default.
2. When using the commands "Add label at selection" and "Add label at playback position", when the dialog closes, focus is returned to the track which was the focus before the dialog opened. I think this is more convenient for users of screen readers.
The main point of this is not to ask for overcrowded rulers.
We already handle overcrowded rulers well, by not showing the minor ticks.
This change means that we are more likely to ask for a spacing that works.
In turn that means that we are less likely to have anomalies where numbers disappear due to overcrowding and reappear again as you resize the ruler.
Modification to commit 7ab4b8c. The first non-zero digit only becomes the focus on the first visit to the control. On subsequent visits, the focus is the previous focus. Example use case: modifying start and end times by a tenth of a second. The user can move between the controls without loosing his "place".
The main change in wx accessibility is this:
7dab555f71 (diff-04f5191d86f95b1c4d5d9c979da65878)
However wxWindowAccessible has not been updated to take into account of that change. In particular wxWindowAccessible::GetParent() was always wrong, but it was consistent with the rest of the framework. Now it's wrong and inconsistent. This function should return an object with role window, and which has the same name.
The fix is to introduce class WindowAccessible, which is effectively our own version of wxWindowAccessible. This class does not override GetParent(), and so just relies on a standard accessible object to to the right thing in wxIAccessible::get_accParent() (which is does). This class also allows us to have our own version of GetName(), which allows us to set the accessibility names of buttons.
These changes will break the accessibility of Audacity if it is built with wxWidgets 3.0.X. If this is a problem, then there could be some #if stuff in WindowAccessible.h to turn the WindowAccessible class into one which simply inherits from wxWindowAccessible, and doesn't override anything.
The problem was actually more general, and involves misalignment between selections
in clips and selections in the background and in the ruler - so could be seen with just
audio tracks and no label tracks.
... Such are not for display to the user. They are appended to menu item
names to identify accelerators, and wxWidgets transforms them appropriately
for the operating system.
This is a squash of 50 commits.
This merges the capabilities of BatchCommands and Effects using a new
AudacityCommand class. AudacityCommand provides one function to specify the
parameters, and then we leverage that one function in automation, whether by chains,
mod-script-pipe or (future) Nyquist.
- Now have AudacityCommand which is using the same mechanism as Effect
- Has configurable parameters
- Has data-entry GUI (built using shuttle GUI)
- Registers with PluginManager.
- Menu commands now provided in chains, and to python batch.
- Tested with Zoom Toggle.
- ShuttleParams now can set, get, set defaults, validate and specify
the parameters.
- Bugfix: Don't overwrite values with defaults first time out.
- Add DefineParams function for all built-in effects.
- Extend CommandContext to carry output channels for results.
We abuse EffectsManager. It handles both Effects and
AudacityCommands now. In time an Effect should become a special case of
AudacityCommand and we'll split and rename the EffectManager class.
- Don't use 'default' as a parameter name.
- Massive renaming for CommandDefinitionInterface
- EffectIdentInterface becomes EffectDefinitionInterface
- EffectAutomationParameters becomes CommandAutomationParameters
- PluginType is now a bit field.
This way we can search for related types at the same time.
- Most old batch commands made into AudacityCommands.
The ones that weren't are for a reason. They are used by mod-script-pipe
to carry commands and responses across from a non-GUI thread to the GUI
thread.
- Major tidy up of ScreenshotCommand
- Reworking of SelectCommand
- GetPreferenceCommand and SetPreferenceCommand
- GetTrackInfo and SetTrackInfo
- GetInfoCommand
- Help, Open, Save, Import and Export commands.
- Removed obsolete commands ExecMenu, GetProjectInfo and SetProjectInfo
which are now better handled by other commands.
- JSONify "GetInfo: Commands" output, i.e. commas in the right places.
- General work on better Doxygen.
- Lyrics -> LyricsPanel
- Meter -> MeterPanel
- Updated Linux makefile.
- Scripting commands added into Extra menu.
- Distinct names for previously duplicated find-clipping parameters.
- Fixed longstanding error with erroneous status field number which
previously caused an ASSERT in debug.
- Sensible formatting of numbers in Chains, 0.1 not 0.1000000000137