Audacity 3.2.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
LabelDialog Class Referencefinal

Dialog for editing labels. More...

#include <LabelDialog.h>

Inheritance diagram for LabelDialog:
[legend]
Collaboration diagram for LabelDialog:
[legend]

Public Member Functions

 LabelDialog (wxWindow *parent, AudacityProject &project, TrackList *tracks, LabelTrack *selectedTrack, int index, ViewInfo &viewinfo, const NumericFormatID &format, const NumericFormatID &freqFormat)
 
 ~LabelDialog ()
 
bool Show (bool show=true) override
 
- Public Member Functions inherited from wxDialogWrapper
 wxDialogWrapper ()
 
 wxDialogWrapper (wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const TranslatableString &name=XO("Dialog"))
 
bool Create (wxWindow *parent, wxWindowID id, const TranslatableString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE, const TranslatableString &name=XO("Dialog"))
 
void SetTitle (const TranslatableString &title)
 
void SetLabel (const TranslatableString &title)
 
void SetName (const TranslatableString &title)
 
void SetName ()
 
- Public Member Functions inherited from wxTabTraversalWrapper< wxDialog >
 wxTabTraversalWrapper (Args &&... args)
 
 wxTabTraversalWrapper (const wxTabTraversalWrapper &)=delete
 
 wxTabTraversalWrapper (wxTabTraversalWrapper &&)=delete
 
wxTabTraversalWrapperoperator= (const wxTabTraversalWrapper &)=delete
 
wxTabTraversalWrapperoperator= (wxTabTraversalWrapper &&)=delete
 

Private Member Functions

void Populate ()
 Creates the dialog and its contents. More...
 
void PopulateOrExchange (ShuttleGui &S)
 
void PopulateLabels ()
 
void OnHelp (wxCommandEvent &event)
 
ManualPageID GetHelpPageName ()
 
bool TransferDataToWindow () override
 
bool TransferDataFromWindow () override
 
bool Validate () override
 
void FindAllLabels ()
 
void AddLabels (const LabelTrack *t)
 
void FindInitialRow ()
 
wxString TrackName (int &index, const wxString &dflt=_("Label Track"))
 
void OnUpdate (wxCommandEvent &event)
 
void OnFreqUpdate (wxCommandEvent &event)
 
void OnInsert (wxCommandEvent &event)
 
void OnRemove (wxCommandEvent &event)
 
void OnImport (wxCommandEvent &event)
 
void OnExport (wxCommandEvent &event)
 
void OnSelectCell (wxGridEvent &event)
 
void OnCellChange (wxGridEvent &event)
 
void OnChangeTrack (wxGridEvent &event, int row, RowData *rd)
 
void OnChangeLabel (wxGridEvent &event, int row, RowData *rd)
 
void OnChangeStime (wxGridEvent &event, int row, RowData *rd)
 
void OnChangeEtime (wxGridEvent &event, int row, RowData *rd)
 
void OnChangeLfreq (wxGridEvent &event, int row, RowData *rd)
 
void OnChangeHfreq (wxGridEvent &event, int row, RowData *rd)
 
void OnOK (wxCommandEvent &event)
 
void OnCancel (wxCommandEvent &event)
 
void ReadSize ()
 
void WriteSize ()
 

Private Attributes

AudacityProjectmProject
 
GridmGrid
 
ChoiceEditormChoiceEditor
 
NumericEditormTimeEditor
 
NumericEditormFrequencyEditor
 
RowDataArray mData
 
TrackListmTracks
 
LabelTrackmSelectedTrack {}
 
int mIndex { -1 }
 
ViewInfomViewInfo
 
wxArrayString mTrackNames
 
NumericFormatID mFormat
 
NumericFormatID mFreqFormat
 
int mInitialRow
 

Detailed Description

Dialog for editing labels.

Definition at line 35 of file LabelDialog.h.

Constructor & Destructor Documentation

◆ LabelDialog()

LabelDialog::LabelDialog ( wxWindow *  parent,
AudacityProject project,
TrackList tracks,
LabelTrack selectedTrack,
int  index,
ViewInfo viewinfo,
const NumericFormatID format,
const NumericFormatID freqFormat 
)

◆ ~LabelDialog()

LabelDialog::~LabelDialog ( )

Definition at line 120 of file LabelDialog.cpp.

121{
122}

Member Function Documentation

◆ AddLabels()

void LabelDialog::AddLabels ( const LabelTrack t)
private

Definition at line 467 of file LabelDialog.cpp.

468{
469 wxString lab;
470 int tndx = 0;
471 int i;
472
473 // Add a NEW track name
474 TrackName(tndx, t->GetName());
475
476 // If editor was invoked for one label, add that one only, else add all.
477 if (!mSelectedTrack || mSelectedTrack == t) {
478 for (i = 0; i < t->GetNumLabels(); i++) {
479 const LabelStruct *ls = t->GetLabel(i);
480
481 if (mIndex < 0 || mIndex == i)
482 mData.push_back(RowData(tndx, ls->title, ls->selectedRegion));
483 }
484 }
485}
wxString TrackName(int &index, const wxString &dflt=_("Label Track"))
LabelTrack * mSelectedTrack
Definition: LabelDialog.h:105
RowDataArray mData
Definition: LabelDialog.h:102
A LabelStruct holds information for ONE label in a LabelTrack.
Definition: LabelTrack.h:29
wxString title
Definition: LabelTrack.h:70
SelectedRegion selectedRegion
Definition: LabelTrack.h:69
int GetNumLabels() const
Definition: LabelTrack.cpp:965
const LabelStruct * GetLabel(int index) const
Definition: LabelTrack.cpp:970
const wxString & GetName() const
Name is always the same for all channels of a group.
Definition: Track.cpp:56

References LabelTrack::GetLabel(), Track::GetName(), LabelTrack::GetNumLabels(), mData, mIndex, mSelectedTrack, LabelStruct::selectedRegion, LabelStruct::title, and TrackName().

