Audacity  3.0.3
Public Types | Public Member Functions | Static Public Member Functions | Private Attributes | Friends | List of all members
Tags Class Referencefinal

ID3 Tags (for MP3) More...

#include <Tags.h>

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

Public Types

using Iterators = IteratorRange< TagMap::const_iterator >
 

Public Member Functions

 Tags ()
 
 Tags (const Tags &)=default
 
virtual ~Tags ()
 
std::shared_ptr< TagsDuplicate () const
 
void Merge (const Tags &other)
 
Tagsoperator= (const Tags &src)
 
bool ShowEditDialog (wxWindow *parent, const TranslatableString &title, bool force=false)
 
bool HandleXMLTag (const wxChar *tag, const wxChar **attrs) override
 
XMLTagHandlerHandleXMLChild (const wxChar *tag) override
 
void WriteXML (XMLWriter &xmlFile) const
 
void AllowEditTitle (bool editTitle)
 
void AllowEditTrackNumber (bool editTrackNumber)
 
void LoadDefaultGenres ()
 
void LoadGenres ()
 
void LoadDefaults ()
 
int GetNumUserGenres ()
 
wxString GetUserGenre (int value)
 
wxString GetGenre (int value)
 
int GetGenre (const wxString &name)
 
bool HasTag (const wxString &name) const
 
wxString GetTag (const wxString &name) const
 
Iterators GetRange () const
 
void SetTag (const wxString &name, const wxString &value, const bool bSpecialTag=false)
 
void SetTag (const wxString &name, const int &value)
 
bool IsEmpty ()
 
void Clear ()
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual void HandleXMLEndTag (const wxChar *WXUNUSED(tag))
 
virtual void HandleXMLContent (const wxString &WXUNUSED(content))
 
bool ReadXMLTag (const char *tag, const char **attrs)
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 
- Public Member Functions inherited from ClientData::Base
virtual ~Base ()
 

Static Public Member Functions

static TagsGet (AudacityProject &project)
 
static const TagsGet (const AudacityProject &project)
 
static TagsSet (AudacityProject &project, const std::shared_ptr< Tags > &tags)
 

Private Attributes

TagMap mXref
 
TagMap mMap
 
wxArrayString mGenres
 
bool mEditTitle
 
bool mEditTrackNumber
 

Friends

bool operator== (const Tags &lhs, const Tags &rhs)
 

Detailed Description

ID3 Tags (for MP3)

This class started as an ID3 tag

This class holds a few informational tags, such as Title, Author, etc. that can be associated with a project or other audio file. It is modeled after the ID3 format for MP3 files, and it can both import and export ID3 tags from/to MP2, MP3, and AIFF files.

It can present the user with a dialog for editing this information.

Use of this functionality requires that libid3tag be compiled in with Audacity.

Definition at line 70 of file Tags.h.

Member Typedef Documentation

◆ Iterators

using Tags::Iterators = IteratorRange<TagMap::const_iterator>

Definition at line 119 of file Tags.h.

Constructor & Destructor Documentation

◆ Tags() [1/2]

Tags::Tags ( )

Definition at line 254 of file Tags.cpp.

255 {
256  mEditTitle = true;
257  mEditTrackNumber = true;
258 
259  LoadDefaults();
260  LoadGenres();
261 }

References LoadDefaults(), LoadGenres(), mEditTitle, and mEditTrackNumber.

Here is the call graph for this function:

◆ Tags() [2/2]

Tags::Tags ( const Tags )
default

◆ ~Tags()

Tags::~Tags ( )
virtual

Definition at line 263 of file Tags.cpp.

264 {
265 }

Member Function Documentation

◆ AllowEditTitle()

void Tags::AllowEditTitle ( bool  editTitle)

Definition at line 378 of file Tags.cpp.

379 {
380  mEditTitle = editTitle;
381 }

References mEditTitle.

◆ AllowEditTrackNumber()

