20#include <wx/combobox.h>
21#include <wx/display.h>
22#include <wx/scrolbar.h>
29 return dlg.ShowModal() == wxID_OK;
42 ComboEditor(
const wxArrayString& choices,
bool allowOthers =
false)
43 : wxGridCellChoiceEditor(choices, allowOthers)
49 void PaintBackground(wxDC&,
const wxRect& WXUNUSED(rectCell),
const wxGridCellAttr & WXUNUSED(attr))
override
56 wxGridCellChoiceEditor::SetParameters(
params);
65 void SetSize(
const wxRect& rectOrig)
override
67 wxRect rect(rectOrig);
68 wxRect r = Combo()->GetRect();
71 rect.y -= (r.GetHeight() - rect.GetHeight()) / 2;
72 rect.height = r.GetHeight();
74 wxGridCellChoiceEditor::SetSize(rect);
91 wxComboBox * tc = Combo();
97 ch =
event.GetUnicodeKey();
103 ch =
event.GetKeyCode();
104 isPrintable = ch >= WXK_SPACE && ch < WXK_START;
117 const long pos = tc->GetLastPosition();
118 tc->Remove(pos - 1, pos);
124 tc->WriteText(
static_cast<wxChar
>(ch));
130 wxGridCellEditor *
Clone()
const override
144#define LABEL_ARTIST XO("Artist Name")
145#define LABEL_TITLE XO("Track Title")
146#define LABEL_ALBUM XO("Album Title")
147#define LABEL_TRACK XO("Track Number")
148#define LABEL_YEAR XO("Year")
149#define LABEL_GENRE XO("Genre")
150#define LABEL_COMMENTS XO("Comments")
178#define STATICCNT WXSIZEOF(labelmap)
215 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
217 mEditTitle(editTitle),
218 mEditTrack(editTrack)
229 PopulateOrExchange(
S);
231 TransferDataToWindow();
236 wxSize sz = GetSize();
237 SetSizeHints(sz.x,
std::min(sz.y, 600));
244 wxRect r = GetRect();
245 gPrefs->Read(
wxT(
"/TagsEditorDialog/x"), &r.x, r.x);
246 gPrefs->Read(
wxT(
"/TagsEditorDialog/y"), &r.y, r.y);
247 gPrefs->Read(
wxT(
"/TagsEditorDialog/width"), &r.width, r.width);
248 gPrefs->Read(
wxT(
"/TagsEditorDialog/height"), &r.height, r.height);
251 if (IsWindowRectValid(&r))
252 Move(r.GetPosition());
254 SetSize(r.GetSize());
258 wxScrollBar sb(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);
259 r = mGrid->GetClientRect();
260 r.width -= mGrid->GetColSize(0);
261 r.width -= sb.GetSize().GetWidth();
264 mGrid->SetColSize(1, r.width);
288 gPrefs->Read(
wxT(
"/AudioFiles/ShowId3Dialog"), &bShow,
true );
290 S.StartVerticalLay();
292 S.StartHorizontalLay(wxALIGN_LEFT, 0);
294 S.AddUnits(
XO(
"Use arrow keys (or ENTER key after editing) to navigate fields."));
296 S.EndHorizontalLay();
305 mGrid->RegisterDataType(
wxT(
"Combo"),
309 mGrid->SetColLabelSize(
mGrid->GetDefaultRowSize());
311 auto cs = transform_container<wxArrayStringEx>(
315 mGrid->CreateGrid(0, 2, wxGrid::wxGridSelectRows);
316 mGrid->SetRowLabelSize(0);
317 mGrid->SetDefaultCellAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
318 mGrid->SetColLabelValue(0,
_(
"Tag"));
319 mGrid->SetColLabelValue(1,
_(
"Value"));
322 wxComboBox tc(
this, wxID_ANY,
wxT(
""), wxDefaultPosition, wxDefaultSize, cs);
323 mGrid->SetColSize(0, tc.GetSize().x);
324 mGrid->SetColMinimalWidth(0, tc.GetSize().x);
327 .Position(wxEXPAND | wxALL)
330 S.StartMultiColumn(4, wxALIGN_CENTER);
339 S.StartHorizontalLay(wxALIGN_CENTRE, 0);
341 S.StartStatic(
XO(
"Genres"));
343 S.StartMultiColumn(4, wxALIGN_CENTER);
351 S.StartStatic(
XO(
"Template"));
353 S.StartMultiColumn(4, wxALIGN_CENTER);
364 S.EndHorizontalLay();
365 S.StartHorizontalLay(wxALIGN_LEFT, 0);
367 S.Id(
DontShowID ).AddCheckBox(
XXO(
"Don't show this when exporting audio"), !bShow );
369 S.EndHorizontalLay();
378 bool bShow = !Evt.IsChecked();
379 gPrefs->Write(
wxT(
"/AudioFiles/ShowId3Dialog"), bShow );
390 int i, cnt =
mGrid->GetNumberRows();
392 if (
mGrid->IsCellEditControlShown()) {
393 mGrid->SaveEditControlValue();
394 mGrid->HideCellEditControl();
398 for (i = 0; i < cnt; i++) {
401 auto n =
mGrid->GetCellValue(i, 0);
402 wxString v =
mGrid->GetCellValue(i, 1);
408 bool bSpecialTag =
true;
414 else if (n.CmpNoCase(
LABEL_TITLE.Translation()) == 0) {
417 else if (n.CmpNoCase(
LABEL_ALBUM.Translation()) == 0) {
420 else if (n.CmpNoCase(
LABEL_TRACK.Translation()) == 0) {
423 else if (n.CmpNoCase(
LABEL_YEAR.Translation()) == 0) {
426 else if (n.CmpNoCase(
LABEL_GENRE.Translation()) == 0) {
451 if (
mGrid->GetNumberRows()) {
459 mGrid->SetReadOnly(i, 0);
467 mGrid->SetReadOnly(i, 1);
472 mGrid->SetReadOnly(i, 1);
480 const auto &n = pair.first;
481 const auto &v = pair.second;
482 if (popTagMap.find(n) == popTagMap.end()) {
484 mGrid->SetCellValue(i, 0, n);
485 mGrid->SetCellValue(i, 1, v);
491 mGrid->AppendRows(1);
506 static bool ischanging =
false;
515 if (event.GetCol() != 0) {
521 auto row =
event.GetRow();
522 const wxString
key0 =
mGrid->GetCellValue(row, 0).Upper();
523 auto nn =
mGrid->GetNumberRows();
524 for (
decltype(nn) ii = 0; ii < nn; ++ii) {
527 auto key =
mGrid->GetCellValue(ii, 0).Upper();
528 if (
key0.CmpNoCase(
key) == 0) {
531 mGrid->SetGridCursor(ii, 0);
543 if (
mGrid->IsCellEditControlShown()) {
544 mGrid->SaveEditControlValue();
545 mGrid->HideCellEditControl();
549 wxDefaultPosition, wxDefaultSize,
550 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
556 S.StartVerticalLay(
true);
558 tc =
S.AddTextWindow(
wxT(
""));
562 S.AddStandardButtons();
566 for (
int i = 0; i < cnt; i++) {
569 std::sort( g.begin(), g.end() );
571 for (
int i = 0; i < cnt; i++) {
572 tc->AppendText(g[i] +
wxT(
"\n"));
576 if (dlg.ShowModal() == wxID_CANCEL) {
581 wxFile f(
fn.GetFullPath(), wxFile::write);
582 if (!f.IsOpened() || !f.Write(tc->GetValue())) {
584 XO(
"Unable to save genre file."),
585 XO(
"Reset Genres") );
597 XO(
"Are you sure you want to reset the genre list to defaults?"),
607 wxTextFile tf(
fn.GetFullPath());
609 bool open = (tf.Exists() && tf.Open()) ||
610 (!tf.Exists() && tf.Create());
614 XO(
"Unable to open genre file."),
615 XO(
"Reset Genres") );
622 for (
int i = 0; i < cnt; i++) {
628 XO(
"Unable to save genre file."),
629 XO(
"Reset Genres") );
652 XO(
"Load Metadata As:"),
657 wxFD_OPEN | wxRESIZE_BORDER,
668 if (!reader.
Parse(&temp,
fn)) {
672 XO(
"Error Loading Metadata"),
710 XO(
"Save Metadata As:"),
715 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
741 auto cleanup =
finally( [&] {
784 const auto &n = pair.first;
785 const auto &v = pair.second;
808 size_t row =
mGrid->GetGridCursorRow();
815 mGrid->GetCellValue(row, 0)
820 mGrid->SetCellValue(row, 1, wxEmptyString);
823 mGrid->DeleteRows(row, 1);
829 if (
mGrid->IsCellEditControlShown()) {
830 mGrid->SaveEditControlValue();
831 mGrid->HideCellEditControl();
832#if defined(__WXMAC__)
846 wxRect r = GetRect();
847 gPrefs->Write(
wxT(
"/TagsEditorDialog/x"), r.x);
848 gPrefs->Write(
wxT(
"/TagsEditorDialog/y"), r.y);
849 gPrefs->Write(
wxT(
"/TagsEditorDialog/width"), r.width);
850 gPrefs->Write(
wxT(
"/TagsEditorDialog/height"), r.height);
863 if (
mGrid->IsCellEditControlShown()) {
864 auto editor =
mGrid->GetCellEditor(
mGrid->GetGridCursorRow(),
865 mGrid->GetGridCursorCol());
869 mGrid->HideCellEditControl();
870#if defined(__WXMSW__)
875 auto focus = wxWindow::FindFocus();
876 if (escKey && focus ==
mGrid)
879 EndModal(wxID_CANCEL);
884 if (event.GetKeyCode() == WXK_ESCAPE)
892 int cnt =
mGrid->GetNumberRows();
894 for (
int i = 0; i < cnt; i++) {
898 mGrid->SetCellEditor(i, 1,
mGrid->GetDefaultEditorForType(
wxT(
"Combo")));
901 mGrid->SetCellEditor(i, 1, NULL);
913 for (i = 0; i < cnt; i++) {
916 std::sort( g.begin(), g.end() );
918 for (i = 0; i < cnt; i++) {
919 parm = parm + (i == 0 ?
wxT(
"") :
wxT(
",")) + g[i];
924 auto editor =
mGrid->GetDefaultEditorForType(
wxT(
"Combo"));
925 editor->SetParameters(parm);
932 wxPoint topLeft(windowRect->GetTopLeft().x, windowRect->GetTopLeft().y);
933 wxPoint topRight(windowRect->GetTopRight().x, windowRect->GetTopRight().y);
934 wxPoint bottomLeft(windowRect->GetBottomLeft().x, windowRect->GetBottomLeft().y);
935 wxPoint bottomRight(windowRect->GetBottomRight().x, windowRect->GetBottomRight().y);
936 display.GetFromPoint(topLeft);
937 if (display.GetFromPoint(topLeft) == -1 &&
938 display.GetFromPoint(topRight) == -1 &&
939 display.GetFromPoint(bottomLeft) == -1 &&
940 display.GetFromPoint(bottomRight) == -1) {
964 auto newTags = tags.Duplicate();
968 if (tags != *newTags) {
974 gPrefs->Read(
wxT(
"/AudioFiles/ShowId3Dialog"), &bShowInFuture,
true);
975 settings.SetShowId3Dialog( bShowInFuture );
990 auto &project = context.
project;
992 XO(
"Edit Metadata Tags"),
XO(
"Metadata Tags"),
true);
R GuardedCall(const F1 &body, const F2 &handler=F2::Default(), F3 delayedHandler=DefaultDelayedHandlerAction) noexcept(noexcept(handler(std::declval< AudacityException * >())) &&noexcept(handler(nullptr)) &&noexcept(std::function< void(AudacityException *)>{std::move(delayedHandler)}))
Execute some code on any thread; catch any AudacityException; enqueue error report on the main thread...
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
static const AudacityProject::AttachedObjects::RegisteredFactory key
const ReservedCommandFlag & AudioIONotBusyFlag()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
EffectDistortionSettings params
XXO("&Cut/Copy/Paste Toolbar")
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
accessors for certain important windows associated with each project
FilePath SelectFile(FileNames::Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
static Settings & settings()
std::vector< TranslatableString > TranslatableStrings
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
void PaintBackground(wxDC &, const wxRect &WXUNUSED(rectCell), const wxGridCellAttr &WXUNUSED(attr)) override
ComboEditor(const wxArrayString &choices, bool allowOthers=false)
virtual void StartingKey(wxKeyEvent &event) override
void SetParameters(const wxString ¶ms) override
void SetSize(const wxRect &rectOrig) override
wxGridCellEditor * Clone() const override
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
virtual bool DeleteGroup(const wxString &key) wxOVERRIDE
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
FILES_API const FileType XMLFiles
Supplies an accessible grid based on wxGrid.
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
static ProjectHistory & Get(AudacityProject &project)
static ProjectSettings & Get(AudacityProject &project)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
Reads a file and passes the results through an XMLTagHandler.
const TranslatableString & GetErrorStr() const
bool Parse(XMLTagHandler *baseHandler, const FilePath &fname)
Wrapper to output XML data to files.
void SetName(const TranslatableString &title)
FILES_API FilePath DataDir()
Audacity user data directory.