Referenced by FindAllLabels(), and OnImport().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindAllLabels()

void LabelDialog::FindAllLabels ( )
private

Definition at line 452 of file LabelDialog.cpp.

453{
454 // Add labels from all label tracks
455 for (auto lt : mTracks->Any<const LabelTrack>()) {
456 AddLabels(lt);
457 }
458
460
461 if (mData.size() == 0) {
462 wxCommandEvent e;
463 OnInsert(e);
464 }
465}
void AddLabels(const LabelTrack *t)
void FindInitialRow()
TrackList * mTracks
Definition: LabelDialog.h:104
void OnInsert(wxCommandEvent &event)
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:87
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1097

References AddLabels(), TrackList::Any(), FindInitialRow(), mData, mTracks, and OnInsert().

Referenced by PopulateLabels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindInitialRow()

void LabelDialog::FindInitialRow ( )
private

Definition at line 487 of file LabelDialog.cpp.

488{
489 int cnt = mData.size();
490 mInitialRow = -1;
491
492 if (cnt == 0)
493 return;
494
495 // find closest previous label
496
497 double distMin = std::numeric_limits<double>::max();
498 double dist;
499 double t0 = mViewInfo->selectedRegion.t0();
500 int i;
501 for (i = 0; i < cnt; i++)
502 {
503 dist = t0 - mData[i].selectedRegion.t0();
504 if (dist >= 0.0 && dist < distMin)
505 {
506 mInitialRow = i;
507 distMin = dist;
508 }
509 }
510
511 // if no previous label was found, find first label
512
513 if (mInitialRow == -1)
514 {
515 double t0Min = std::numeric_limits<double>::max();
516 for (i = 0; i < cnt; i++)
517 {
518 if (mData[i].selectedRegion.t0() < t0Min)
519 {
520 mInitialRow = i;
521 t0Min = mData[i].selectedRegion.t0();
522 }
523 }
524 }
525}
ViewInfo * mViewInfo
Definition: LabelDialog.h:107
double t0() const
Definition: ViewInfo.h:35
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:215

References mData, mInitialRow, mViewInfo, ViewInfo::selectedRegion, and NotifyingSelectedRegion::t0().

Referenced by FindAllLabels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetHelpPageName()

ManualPageID LabelDialog::GetHelpPageName ( )
inlineprivate

Definition at line 63 of file LabelDialog.h.

63{return "Labels_Editor";}

Referenced by OnHelp().

Here is the caller graph for this function:

◆ OnCancel()

void LabelDialog::OnCancel ( wxCommandEvent &  event)
private

Definition at line 935 of file LabelDialog.cpp.

936{
937 if (mGrid->IsCellEditControlShown()) {
938 auto editor = mGrid->GetCellEditor(mGrid->GetGridCursorRow(),
939 mGrid->GetGridCursorCol());
940 editor->Reset();
941 // To avoid memory leak, don't forget DecRef()!
942 editor->DecRef();
943 mGrid->HideCellEditControl();
944 return;
945 }
946
947 WriteSize();
948 // Standard handling
949 EndModal(wxID_CANCEL);
950
951 return;
952}
void WriteSize()
Grid * mGrid
Definition: LabelDialog.h:97

References mGrid, and WriteSize().

Here is the call graph for this function:

◆ OnCellChange()

void LabelDialog::OnCellChange ( wxGridEvent &  event)
private

Definition at line 758 of file LabelDialog.cpp.

759{
760 static bool guard = false;
761 int row = event.GetRow();
762
763 // Guard against recursion which can happen when a change to the "NEW label" row
764 // is made. When InsertRow() is done in TransferDataToWindow(), checks are made
765 // within wxGrid to see if the edit control is active and since it hasn't yet
766 // been marked inactive on the first time through here, we get entered again.
767 // Sort of a double change. I think this is probably a bug in wxGrid.
768 if (guard) {
769 return;
770 }
771 guard = true;
772
773 // The change was to an existing label, so go process it based
774 // on which column was changed.
775 RowData *rd = &mData[row];
776 switch (event.GetCol())
777 {
778 case Col_Track:
779 OnChangeTrack(event, row, rd);
780 break;
781
782 case Col_Label:
783 OnChangeLabel(event, row, rd);
784 break;
785
786 case Col_Stime:
787 OnChangeStime(event, row, rd);
788 break;
789
790 case Col_Etime:
791 OnChangeEtime(event, row, rd);
792 break;
793
794 case Col_Lfreq:
795 OnChangeLfreq(event, row, rd);
796 break;
797
798 case Col_Hfreq:
799 OnChangeHfreq(event, row, rd);
800 break;
801 }
802
803 // Done...no need for protection anymore
804 guard = false;
805
806 return;
807}
@ Col_Track
Definition: LabelDialog.cpp:47
@ Col_Label
Definition: LabelDialog.cpp:48
@ Col_Stime
Definition: LabelDialog.cpp:49
@ Col_Hfreq
Definition: LabelDialog.cpp:52
@ Col_Lfreq
Definition: LabelDialog.cpp:51
@ Col_Etime
Definition: LabelDialog.cpp:50
void OnChangeEtime(wxGridEvent &event, int row, RowData *rd)
void OnChangeTrack(wxGridEvent &event, int row, RowData *rd)
void OnChangeLabel(wxGridEvent &event, int row, RowData *rd)
void OnChangeLfreq(wxGridEvent &event, int row, RowData *rd)
void OnChangeStime(wxGridEvent &event, int row, RowData *rd)
void OnChangeHfreq(wxGridEvent &event, int row, RowData *rd)

References Col_Etime, Col_Hfreq, Col_Label, Col_Lfreq, Col_Stime, Col_Track, mData, OnChangeEtime(), OnChangeHfreq(), OnChangeLabel(), OnChangeLfreq(), OnChangeStime(), and OnChangeTrack().

Here is the call graph for this function:

◆ OnChangeEtime()

void LabelDialog::OnChangeEtime ( wxGridEvent &  event,
int  row,
RowData rd 
)
private