void Tags::AllowEditTrackNumber ( bool  editTrackNumber)

Definition at line 383 of file Tags.cpp.

384 {
385  mEditTrackNumber = editTrackNumber;
386 }

References mEditTrackNumber.

◆ Clear()

void Tags::Clear ( )

Definition at line 337 of file Tags.cpp.

338 {
339  mXref.clear();
340  mMap.clear();
341 }

References mMap, and mXref.

Referenced by FLACImportFileHandle::Import(), OggImportFileHandle::Import(), MP3ImportFileHandle::LoadID3(), TagsEditorDialog::OnClear(), and TagsEditorDialog::TransferDataFromWindow().

Here is the caller graph for this function:

◆ Duplicate()

std::shared_ptr< Tags > Tags::Duplicate ( ) const

Definition at line 267 of file Tags.cpp.

268 {
269  return std::make_shared<Tags>(*this);
270 }

◆ Get() [1/2]

Tags & Tags::Get ( AudacityProject project)
static

Definition at line 237 of file Tags.cpp.

238 {
239  return project.AttachedObjects::Get< Tags >( key );
240 }

References key.

Referenced by Exporter::DoEditMetadata(), ExportCL::Export(), ExportMP3::Export(), ExportPCM::Export(), ExportMultipleDialog::ExportMultipleByLabel(), ExportMultipleDialog::ExportMultipleByTrack(), ExportOGG::FillComment(), Get(), ExportFLAC::GetMetadata(), ProjectFileManager::Import(), anonymous_namespace{ProjectFileManager.cpp}::ImportProject(), ExportFFmpeg::Init(), ProjectHistory::InitialState(), ProjectHistory::ModifyState(), and ProjectHistory::PushState().

Here is the caller graph for this function:

◆ Get() [2/2]

const Tags & Tags::Get ( const AudacityProject project)
static

Definition at line 242 of file Tags.cpp.

243 {
244  return Get( const_cast< AudacityProject & >( project ) );
245 }

References Get().

Here is the call graph for this function:

◆ GetGenre() [1/2]

int Tags::GetGenre ( const wxString &  name)

Definition at line 439 of file Tags.cpp.

440 {
441  int cnt = WXSIZEOF(DefaultGenres);
442 
443  for (int i = 0; i < cnt; i++) {
444  if (name.CmpNoCase(DefaultGenres[i])) {
445  return i;
446  }
447  }
448 
449  return 255;
450 }

References DefaultGenres, and name.

◆ GetGenre() [2/2]

wxString Tags::GetGenre ( int  value)

Definition at line 428 of file Tags.cpp.

429 {
430  int cnt = WXSIZEOF(DefaultGenres);
431 
432  if (i >= 0 && i < cnt) {
433  return DefaultGenres[i];
434  }
435 
436  return wxT("");
437 }

References DefaultGenres.

Referenced by PCMImportFileHandle::Import(), and MP3ImportFileHandle::LoadID3().

Here is the caller graph for this function:

◆ GetNumUserGenres()

int Tags::GetNumUserGenres ( )

Definition at line 388 of file Tags.cpp.

389 {
390  return mGenres.size();
391 }

References mGenres.

Referenced by GetUserGenre(), TagsEditorDialog::OnEdit(), TagsEditorDialog::OnReset(), and TagsEditorDialog::PopulateGenres().

Here is the caller graph for this function:

◆ GetRange()

Tags::Iterators Tags::GetRange ( ) const

Definition at line 481 of file Tags.cpp.

482 {
483  return { mMap.begin(), mMap.end() };
484 }

References mMap.

Referenced by ExportPCM::AddID3Chunk(), ExportMP3::AddTags(), ExportOGG::FillComment(), ExportCL::GetMetaChunk(), ExportFLAC::GetMetadata(), TagsEditorDialog::OnSaveDefaults(), and TagsEditorDialog::TransferDataToWindow().

Here is the caller graph for this function:

◆ GetTag()