Definition at line 863 of file LabelDialog.cpp.

864{
865 // Remember the value...no need to repopulate
866 double t {};
867 mGrid->GetCellValue(row, Col_Etime).ToDouble(&t);
868 rd->selectedRegion.setT1(t, false);
869 mGrid->SetCellValue(row, Col_Stime, wxString::Format(wxT("%g"),
870 rd->selectedRegion.t0()));
871
872 return;
873}
wxT("CloseDown"))
SelectedRegion selectedRegion
Definition: LabelDialog.cpp:67
double t0() const
bool setT1(double t, bool maySwap=true)

References Col_Etime, Col_Stime, mGrid, RowData::selectedRegion, SelectedRegion::setT1(), SelectedRegion::t0(), and wxT().

Referenced by OnCellChange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnChangeHfreq()

void LabelDialog::OnChangeHfreq ( wxGridEvent &  event,
int  row,
RowData rd 
)
private

Definition at line 887 of file LabelDialog.cpp.

888{
889 // Remember the value...no need to repopulate
890 double f;
891 mGrid->GetCellValue(row, Col_Hfreq).ToDouble(&f);
892 rd->selectedRegion.setF1(f, false);
893 mGrid->SetCellValue(row, Col_Lfreq, wxString::Format(wxT("%g"),
894 rd->selectedRegion.f0()));
895
896 return;
897}

References Col_Hfreq, Col_Lfreq, mGrid, RowData::selectedRegion, and wxT().

Referenced by OnCellChange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnChangeLabel()

void LabelDialog::OnChangeLabel ( wxGridEvent &  event,
int  row,
RowData rd 
)
private

Definition at line 843 of file LabelDialog.cpp.

844{
845 // Remember the value...no need to repopulate
846 rd->title = mGrid->GetCellValue(row, Col_Label);
847
848 return;
849}
wxString title
Definition: LabelDialog.cpp:66

References Col_Label, mGrid, and RowData::title.

Referenced by OnCellChange().

Here is the caller graph for this function:

◆ OnChangeLfreq()

void LabelDialog::OnChangeLfreq ( wxGridEvent &  event,
int  row,
RowData rd 
)
private

Definition at line 875 of file LabelDialog.cpp.

876{
877 // Remember the value...no need to repopulate
878 double f;
879 mGrid->GetCellValue(row, Col_Lfreq).ToDouble(&f);
880 rd->selectedRegion.setF0(f, false);
881 mGrid->SetCellValue(row, Col_Hfreq, wxString::Format(wxT("%g"),
882 rd->selectedRegion.f1()));
883
884 return;
885}

References Col_Hfreq, Col_Lfreq, mGrid, RowData::selectedRegion, and wxT().

Referenced by OnCellChange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnChangeStime()

void LabelDialog::OnChangeStime ( wxGridEvent &  event,
int  row,
RowData rd 
)
private

Definition at line 851 of file LabelDialog.cpp.

852{
853 // Remember the value...no need to repopulate
854 double t {};
855 mGrid->GetCellValue(row, Col_Stime).ToDouble(&t);
856 rd->selectedRegion.setT0(t, false);
857 mGrid->SetCellValue(row, Col_Etime, wxString::Format(wxT("%g"),
858 rd->selectedRegion.t1()));
859
860 return;
861}
double t1() const
bool setT0(double t, bool maySwap=true)

References Col_Etime, Col_Stime, mGrid, RowData::selectedRegion, SelectedRegion::setT0(), SelectedRegion::t1(), and wxT().

Referenced by OnCellChange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnChangeTrack()

void LabelDialog::OnChangeTrack ( wxGridEvent &  event,
int  row,
RowData rd 
)
private

Definition at line 809 of file LabelDialog.cpp.

810{
811 wxString val = mGrid->GetCellValue(row, Col_Track);
812
813 // User selected the "New..." choice so ask for a NEW name
814 if ( make_iterator_range( mTrackNames ).index( val ) == 0 ) {
816 XO("New Label Track"),
817 XO("Enter track name"),
818 /* i18n-hint: (noun) it's the name of a kind of track.*/
819 XO("Label Track").Translation());
820
821 // User canceled so repopulating the grid will set the track
822 // name to the original value
823 if (d.ShowModal() == wxID_CANCEL) {
825 return;
826 }
827
828 // Force generation of a NEW track name
829 rd->index = 0;
830 TrackName(rd->index, d.GetValue());
831 }
832 else {
833 // Remember the tracks index
834 rd->index = make_iterator_range( mTrackNames ).index( val );
835 }
836
837 // Repopulate the grid
839
840 return;
841}
XO("Cut/Copy/Paste")
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210
Wrap wxTextEntryDialog so that caption IS translatable.
bool TransferDataToWindow() override
wxArrayString mTrackNames
Definition: LabelDialog.h:108

References Col_Track, RowData::index, make_iterator_range(), mGrid, mTrackNames, TrackName(), TransferDataToWindow(), and XO().

Referenced by OnCellChange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnExport()

void LabelDialog::OnExport ( wxCommandEvent &  event)
private

Definition at line 667 of file LabelDialog.cpp.

668{
669 int cnt = mData.size();
670
671 // Silly user (could just disable the button, but that's a hassle ;-))
672 if (cnt == 0) {
673 AudacityMessageBox( XO("No labels to export.") );
674 return;
675 }
676
677 // Extract the actual name.
678 wxString fName = mTrackNames[mTrackNames.size() - 1].AfterFirst(wxT('-')).Mid(1);
679
680 fName = SelectFile(FileNames::Operation::Export,
681 XO("Export Labels As:"),
682 wxEmptyString,
683 fName,
684 wxT("txt"),
686 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
687 this);
688
689 if (fName.empty())
690 return;
691
692 // Move existing files out of the way. Otherwise wxTextFile will
693 // append to (rather than replace) the current file.
694
695 if (wxFileExists(fName)) {
696#ifdef __WXGTK__
697 wxString safetyFileName = fName + wxT("~");
698#else
699 wxString safetyFileName = fName + wxT(".bak");
700#endif
701
702 if (wxFileExists(safetyFileName))
703 wxRemoveFile(safetyFileName);
704
705 wxRename(fName, safetyFileName);
706 }
707
708 wxTextFile f(fName);
709#ifdef __WXMAC__
710 wxFile{}.Create(fName);
711#else
712 f.Create();
713#endif
714 f.Open();
715 if (!f.IsOpened()) {
717 XO("Couldn't write to file: %s").Format( fName ) );
718 return;
719 }
720
721 // Transfer our collection to a temporary label track
722 auto lt = std::make_shared<LabelTrack>();
723 int i;
724
725 for (i = 0; i < cnt; i++) {
726 RowData &rd = mData[i];
727
728 lt->AddLabel(rd.selectedRegion, rd.title);
729 }
730
731 // Export them and clean
732 lt->Export(f);
733
734#ifdef __WXMAC__
735 f.Write(wxTextFileType_Mac);
736#else
737 f.Write();
738#endif
739 f.Close();
740}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
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)
Definition: SelectFile.cpp:17
FILES_API const FileType TextFiles
Definition: FileNames.h:73
Abstract base class used in importing a file.

References AudacityMessageBox(), mData, mTrackNames, RowData::selectedRegion, SelectFile(), FileNames::TextFiles, RowData::title, wxT(), and XO().

Here is the call graph for this function:

◆ OnFreqUpdate()

void LabelDialog::OnFreqUpdate ( wxCommandEvent &  event)
private

Definition at line 538 of file LabelDialog.cpp.

539{
540 // Remember the NEW format and repopulate grid
543 NumericConverterType_FREQUENCY(), event.GetString()).Internal();
545
546 event.Skip(false);
547}
const NumericConverterType & NumericConverterType_FREQUENCY()
const wxString & Internal() const
static FormatterContext ProjectContext(const AudacityProject &project)
NumericFormatID mFreqFormat
Definition: LabelDialog.h:109
AudacityProject & mProject
Definition: LabelDialog.h:95
NUMERIC_FORMATS_API NumericFormatSymbol Lookup(const FormatterContext &context, const NumericConverterType &type, const NumericFormatID &formatIdentifier)
Looks up the format, returns Default for the type if the format is not registered.

References ComponentInterfaceSymbol::Internal(), NumericConverterFormats::Lookup(), mFreqFormat, mProject, NumericConverterType_FREQUENCY(), FormatterContext::ProjectContext(), and TransferDataToWindow().

Here is the call graph for this function:

◆ OnHelp()

void LabelDialog::OnHelp ( wxCommandEvent &  event)
private

Definition at line 284 of file LabelDialog.cpp.

285{
286 const auto &page = GetHelpPageName();
287 HelpSystem::ShowHelp(this, page, true);
288}
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:231
ManualPageID GetHelpPageName()
Definition: LabelDialog.h:63

References GetHelpPageName(), and HelpSystem::ShowHelp().

Here is the call graph for this function:

◆ OnImport()

void LabelDialog::OnImport ( wxCommandEvent &  event)
private

Definition at line 627 of file LabelDialog.cpp.

628{
629 // Ask user for a filename
630 wxString fileName =
631 SelectFile(FileNames::Operation::Open,
632 XO("Select a text file containing labels"),
633 wxEmptyString, // Path
634 wxT(""), // Name
635 wxT("txt"), // Extension
637 wxRESIZE_BORDER, // Flags
638 this); // Parent
639
640 // They gave us one...
641 if (!fileName.empty()) {
642 wxTextFile f;
643
644 // Get at the data
645 f.Open(fileName);
646 if (!f.IsOpened()) {
648 XO("Could not open file: %s").Format( fileName ) );
649 }
650 else {
651 // Create a temporary label track and load the labels
652 // into it
653 auto lt = std::make_shared<LabelTrack>();
654 lt->Import(f);
655
656 // Add the labels to our collection
657 AddLabels(lt.get());
658
659 // Done with the temporary track
660 }
661
662 // Repopulate the grid
664 }
665}
FILES_API const FileType AllFiles
Definition: FileNames.h:70

References AddLabels(), FileNames::AllFiles, AudacityMessageBox(), SelectFile(), FileNames::TextFiles, TransferDataToWindow(), wxT(), and XO().

Here is the call graph for this function:

◆ OnInsert()

void LabelDialog::OnInsert ( wxCommandEvent &  event)
private

Definition at line 549 of file LabelDialog.cpp.

550{
551 int cnt = mData.size();
552 int row = 0;
553 int index = 0;
554
555 // Make sure the edit control isn't active before inserting any rows
556 if (mGrid->IsCellEditControlShown()) {
557 mGrid->HideCellEditControl();
558 }
559
560 // Attempt to guess which track the label should reside on
561 if (cnt > 0) {
562 row = mGrid->GetGridCursorRow();
563 if (row > 0 && row >= cnt) {
565 .index( mGrid->GetCellValue(row - 1, Col_Track) );
566 }
567 else {
569 .index( mGrid->GetCellValue(row, Col_Track) );
570 }
571 }
572
573 // Insert NEW label before or after the current row
574 if (event.GetId() == ID_INSERTA && row < cnt) {
575 row++;
576 }
577 mData.insert(mData.begin() + row, RowData(index, wxT(""), SelectedRegion()));
578
579 // Repopulate the grid
581
582 // Reposition cursor to NEW row/col and put user into edit mode to
583 // set the label name
584 mGrid->SetGridCursor(row, Col_Label);
585 mGrid->EnableCellEditControl(true);
586 mGrid->ShowCellEditControl();
587}
@ ID_INSERTA
Definition: LabelDialog.cpp:71
Defines a selected portion of a project.

References Col_Label, Col_Track, ID_INSERTA, make_iterator_range(), mData, mGrid, mTrackNames, TransferDataToWindow(), and wxT().

Referenced by FindAllLabels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnOK()

void LabelDialog::OnOK ( wxCommandEvent &  event)
private