wxString Tags::GetTag ( const wxString &  name) const

Definition at line 461 of file Tags.cpp.

462 {
463  wxString key = name;
464  key.UpperCase();
465 
466  auto iter = mXref.find(key);
467 
468  if (iter == mXref.end()) {
469  return wxEmptyString;
470  }
471 
472  auto iter2 = mMap.find(iter->second);
473  if (iter2 == mMap.end()) {
474  wxASSERT(false);
475  return wxEmptyString;
476  }
477  else
478  return iter2->second;
479 }

References key, mMap, mXref, and name.

Referenced by ExportPCM::AddStrings(), PCMImportFileHandle::Import(), MP3ImportFileHandle::LoadID3(), TagsEditorDialog::OnLoad(), TagsEditorDialog::OnSave(), TagsEditorDialog::OnSaveDefaults(), ExportFFmpeg::SetMetadata(), and TagsEditorDialog::TransferDataToWindow().

Here is the caller graph for this function:

◆ GetUserGenre()

wxString Tags::GetUserGenre ( int  value)

Definition at line 419 of file Tags.cpp.

420 {
421  if (i >= 0 && i < GetNumUserGenres()) {
422  return mGenres[i];
423  }
424 
425  return wxT("");
426 }

References GetNumUserGenres(), and mGenres.

Referenced by TagsEditorDialog::OnEdit(), TagsEditorDialog::OnReset(), and TagsEditorDialog::PopulateGenres().

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

◆ HandleXMLChild()