Definition at line 918 of file LabelDialog.cpp.

919{
920 if (mGrid->IsCellEditControlShown()) {
921 mGrid->SaveEditControlValue();
922 mGrid->HideCellEditControl();
923 return;
924 }
925
926 // Standard handling
927 if (Validate() && TransferDataFromWindow()) {
928 WriteSize();
929 EndModal(wxID_OK);
930 }
931
932 return;
933}
bool Validate() override
bool TransferDataFromWindow() override

References mGrid, TransferDataFromWindow(), Validate(), and WriteSize().

Here is the call graph for this function:

◆ OnRemove()

void LabelDialog::OnRemove ( wxCommandEvent &  event)
private

Definition at line 589 of file LabelDialog.cpp.

590{
591 int row = mGrid->GetGridCursorRow();
592 int col = mGrid->GetGridCursorCol();
593 int cnt = mData.size();
594
595 // Don't try to remove if no labels exist
596 if (cnt == 0) {
597 return;
598 }
599
600 // Make sure the edit control isn't active before removing rows
601 if (mGrid->IsCellEditControlShown()) {
602 mGrid->HideCellEditControl();
603 }
604
605 // Remove the row
606 //RowData &rd = mData[row];
607 mData.erase(mData.begin() + row);
608
609 // Repopulate the grid
611
612 // Reposition the cursor
613 if (row > 0 && row >= --cnt) {
614 row--;
615 }
616 mGrid->SetGridCursor(row, col);
617
618 // Make sure focus isn't lost
619 if (mData.size() == 0 && wxWindow::FindFocus() == mGrid->GetGridWindow()) {
620 wxWindow *ok = wxWindow::FindWindowById( wxID_OK, this);
621 if (ok) {
622 ok->SetFocus();
623 }
624 }
625}
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:373

References BasicUI::FindFocus(), mData, mGrid, and TransferDataToWindow().

Here is the call graph for this function:

◆ OnSelectCell()

void LabelDialog::OnSelectCell ( wxGridEvent &  event)
private

Definition at line 742 of file LabelDialog.cpp.

743{
744 for (auto t: *mTracks)
745 t->SetSelected( true );
746
747 if (!mData.empty())
748 {
749 RowData &rd = mData[event.GetRow()];
751
753 }
754
755 event.Skip();
756}
void Redraw()
Definition: Viewport.cpp:748
static Viewport & Get(AudacityProject &project)
Definition: Viewport.cpp:32

References Viewport::Get(), mData, mProject, mTracks, mViewInfo, Viewport::Redraw(), ViewInfo::selectedRegion, and RowData::selectedRegion.

Here is the call graph for this function:

◆ OnUpdate()

void LabelDialog::OnUpdate ( wxCommandEvent &  event)
private

Definition at line 527 of file LabelDialog.cpp.

528{
529 // Remember the NEW format and repopulate grid
532 NumericConverterType_TIME(), event.GetString()).Internal();
534
535 event.Skip(false);
536}
const NumericConverterType & NumericConverterType_TIME()
NumericFormatID mFormat
Definition: LabelDialog.h:109

References ComponentInterfaceSymbol::Internal(), NumericConverterFormats::Lookup(), mFormat, mProject, NumericConverterType_TIME(), FormatterContext::ProjectContext(), and TransferDataToWindow().

Here is the call graph for this function:

◆ Populate()

void LabelDialog::Populate ( )
private

Creates the dialog and its contents.

Definition at line 211 of file LabelDialog.cpp.

212{
213
214 //------------------------- Main section --------------------
215 ShuttleGui S(this, eIsCreating);
217 // ----------------------- End of main section --------------
218
219 // Go populate the macros list.
221
222 // Layout the works
223 Layout();
224 //Fit();
225
226 // Resize width based on width of columns and the vertical scrollbar
227 wxRect r = mGrid->GetGridColLabelWindow()->GetRect();
228 wxScrollBar sb(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);
229 r.width += sb.GetSize().GetWidth() + 6;
230
231 // Add the size of the right column of buttons too...
232 wxWindow * w = FindWindowById( ID_IMPORT, this );
233 wxASSERT( w );
234 if( w )
235 r.width += w->GetSize().GetWidth();
236
237 SetClientSize(r.width, 300);
238
239 // Make sure it doesn't go below this size
240 r = GetRect();
241 SetSizeHints(r.GetWidth(), r.GetHeight());
242
243 // Bug 1465
244 // There might be a saved size, in which case use that.
245 ReadSize();
246
247 // Center on display
248 Center();
249}
@ ID_IMPORT
Definition: LabelDialog.cpp:74
@ eIsCreating
Definition: ShuttleGui.h:37
#define S(N)
Definition: ToChars.cpp:64
void PopulateLabels()
void PopulateOrExchange(ShuttleGui &S)
void ReadSize()
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640

References eIsCreating, ID_IMPORT, mGrid, PopulateLabels(), PopulateOrExchange(), ReadSize(), and S.

Here is the call graph for this function:

◆ PopulateLabels()

void LabelDialog::PopulateLabels ( )
private

Definition at line 124 of file LabelDialog.cpp.

125{
126 // Build the initial (empty) grid
127 mGrid->CreateGrid(0, Col_Max, wxGrid::wxGridSelectRows);
128 mGrid->SetDefaultCellAlignment(wxALIGN_LEFT, wxALIGN_CENTER);
129 mGrid->SetRowLabelSize(0);
130
131 size_t ii = 0;
132 for ( const auto &label : {
133 /* i18n-hint: (noun). A track contains waves, audio etc.*/
134 XO("Track"),
135 /* i18n-hint: (noun)*/
136 XO("Label"),
137 /* i18n-hint: (noun) of a label*/
138 XO("Start Time"),
139 /* i18n-hint: (noun) of a label*/
140 XO("End Time"),
141 /* i18n-hint: (noun) of a label*/
142 XO("Low Frequency"),
143 /* i18n-hint: (noun) of a label*/
144 XO("High Frequency"),
145 })
146 mGrid->SetColLabelValue( ii++, label.Translation() );
147
148 // Create and remember editors. No need to DELETE these as the wxGrid will
149 // do it for us. (The DecRef() that is needed after GetDefaultEditorForType
150 // becomes the duty of the wxGridCellAttr objects after we set them in the grid.)
151 mChoiceEditor = (ChoiceEditor *) mGrid->GetDefaultEditorForType(GRID_VALUE_CHOICE);
152 mTimeEditor = static_cast<NumericEditor*>
153 (mGrid->GetDefaultEditorForType(GRID_VALUE_TIME));
154 mFrequencyEditor = static_cast<NumericEditor *>
155 (mGrid->GetDefaultEditorForType(GRID_VALUE_FREQUENCY));
156
157 // Initialize and set the track name column attributes
158 wxGridCellAttr *attr;
159 mGrid->SetColAttr(Col_Track, (attr = safenew wxGridCellAttr));
160 attr->SetEditor(mChoiceEditor);
161 mTrackNames.push_back(_("New..."));
162
163 // Initialize and set the time column attributes
164 mGrid->SetColAttr(Col_Stime, (attr = safenew wxGridCellAttr));
165 // Don't need DecRef() after this GetDefaultRendererForType.
166 attr->SetRenderer(mGrid->GetDefaultRendererForType(GRID_VALUE_TIME));
167 attr->SetEditor(mTimeEditor);
168 attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
169
170 mGrid->SetColAttr(Col_Etime, attr->Clone());
171
172 // Initialize and set the frequency column attributes
173 mGrid->SetColAttr(Col_Lfreq, (attr = safenew wxGridCellAttr));
174 // Don't need DecRef() after this GetDefaultRendererForType.
175 attr->SetRenderer(mGrid->GetDefaultRendererForType(GRID_VALUE_FREQUENCY));
176 attr->SetEditor(mFrequencyEditor);
177 attr->SetAlignment(wxALIGN_CENTER, wxALIGN_CENTER);
178
179 mGrid->SetColAttr(Col_Hfreq, attr->Clone());
180
181 // Seems there's a bug in wxGrid. Adding only 1 row does not
182 // allow SetCellSize() to work properly and you will not get
183 // the expected 1 row by 4 column cell.
184 //
185 // So, we set the minimum row height to 0 and basically hide
186 // the extra row by setting its height to 0. And not allowing the
187 // rows to be manually resized prevents the user from ever seeing
188 // the extra row.
189 mGrid->SetRowMinimalAcceptableHeight(0);
190 mGrid->EnableDragRowSize(false);
191
192 // Locate all labels in current track list
194
195 // Populate the grid
197
198 // Resize the label name column and ensure it doesn't go below an
199 // arbitrary width.
200 //
201 // This should not be in TransferDataToWindow() since a user might
202 // resize the column and we'd resize it back to the minimum.
203 mGrid->AutoSizeColumn(Col_Label, false );
204 mGrid->SetColSize(Col_Label, wxMax(150, mGrid->GetColSize(Col_Label)));
205 mGrid->SetColMinimalWidth(Col_Label, mGrid->GetColSize(Col_Label));
206
207}
#define GRID_VALUE_TIME
Definition: Grid.h:36
#define GRID_VALUE_FREQUENCY
Definition: Grid.h:37
#define GRID_VALUE_CHOICE
Definition: Grid.h:123
#define _(s)
Definition: Internat.h:73
@ Col_Max
Definition: LabelDialog.cpp:53
#define safenew
Definition: MemoryX.h:9
TranslatableString label
Definition: TagsEditor.cpp:165
Modified version of wxGridChoiceEditor using wxChoice instead of wxComboBox.
Definition: Grid.h:127
ChoiceEditor * mChoiceEditor
Definition: LabelDialog.h:98
void FindAllLabels()
NumericEditor * mFrequencyEditor
Definition: LabelDialog.h:100
NumericEditor * mTimeEditor
Definition: LabelDialog.h:99
wxGridCellEditor for the NumericTextCtrl.
Definition: Grid.h:40
wxString Translation() const

References _, Col_Etime, Col_Hfreq, Col_Label, Col_Lfreq, Col_Max, Col_Stime, Col_Track, FindAllLabels(), GRID_VALUE_CHOICE, GRID_VALUE_FREQUENCY, GRID_VALUE_TIME, label, mChoiceEditor, mFrequencyEditor, mGrid, mTimeEditor, mTrackNames, safenew, TransferDataToWindow(), TranslatableString::Translation(), and XO().

Referenced by Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PopulateOrExchange()

void LabelDialog::PopulateOrExchange ( ShuttleGui S)
private

Definition at line 251 of file LabelDialog.cpp.

252{
253 S.AddFixedText(XO("Press F2 or double click to edit cell contents."));
254 S.StartHorizontalLay(wxEXPAND,1);
255 {
256 S.StartVerticalLay(wxEXPAND,1);
257 {
260 wxID_ANY);
261 S.Prop(1).AddWindow(mGrid);
262 }
263 S.EndVerticalLay();
264 S.StartVerticalLay(0);
265 {
266 //S.Id(ID_INSERTA).AddButton(XO("&Insert"), wxALIGN_LEFT);
267 S.Id(ID_INSERTB).AddButton(XXO("&Insert"), wxALIGN_LEFT);
268 //S.Id(EditButtonID).AddButton(XO("&Edit"), wxALIGN_LEFT);
269 S.Id(ID_REMOVE).AddButton(XXO("De&lete"), wxALIGN_LEFT);
270 S.Id(ID_IMPORT).AddButton(XXO("I&mport..."), wxALIGN_LEFT);
271 S.Id(ID_EXPORT).AddButton(XXO("&Export..."), wxALIGN_LEFT);
272 }
273 S.EndVerticalLay();
274 }
275 S.EndHorizontalLay();
276
277 S.StartHorizontalLay(wxALIGN_RIGHT, false);
278 {
279 S.AddStandardButtons( eOkButton | eCancelButton | eHelpButton);
280 }
281 S.EndHorizontalLay();
282}
XXO("&Cut/Copy/Paste Toolbar")
@ ID_INSERTB
Definition: LabelDialog.cpp:72
@ ID_REMOVE
Definition: LabelDialog.cpp:73
@ ID_EXPORT
Definition: LabelDialog.cpp:75
@ eOkButton
Definition: ShuttleGui.h:609
@ eCancelButton
Definition: ShuttleGui.h:610
@ eHelpButton
Definition: ShuttleGui.h:613
Supplies an accessible grid based on wxGrid.
Definition: Grid.h:190