XMLTagHandler * Tags::HandleXMLChild ( const wxChar *  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 587 of file Tags.cpp.

588 {
589  if (wxStrcmp(tag, wxT("tags")) == 0) {
590  return this;
591  }
592 
593  if (wxStrcmp(tag, wxT("tag")) == 0) {
594  return this;
595  }
596 
597  return NULL;
598 }

◆ HandleXMLTag()

bool Tags::HandleXMLTag ( const wxChar *  tag,
const wxChar **  attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 546 of file Tags.cpp.

547 {
548  if (wxStrcmp(tag, wxT("tags")) == 0) {
549  return true;
550  }
551 
552  if (wxStrcmp(tag, wxT("tag")) == 0) {
553  wxString n, v;
554 
555  while (*attrs) {
556  wxString attr = *attrs++;
557  if (attr.empty())
558  break;
559  wxString value = *attrs++;
560 
561  if (!XMLValueChecker::IsGoodString(attr) ||
563  break;
564  }
565 
566  if (attr == wxT("name")) {
567  n = value;
568  }
569  else if (attr == wxT("value")) {
570  v = value;
571  }
572  }
573 
574  if (n == wxT("id3v2")) {
575  // LLL: This is obsolete, but it must be handled and ignored.
576  }
577  else {
578  SetTag(n, v);
579  }
580 
581  return true;
582  }
583 
584  return false;
585 }

References XMLValueChecker::IsGoodLongString(), XMLValueChecker::IsGoodString(), and SetTag().

Here is the call graph for this function:

◆ HasTag()

bool Tags::HasTag ( const wxString &  name) const

Definition at line 452 of file Tags.cpp.

453 {
454  wxString key = name;
455  key.UpperCase();
456 
457  auto iter = mXref.find(key);
458  return (iter != mXref.end());
459 }

References key, mXref, and name.

Referenced by ExportPCM::AddStrings(), FLACImportFileHandle::Import(), OggImportFileHandle::Import(), PCMImportFileHandle::Import(), IsEmpty(), MP3ImportFileHandle::LoadID3(), and ExportFFmpeg::SetMetadata().

Here is the caller graph for this function:

◆ IsEmpty()

bool Tags::IsEmpty ( )

Definition at line 326 of file Tags.cpp.

327 {
328  // At least one of these should be filled in, otherwise
329  // it's assumed that the tags have not been set...
331  return false;
332  }
333 
334  return true;
335 }

References HasTag(), TAG_ALBUM, TAG_ARTIST, and TAG_TITLE.

Referenced by FFmpegImportFileHandle::WriteMetadata().

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

◆ LoadDefaultGenres()

void Tags::LoadDefaultGenres ( )

Definition at line 393 of file Tags.cpp.

394 {
395  mGenres.clear();
396  for (size_t i = 0; i < WXSIZEOF(DefaultGenres); i++) {
397  mGenres.push_back(DefaultGenres[i]);
398  }
399 }

References DefaultGenres, and mGenres.

Referenced by LoadGenres(), and TagsEditorDialog::OnReset().

Here is the caller graph for this function:

◆ LoadDefaults()

void Tags::LoadDefaults ( )

Definition at line 295 of file Tags.cpp.

296 {
297  wxString path;
298  wxString name;
299  wxString value;
300  long ndx;
301  bool cont;
302 
303  // Set the parent group
304  path = gPrefs->GetPath();
305  gPrefs->SetPath(wxT("/Tags"));
306 
307  // Process all entries in the group
308  cont = gPrefs->GetFirstEntry(name, ndx);
309  while (cont) {
310  gPrefs->Read(name, &value, wxT(""));
311 
312  if (name == wxT("ID3V2")) {
313  // LLL: This is obsolute, but it must be handled and ignored.
314  }
315  else {
316  SetTag(name, value);
317  }
318 
319  cont = gPrefs->GetNextEntry(name, ndx);
320  }
321 
322  // Restore original group
323  gPrefs->SetPath(path);
324 }

References FileConfig::GetFirstEntry(), FileConfig::GetNextEntry(), FileConfig::GetPath(), gPrefs, name, FileConfig::SetPath(), and SetTag().

Referenced by Tags().

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

◆ LoadGenres()

void Tags::LoadGenres ( )

Definition at line 401 of file Tags.cpp.

402 {
403  wxFileName fn(FileNames::DataDir(), wxT("genres.txt"));
404  wxTextFile tf(fn.GetFullPath());
405 
406  if (!tf.Exists() || !tf.Open()) {
408  return;
409  }
410 
411  mGenres.clear();
412 
413  int cnt = tf.GetLineCount();
414  for (int i = 0; i < cnt; i++) {
415  mGenres.push_back(tf.GetLine(i));
416  }
417 }

References FileNames::DataDir(), fn, LoadDefaultGenres(), and mGenres.

Referenced by TagsEditorDialog::OnEdit(), TagsEditorDialog::OnReset(), and Tags().

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

◆ Merge()

void Tags::Merge ( const Tags other)

Definition at line 272 of file Tags.cpp.

273 {
274  for ( auto &pair : other.mMap ) {
275  SetTag( pair.first, pair.second );
276  }
277 }

References mMap, and SetTag().

Referenced by anonymous_namespace{ProjectFileManager.cpp}::ImportProject().

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

◆ operator=()

Tags & Tags::operator= ( const Tags src)

Definition at line 279 of file Tags.cpp.

280 {
281  mEditTitle = src.mEditTitle;
283 
284  mXref.clear();
285  mXref = src.mXref;
286  mMap.clear();
287  mMap = src.mMap;
288 
289  mGenres.clear();
290  mGenres = src.mGenres;
291 
292  return *this;
293 }

References mEditTitle, mEditTrackNumber, mGenres, mMap, and mXref.

◆ Set()

Tags & Tags::Set ( AudacityProject project,
const std::shared_ptr< Tags > &  tags 
)
static

Definition at line 247 of file Tags.cpp.

248 {
249  auto &result = *tags;
250  project.AttachedObjects::Assign( key, tags );
251  return result;
252 }

References key.

Referenced by Exporter::DoEditMetadata(), ProjectFileManager::Import(), and ProjectHistory::PopState().

Here is the caller graph for this function:

◆ SetTag() [1/2]

void Tags::SetTag ( const wxString &  name,
const int &  value 
)

Definition at line 541 of file Tags.cpp.

542 {
543  SetTag(name, wxString::Format(wxT("%d"), value));
544 }

References name, and SetTag().

Here is the call graph for this function:

◆ SetTag() [2/2]

void Tags::SetTag ( const wxString &  name,
const wxString &  value,
const bool  bSpecialTag = false 
)

Definition at line 486 of file Tags.cpp.

487 {
488  // We don't like empty names
489  if (name.empty()) {
490  return;
491  }
492 
493  // Tag name must be ascii
494  if (!name.IsAscii()) {
495  wxLogError("Tag rejected (Non-ascii character in name)");
496  return;
497  }
498 
499  // All keys are uppercase
500  wxString key = name;
501  key.UpperCase();
502 
503  // Look it up
504  TagMap::iterator iter = mXref.find(key);
505 
506  // The special tags, if empty, should not exist.
507  // However it is allowable for a custom tag to be empty.
508  // See Bug 440 and Bug 1382
509  if (value.empty() && bSpecialTag) {
510  // Erase the tag
511  if (iter == mXref.end())
512  // nothing to do
513  ;
514  else {
515  mMap.erase(iter->second);
516  mXref.erase(iter);
517  }
518  }
519  else
520  {
521  if (iter == mXref.end()) {
522  // Didn't find the tag
523 
524  // Add a NEW tag
525  mXref[key] = name;
526  mMap[name] = value;
527  }
528  else if (iter->second != name) {
529  // Watch out for case differences!
530  mMap[name] = value;
531  mMap.erase(iter->second);
532  iter->second = name;
533  }
534  else {
535  // Update the value
536  mMap[iter->second] = value;
537  }
538  }
539 }

References key, mMap, mXref, and name.

Referenced by FFmpegImportFileHandle::GetMetadata(), AUPImportFileHandle::HandleTag(), AUPImportFileHandle::HandleTags(), HandleXMLTag(), FLACImportFileHandle::Import(), OggImportFileHandle::Import(), PCMImportFileHandle::Import(), LoadDefaults(), MP3ImportFileHandle::LoadID3(), Merge(), TagsEditorDialog::OnLoad(), TagsEditorDialog::OnSave(), TagsEditorDialog::OnSaveDefaults(), GStreamerImportFileHandle::OnTag(), SetTag(), and TagsEditorDialog::TransferDataFromWindow().

Here is the caller graph for this function:

◆ ShowEditDialog()

bool Tags::ShowEditDialog ( wxWindow *  parent,
const TranslatableString title,
bool  force = false 
)

Definition at line 617 of file Tags.cpp.

618 {
619  if (force) {
620  TagsEditorDialog dlg(parent, title, this, mEditTitle, mEditTrackNumber);
621 
622  return dlg.ShowModal() == wxID_OK;
623  }
624 
625  return true;
626 }

References mEditTitle, mEditTrackNumber, and title.

◆ WriteXML()

void Tags::WriteXML ( XMLWriter xmlFile) const

Definition at line 600 of file Tags.cpp.

602 {
603  xmlFile.StartTag(wxT("tags"));
604 
605  for (const auto &pair : GetRange()) {
606  const auto &n = pair.first;
607  const auto &v = pair.second;
608  xmlFile.StartTag(wxT("tag"));
609  xmlFile.WriteAttr(wxT("name"), n);
610  xmlFile.WriteAttr(wxT("value"), v);
611  xmlFile.EndTag(wxT("tag"));
612  }
613 
614  xmlFile.EndTag(wxT("tags"));
615 }

Referenced by TagsEditorDialog::OnSave().

Here is the caller graph for this function:

Friends And Related Function Documentation

◆ operator==

bool operator== ( const Tags lhs,
const Tags rhs 
)
friend

Definition at line 361 of file Tags.cpp.

362 {
363  if (!EqualMaps(lhs.mXref, rhs.mXref))
364  return false;
365 
366  if (!EqualMaps(lhs.mMap, rhs.mMap))
367  return false;
368 
369  return
370  lhs.mGenres == rhs.mGenres
371  &&
372  lhs.mEditTitle == rhs.mEditTitle
373  &&
375  ;
376 }

Member Data Documentation

◆ mEditTitle

bool Tags::mEditTitle
private

Definition at line 136 of file Tags.h.

Referenced by AllowEditTitle(), operator=(), operator==(), ShowEditDialog(), and Tags().

◆ mEditTrackNumber

bool Tags::mEditTrackNumber
private

Definition at line 137 of file Tags.h.

Referenced by AllowEditTrackNumber(), operator=(), operator==(), ShowEditDialog(), and Tags().

◆ mGenres

wxArrayString Tags::mGenres
private

◆ mMap

TagMap Tags::mMap
private

Definition at line 132 of file Tags.h.

Referenced by Clear(), GetRange(), GetTag(), Merge(), operator=(), operator==(), and SetTag().

◆ mXref

TagMap Tags::mXref
private

Definition at line 131 of file Tags.h.

Referenced by Clear(), GetTag(), HasTag(), operator=(), operator==(), and SetTag().


The documentation for this class was generated from the following files:
XMLWriter::EndTag
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:99
FileConfig::SetPath
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:93
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: Tags.cpp:233
Tags::LoadDefaultGenres
void LoadDefaultGenres()
Definition: Tags.cpp:393
Tags::mEditTrackNumber
bool mEditTrackNumber
Definition: Tags.h:137
fn
static const auto fn
Definition: WaveformView.cpp:1113
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
Tags::HasTag
bool HasTag(const wxString &name) const
Definition: Tags.cpp:452
Tags
ID3 Tags (for MP3)
Definition: Tags.h:74
Tags::GetRange
Iterators GetRange() const
Definition: Tags.cpp:481
Tags::LoadGenres
void LoadGenres()
Definition: Tags.cpp:401
Tags::mXref
TagMap mXref
Definition: Tags.h:131
FileConfig::GetFirstEntry
virtual bool GetFirstEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:113
XMLValueChecker::IsGoodString
static bool IsGoodString(const wxString &str)
Definition: XMLTagHandler.cpp:38
FileConfig::GetNextEntry
virtual bool GetNextEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:118
Tags::Get
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:237
FileNames::DataDir
FILES_API FilePath DataDir()
Audacity user data directory.
Tags::mEditTitle
bool mEditTitle
Definition: Tags.h:136
DefaultGenres
static const wxChar * DefaultGenres[]
Definition: Tags.cpp:73
Tags::SetTag
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:486
anonymous_namespace{Tags.cpp}::EqualMaps
bool EqualMaps(const TagMap &map1, const TagMap &map2)
Definition: Tags.cpp:344
Tags::mGenres
wxArrayString mGenres
Definition: Tags.h:134
Tags::mMap
TagMap mMap
Definition: Tags.h:132
TagsEditorDialog
Derived from ExpandingToolBar, this dialog allows editing of Tags.
Definition: Tags.h:144
Tags::GetNumUserGenres
int GetNumUserGenres()
Definition: Tags.cpp:388
title
static const auto title
Definition: NoUpdatesAvailableDialog.cpp:22
XMLValueChecker::IsGoodLongString
static bool IsGoodLongString(const wxString &str)
Definition: XMLTagHandler.cpp:51
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
Tags::LoadDefaults
void LoadDefaults()
Definition: Tags.cpp:295
XMLWriter::WriteAttr
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:34
TAG_ARTIST
#define TAG_ARTIST
Definition: Tags.h:61
name
wxString name
Definition: Tags.cpp:757
XMLWriter::StartTag
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:76
TAG_TITLE
#define TAG_TITLE
Definition: Tags.h:60
FileConfig::GetPath
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:98
TAG_ALBUM
#define TAG_ALBUM
Definition: Tags.h:62