References eCancelButton, eHelpButton, eOkButton, ID_EXPORT, ID_IMPORT, ID_INSERTB, ID_REMOVE, mGrid, mProject, FormatterContext::ProjectContext(), S, safenew, XO(), and XXO().

Referenced by Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadSize()

void LabelDialog::ReadSize ( )
private

Definition at line 899 of file LabelDialog.cpp.

899 {
900 wxSize sz = GetSize();
901 int prefWidth, prefHeight;
902 gPrefs->Read(wxT("/LabelEditor/Width"), &prefWidth, sz.x);
903 gPrefs->Read(wxT("/LabelEditor/Height"), &prefHeight, sz.y);
904
905 wxRect screenRect(wxGetClientDisplayRect());
906 wxSize prefSize = wxSize(prefWidth, prefHeight);
907 prefSize.DecTo(screenRect.GetSize());
908 SetSize(prefSize);
909}
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
virtual bool Read(const wxString &key, bool *value) const =0

References gPrefs, audacity::BasicSettings::Read(), and wxT().

Referenced by Populate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Show()

bool LabelDialog::Show ( bool  show = true)
override

Definition at line 351 of file LabelDialog.cpp.

352{
353 bool ret = wxDialogWrapper::Show(show);
354
355#if defined(__WXMAC__) || defined(__WXGTK__)
356 if (show) {
357 mGrid->SetFocus(); // Required for Linux and Mac.
358 }
359#endif
360
361 // Set initial row
362 // (This will not work until the grid is actually displayed)
363 if (show && mInitialRow != -1) {
364 mGrid->GoToCell(mInitialRow, Col_Label);
365 }
366
367 return ret;
368}
ExportResult Show(ExportTask exportTask)

References Col_Label, mGrid, mInitialRow, and ExportProgressUI::Show().

Here is the call graph for this function:

◆ TrackName()

wxString LabelDialog::TrackName ( int &  index,
const wxString &  dflt = _("Label Track") 
)
private

Definition at line 440 of file LabelDialog.cpp.

441{
442 // Generate a NEW track name if the passed index is out of range
443 if (index < 1 || index >= (int)mTrackNames.size()) {
444 index = mTrackNames.size();
445 mTrackNames.push_back(wxString::Format(wxT("%d - %s"), index, dflt));
446 }
447
448 // Return the track name
449 return mTrackNames[index];
450}

References mTrackNames, and wxT().

Referenced by AddLabels(), OnChangeTrack(), and TransferDataToWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TransferDataFromWindow()

bool LabelDialog::TransferDataFromWindow ( )
overrideprivate

Definition at line 370 of file LabelDialog.cpp.

371{
372 int cnt = mData.size();
373 int i;
374 int tndx = 0;
375
376 // Clear label tracks of labels
377 for (auto lt : mTracks->Any<LabelTrack>()) {
378 ++tndx;
379 if (!mSelectedTrack) {
380 for (i = lt->GetNumLabels() - 1; i >= 0 ; i--) {
381 lt->DeleteLabel(i);
382 }
383 }
384 else if (mSelectedTrack == lt && mIndex > -1) {
385 lt->DeleteLabel(mIndex);
386 }
387 else
388 // Do nothing to the nonselected tracks
389 ;
390 }
391
392 // Create any added tracks
393 while (tndx < (int)mTrackNames.size() - 1) {
394
395 // Extract the name
396 wxString name = mTrackNames[tndx + 1].AfterFirst(wxT('-')).Mid(1);
397
398 // Create the NEW track and add to track list
399 auto newTrack = std::make_shared<LabelTrack>();
400 newTrack->SetName(name);
401 mTracks->Add( newTrack );
402 tndx++;
403 }
404
405 // Repopulate with updated labels
406 for (i = 0; i < cnt; i++) {
407 RowData &rd = mData[i];
408
409 // Look for track with matching index
410 tndx = 1;
411 LabelTrack *lt{};
412 for (auto t : mTracks->Any<LabelTrack>()) {
413 lt = t;
414 if (rd.index == tndx++) {
415 break;
416 }
417 }
418 wxASSERT(lt);
419 if (!lt)
420 return false;
421
422 // Add the label to it
423 lt->AddLabel(rd.selectedRegion, rd.title);
425 }
426
427 return true;
428}
const TranslatableString name
Definition: Distortion.cpp:76
static LabelTrackView & Get(LabelTrack &)
TrackKind * Add(const std::shared_ptr< TrackKind > &t)
Definition: Track.h:1201

References TrackList::Add(), TrackList::Any(), LabelTrackView::Get(), RowData::index, mData, mIndex, mSelectedTrack, mTrackNames, mTracks, name, LabelTrackView::ResetTextSelection(), RowData::selectedRegion, RowData::title, and wxT().

Referenced by OnOK().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TransferDataToWindow()

bool LabelDialog::TransferDataToWindow ( )
overrideprivate

Definition at line 291 of file LabelDialog.cpp.

292{
293 int cnt = mData.size();
294 int i;
295
296 // Set the editor parameters. Do this each time since they may change
297 // due to NEW tracks and change in NumericTextCtrl format.
301
302 // Disable redrawing until we're done
303 mGrid->BeginBatch();
304
305 // Delete all rows
306 if (mGrid->GetNumberRows()) {
307 mGrid->DeleteRows(0, mGrid->GetNumberRows());
308 }
309
310 // Add the exact number that we'll need
311 mGrid->InsertRows(0, cnt);
312
313 // Populate the rows
314 for (i = 0; i < cnt; i++) {
315 RowData &rd = mData[i];
316
317 // Set the cell contents
318 mGrid->SetCellValue(i, Col_Track, TrackName(rd.index));
319 mGrid->SetCellValue(i, Col_Label, rd.title);
320 mGrid->SetCellValue(i, Col_Stime,
321 wxString::Format(wxT("%g"), rd.selectedRegion.t0()));
322 mGrid->SetCellValue(i, Col_Etime,
323 wxString::Format(wxT("%g"), rd.selectedRegion.t1()));
324 mGrid->SetCellValue(i, Col_Lfreq,
325 wxString::Format(wxT("%g"), rd.selectedRegion.f0()));
326 mGrid->SetCellValue(i, Col_Hfreq,
327 wxString::Format(wxT("%g"), rd.selectedRegion.f1()));
328 }
329
330 // Autosize all the rows
331 mGrid->AutoSizeRows(true);
332
333 // Resize the track name column. Use a wxChoice to determine the maximum
334 // width needed.
335 wxChoice tc(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, mTrackNames);
336 mGrid->SetColSize(Col_Track, tc.GetSize().x);
337 mGrid->SetColMinimalWidth(Col_Track, tc.GetSize().x);
338
339 // Autosize the time columns and set their minimal widths
340 mGrid->AutoSizeColumn(Col_Stime);
341 mGrid->AutoSizeColumn(Col_Etime);
342 mGrid->AutoSizeColumn(Col_Lfreq);
343 mGrid->AutoSizeColumn(Col_Hfreq);
344
345 // We're done, so allow the grid to redraw
346 mGrid->EndBatch();
347
348 return true;
349}
void SetChoices(const wxArrayString &choices)
Definition: Grid.cpp:442
void SetFormat(const NumericFormatID &format)
Definition: Grid.cpp:231

References Col_Etime, Col_Hfreq, Col_Label, Col_Lfreq, Col_Stime, Col_Track, RowData::index, mChoiceEditor, mData, mFormat, mFreqFormat, mFrequencyEditor, mGrid, mTimeEditor, mTrackNames, RowData::selectedRegion, ChoiceEditor::SetChoices(), NumericEditor::SetFormat(), SelectedRegion::t0(), SelectedRegion::t1(), RowData::title, TrackName(), and wxT().

Referenced by OnChangeTrack(), OnFreqUpdate(), OnImport(), OnInsert(), OnRemove(), OnUpdate(), and PopulateLabels().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Validate()

bool LabelDialog::Validate ( )
overrideprivate

Definition at line 430 of file LabelDialog.cpp.

431{
432 if (mGrid->IsCellEditControlShown()) {
433 mGrid->HideCellEditControl();
434 mGrid->SaveEditControlValue();
435 }
436
437 return true;
438}

References mGrid.

Referenced by OnOK().

Here is the caller graph for this function:

◆ WriteSize()

void LabelDialog::WriteSize ( )
private

Definition at line 911 of file LabelDialog.cpp.

911 {
912 wxSize sz = GetSize();
913 gPrefs->Write(wxT("/LabelEditor/Width"), sz.x);
914 gPrefs->Write(wxT("/LabelEditor/Height"), sz.y);
915 gPrefs->Flush();
916}
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0

References audacity::BasicSettings::Flush(), gPrefs, audacity::BasicSettings::Write(), and wxT().

Referenced by OnCancel(), and OnOK().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mChoiceEditor

ChoiceEditor* LabelDialog::mChoiceEditor
private

Definition at line 98 of file LabelDialog.h.

Referenced by PopulateLabels(), and TransferDataToWindow().

◆ mData

RowDataArray LabelDialog::mData
private

◆ mFormat

NumericFormatID LabelDialog::mFormat
private

Definition at line 109 of file LabelDialog.h.

Referenced by OnUpdate(), and TransferDataToWindow().

◆ mFreqFormat

NumericFormatID LabelDialog::mFreqFormat
private

Definition at line 109 of file LabelDialog.h.

Referenced by OnFreqUpdate(), and TransferDataToWindow().

◆ mFrequencyEditor

NumericEditor* LabelDialog::mFrequencyEditor
private

Definition at line 100 of file LabelDialog.h.

Referenced by PopulateLabels(), and TransferDataToWindow().

◆ mGrid

Grid* LabelDialog::mGrid
private

◆ mIndex

int LabelDialog::mIndex { -1 }
private

Definition at line 106 of file LabelDialog.h.

Referenced by AddLabels(), and TransferDataFromWindow().

◆ mInitialRow

int LabelDialog::mInitialRow
private

Definition at line 111 of file LabelDialog.h.

Referenced by FindInitialRow(), and Show().

◆ mProject

AudacityProject& LabelDialog::mProject
private

Definition at line 95 of file LabelDialog.h.

Referenced by OnFreqUpdate(), OnSelectCell(), OnUpdate(), and PopulateOrExchange().

◆ mSelectedTrack

LabelTrack* LabelDialog::mSelectedTrack {}
private

Definition at line 105 of file LabelDialog.h.

Referenced by AddLabels(), and TransferDataFromWindow().

◆ mTimeEditor

NumericEditor* LabelDialog::mTimeEditor
private

Definition at line 99 of file LabelDialog.h.

Referenced by PopulateLabels(), and TransferDataToWindow().

◆ mTrackNames

wxArrayString LabelDialog::mTrackNames
private

◆ mTracks

TrackList* LabelDialog::mTracks
private

Definition at line 104 of file LabelDialog.h.

Referenced by FindAllLabels(), OnSelectCell(), and TransferDataFromWindow().

◆ mViewInfo

ViewInfo* LabelDialog::mViewInfo
private

Definition at line 107 of file LabelDialog.h.

Referenced by FindInitialRow(), and OnSelectCell().


The documentation for this class was generated from the following files: