Audacity  2.2.2
Public Member Functions | Private Member Functions | Private Attributes | List of all members
LOFImportFileHandle Class Referencefinal

An ImportFileHandle for LOF data. More...

Inheritance diagram for LOFImportFileHandle:
ImportFileHandle

Public Member Functions

 LOFImportFileHandle (const wxString &name, std::unique_ptr< wxTextFile > &&file)
 
 ~LOFImportFileHandle ()
 
wxString GetFileDescription () override
 
ByteCount GetFileUncompressedBytes () override
 
ProgressResult Import (TrackFactory *trackFactory, TrackHolders &outTracks, Tags *tags) override
 
wxInt32 GetStreamCount () override
 
const wxArrayString & GetStreamInfo () override
 
void SetStreamUsage (wxInt32 WXUNUSED(StreamID), bool WXUNUSED(Use)) override
 
- Public Member Functions inherited from ImportFileHandle
 ImportFileHandle (const wxString &filename)
 
virtual ~ImportFileHandle ()
 
void CreateProgress ()
 
virtual void SetStreamUsage (wxInt32 StreamID, bool Use)=0
 

Private Member Functions

void lofOpenFiles (wxString *ln)
 Processes a single line from a LOF text file, doing whatever is indicated on the line. More...
 
void doDurationAndScrollOffset ()
 

Private Attributes

std::unique_ptr< wxTextFile > mTextFile
 
wxFileName mLOFFileName
 
AudacityProjectmProject { GetActiveProject() }
 
bool windowCalledOnce { false }
 
bool callDurationFactor { false }
 
double durationFactor { 1 }
 
bool callScrollOffset { false }
 
double scrollOffset { 0 }
 

Additional Inherited Members

- Public Types inherited from ImportFileHandle
using ByteCount = unsigned long long
 
- Protected Attributes inherited from ImportFileHandle
wxString mFilename
 
Maybe< ProgressDialogmProgress
 

Detailed Description

An ImportFileHandle for LOF data.

Supports the opening of ".lof" files which are text files that contain a list of individual files to open in audacity in specific formats. Files may be file names (in the same directory as the LOF file), absolute paths or relative paths relative to the directory of the LOF file.

(In BNF) The syntax for an LOF file, denoted by <lof>:

  <lof> ::= [<window> | <file> | <#>]*
  <window> ::= window [<window-parameter>]* <newline>
  <window-parameter> ::= offset <time> | duration <time>
  <time> ::= [<digit>]+ [ . [<digit>]* ]
  <file> ::= file [<file-parameter>]* <newline>
  <file-parameter> ::= offset <time>
  <#> ::= <comment> <newline>

EXAMPLE LOF file:

  # everything following the hash character is ignored
  window # an initial window command is implicit and optional
  file "C:\folder1\sample1.wav"    # sample1.wav is displayed
  file "C:\sample2.wav" offset 5   # sample2 is displayed with a 5s offset
  File "C:\sample3.wav"            # sample3 is displayed with no offset
  File "foo.aiff" # foo is loaded from the same directory as the LOF file
  window offset 5 duration 10      # open a NEW window, zoom to display
  # 10 seconds total starting at 5 (ending at 15) seconds
  file "C:\sample3.wav" offset 2.5

SEMANTICS:

There are two commands: "window" creates a NEW window, and "file" appends a track to the current window and displays the file there. The first file is always placed in a NEW window, whether or not an initial "window" command is given.

Commands have optional keyword parameters that may be listed in any order. A parameter should only occur once per command. The "offset" parameter specifies a time offset. For windows, this is the leftmost time displayed in the window. For files, the offset is an amount by which the file is shifted in time before display (only enabled for audio; not midi). The offset is specified as an integer or decimal number of seconds, and the default value is zero.

Windows may also have a "duration" parameter, which specifies how much time should be displayed in the window. The default duration is equal to the duration of the longest track currently displayed.

Definition at line 119 of file ImportLOF.cpp.

Constructor & Destructor Documentation

LOFImportFileHandle::LOFImportFileHandle ( const wxString &  name,
std::unique_ptr< wxTextFile > &&  file 
)

Definition at line 164 of file ImportLOF.cpp.

166  mTextFile(std::move(file))
167  , mLOFFileName{name}
168 {
169 }
ImportFileHandle(const wxString &filename)
Definition: ImportPlugin.h:122
std::unique_ptr< wxTextFile > mTextFile
Definition: ImportLOF.cpp:146
const wxChar * name
Definition: Distortion.cpp:94
wxFileName mLOFFileName
Definition: ImportLOF.cpp:147
LOFImportFileHandle::~LOFImportFileHandle ( )

Definition at line 517 of file ImportLOF.cpp.

518 {
519 }

Member Function Documentation

void LOFImportFileHandle::doDurationAndScrollOffset ( )
private

Definition at line 493 of file ImportLOF.cpp.

References callDurationFactor, callScrollOffset, durationFactor, TrackList::GetEndTime(), AudacityProject::GetTracks(), mProject, scrollOffset, AudacityProject::TP_ModifyState(), AudacityProject::TP_ScrollWindow(), and AudacityProject::ZoomBy().

Referenced by Import(), and lofOpenFiles().

494 {
495  if (!mProject)
496  return;
497 
498  bool doSomething = callDurationFactor || callScrollOffset;
499  if (callDurationFactor)
500  {
501  double longestDuration = mProject->GetTracks()->GetEndTime();
502  mProject->ZoomBy(longestDuration / durationFactor);
503  callDurationFactor = false;
504  }
505 
506  if (callScrollOffset && (scrollOffset != 0))
507  {
509  callScrollOffset = false;
510  }
511 
512  if (doSomething)
513  // Amend last undo state
514  mProject->TP_ModifyState(false);
515 }
double GetEndTime() const
Definition: Track.cpp:1418
AudacityProject * mProject
Definition: ImportLOF.cpp:149
void ZoomBy(double multiplier)
Definition: Project.cpp:4953
void TP_ScrollWindow(double scrollto) override
Definition: Project.cpp:1856
void TP_ModifyState(bool bWantsAutoSave) override
Definition: Project.cpp:5420
TrackList * GetTracks()
Definition: Project.h:192
wxString LOFImportFileHandle::GetFileDescription ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 216 of file ImportLOF.cpp.

References DESC.

217 {
218  return DESC;
219 }
#define DESC
Definition: ImportLOF.cpp:96
auto LOFImportFileHandle::GetFileUncompressedBytes ( )
overridevirtual

Implements ImportFileHandle.

Definition at line 221 of file ImportLOF.cpp.

222 {
223  return 0;
224 }
wxInt32 LOFImportFileHandle::GetStreamCount ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 130 of file ImportLOF.cpp.

130 { return 1; }
const wxArrayString& LOFImportFileHandle::GetStreamInfo ( )
inlineoverridevirtual

Implements ImportFileHandle.

Definition at line 132 of file ImportLOF.cpp.

133  {
134  static wxArrayString empty;
135  return empty;
136  }
ProgressResult LOFImportFileHandle::Import ( TrackFactory trackFactory,
TrackHolders outTracks,
Tags tags 
)
overridevirtual

Implements ImportFileHandle.

Definition at line 226 of file ImportLOF.cpp.

References doDurationAndScrollOffset(), Failed, lofOpenFiles(), mTextFile, and Success.

228 {
229  // Unlike other ImportFileHandle subclasses, this one never gives any tracks
230  // back to the caller.
231  // Instead, it recursively calls AudacityProject::Import for each file listed
232  // in the .lof file.
233  // Each importation creates a NEW undo state.
234  // If there is an error or exception during one of them, only that one's
235  // side effects are rolled back, and the rest of the import list is skipped.
236  // The file may have "window" directives that cause NEW AudacityProjects
237  // to be created, and the undo states are pushed onto the latest project.
238  // If a project is created but the first file import into it fails, destroy
239  // the project.
240 
241  outTracks.clear();
242 
243  wxASSERT(mTextFile->IsOpened());
244 
245  if(mTextFile->Eof())
246  {
247  mTextFile->Close();
248  return ProgressResult::Failed;
249  }
250 
251  wxString line = mTextFile->GetFirstLine();
252 
253  while (!mTextFile->Eof())
254  {
255  lofOpenFiles(&line);
256  line = mTextFile->GetNextLine();
257  }
258 
259  // for last line
260  lofOpenFiles(&line);
261 
262  if(!mTextFile->Close())
263  return ProgressResult::Failed;
264 
265  // set any duration/offset factors for last window, as all files were called
267 
269 }
void lofOpenFiles(wxString *ln)
Processes a single line from a LOF text file, doing whatever is indicated on the line.
Definition: ImportLOF.cpp:293
void doDurationAndScrollOffset()
Definition: ImportLOF.cpp:493
std::unique_ptr< wxTextFile > mTextFile
Definition: ImportLOF.cpp:146
void LOFImportFileHandle::lofOpenFiles ( wxString *  ln)
private

Processes a single line from a LOF text file, doing whatever is indicated on the line.

This function should just return for lines it cannot deal with, and the caller will continue to the next line of the input file

Definition at line 293 of file ImportLOF.cpp.

References _(), AudacityMessageBox(), callDurationFactor, callScrollOffset, Internat::CompatibleToDouble(), CountNumTracks(), doDurationAndScrollOffset(), AudacityProject::DoImportMIDI(), durationFactor, AudacityProject::GetTracks(), Importer::IsMidi(), mLOFFileName, mProject, AudacityProject::OpenProject(), scrollOffset, AudacityProject::TP_ModifyState(), and windowCalledOnce.

Referenced by Import().

294 {
295  wxStringTokenizer tok(*ln, wxT(" "));
296  wxStringTokenizer temptok1(*ln, wxT("\""));
297  wxStringTokenizer temptok2(*ln, wxT(" "));
298  int tokenplace = 0;
299 
300  wxString targetfile;
301  wxString tokenholder = tok.GetNextToken();
302 
303  if (tokenholder.IsSameAs(wxT("window"), false))
304  {
305  // set any duration/offset factors for last window, as all files were called
307 
308  if (windowCalledOnce)
309  // Cause a project to be created with the next import
310  mProject = nullptr;
311  else
312  // Apply any offset and duration directives of the first "window" line
313  // to the previously open project, not a NEW one.
314  ;
315 
316  windowCalledOnce = true;
317 
318  while (tok.HasMoreTokens())
319  {
320  tokenholder = tok.GetNextToken();
321 
322  if (tokenholder.IsSameAs(wxT("offset"), false))
323  {
324  if (tok.HasMoreTokens())
325  tokenholder = tok.GetNextToken();
326 
327  if (Internat::CompatibleToDouble(tokenholder, &scrollOffset))
328  {
329  callScrollOffset = true;
330  }
331  else
332  {
333  /* i18n-hint: You do not need to translate "LOF" */
334  AudacityMessageBox(_("Invalid window offset in LOF file."),
335  /* i18n-hint: You do not need to translate "LOF" */
336  _("LOF Error"), wxOK | wxCENTRE);
337  }
338 
339  if (tok.HasMoreTokens())
340  tokenholder = tok.GetNextToken();
341  }
342 
343  if (tokenholder.IsSameAs(wxT("duration"), false))
344  {
345  if (tok.HasMoreTokens())
346  tokenholder = tok.GetNextToken();
347 
348  if (Internat::CompatibleToDouble(tokenholder, &durationFactor))
349  {
350  callDurationFactor = true;
351  }
352  else
353  {
354  /* i18n-hint: You do not need to translate "LOF" */
355  AudacityMessageBox(_("Invalid duration in LOF file."),
356  /* i18n-hint: You do not need to translate "LOF" */
357  _("LOF Error"), wxOK | wxCENTRE);
358  }
359  } // End if statement
360 
361  if (tokenholder.IsSameAs(wxT("#")))
362  {
363  // # indicates comments; ignore line
364  tok = wxStringTokenizer(wxT(""), wxT(" "));
365  }
366  } // End while loop
367  } // End if statement handling "window" lines
368 
369  else if (tokenholder.IsSameAs(wxT("file"), false))
370  {
371 
372  // To identify filename and open it
373  tokenholder = temptok1.GetNextToken();
374  wxString targettoken = temptok1.GetNextToken();
375  targetfile = targettoken;
376 
377  // If path is relative, make absolute path from LOF path
378  if(!wxIsAbsolutePath(targetfile)) {
379  wxFileName fName(targetfile);
380  fName.Normalize(wxPATH_NORM_ALL, mLOFFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
381  if(fName.FileExists()) {
382  targetfile = fName.GetFullPath();
383  }
384  }
385 
386  // Do recursive call to import
387 
388 #ifdef USE_MIDI
389  // If file is a midi
390  if (Importer::IsMidi(targetfile))
391  {
393  }
394 
395  // If not a midi, open audio file
396  else
397 
398 #else // !USE_MIDI
399  /* if we don't have midi support, go straight on to opening as an
400  * audio file. TODO: Some sort of message here? */
401 
402 #endif // USE_MIDI
404 
405  // Set tok to right after filename
406  temptok2.SetString(targettoken);
407  tokenplace = temptok2.CountTokens();
408 
409  for (int i = 0; i < tokenplace; i++)
410  tokenholder = tok.GetNextToken();
411 
412  if (tok.HasMoreTokens())
413  {
414  tokenholder = tok.GetNextToken();
415 
416  if (tokenholder.IsSameAs(wxT("#")))
417  {
418  // # indicates comments; ignore line
419  tok = wxStringTokenizer(wxT(""), wxT(" "));
420  }
421 
422  if (tokenholder.IsSameAs(wxT("offset"), false))
423  {
424  if (tok.HasMoreTokens())
425  tokenholder = tok.GetNextToken();
426  double offset;
427 
428  // handle an "offset" specifier
429  if (!mProject)
430  // there was an import error,
431  // presumably with its own error message
432  ;
433  else if (Internat::CompatibleToDouble(tokenholder, &offset))
434  {
435  Track *t;
437 
438  t = iter.First();
439 
440  for (int i = 1; i < CountNumTracks(mProject) - 1; i++)
441  t = iter.Next();
442 
443  // t is now the last track in the project, unless the import of
444  // all tracks failed, in which case it will be null. In that
445  // case we return because we cannot offset a non-existent track.
446  if (t == NULL) return;
447 #ifdef USE_MIDI
448  if (targetfile.AfterLast(wxT('.')).IsSameAs(wxT("mid"), false) ||
449  targetfile.AfterLast(wxT('.')).IsSameAs(wxT("midi"), false))
450  {
451  AudacityMessageBox(_("MIDI tracks cannot be offset individually, only audio files can be."),
452  _("LOF Error"), wxOK | wxCENTRE);
453  }
454  else
455 #endif
456  {
457  if (CountNumTracks(mProject) == 1)
458  t->SetOffset(offset);
459  else
460  {
461  if (t->GetLinked())
462  t->SetOffset(offset);
463 
464  t = iter.Next();
465  t->SetOffset(offset);
466  }
467  }
468 
469  // Amend the undo transaction made by import
470  mProject->TP_ModifyState(false);
471  } // end of converting "offset" argument
472  else
473  {
474  /* i18n-hint: You do not need to translate "LOF" */
475  AudacityMessageBox(_("Invalid track offset in LOF file."),
476  _("LOF Error"), wxOK | wxCENTRE);
477  }
478  } // End if statement for "offset" parameters
479  } // End if statement (more tokens after file name)
480  } // End if statement "file" lines
481 
482  else if (tokenholder.IsSameAs(wxT("#")))
483  {
484  // # indicates comments; ignore line
485  tok = wxStringTokenizer(wxT(""), wxT(" "));
486  }
487  else
488  {
489  // Couldn't parse a line
490  }
491 }
static bool IsMidi(const wxString &fName)
Definition: Import.cpp:325
AudacityProject * mProject
Definition: ImportLOF.cpp:149
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
void doDurationAndScrollOffset()
Definition: ImportLOF.cpp:493
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
Definition: Internat.cpp:122
void TP_ModifyState(bool bWantsAutoSave) override
Definition: Project.cpp:5420
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:102
An iterator for a TrackList.
Definition: Track.h:402
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
static AudacityProject * DoImportMIDI(AudacityProject *pProject, const wxString &fileName)
TrackList * GetTracks()
Definition: Project.h:192
wxFileName mLOFFileName
Definition: ImportLOF.cpp:147
static AudacityProject * OpenProject(AudacityProject *pProject, const wxString &fileNameArg, bool addtohistory=true)
Definition: Project.cpp:2967
static int CountNumTracks(AudacityProject *proj)
Definition: ImportLOF.cpp:271
void LOFImportFileHandle::SetStreamUsage ( wxInt32   WXUNUSEDStreamID,
bool   WXUNUSEDUse 
)
inlineoverride

Definition at line 138 of file ImportLOF.cpp.

139  {}

Member Data Documentation

bool LOFImportFileHandle::callDurationFactor { false }
private

Definition at line 155 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

bool LOFImportFileHandle::callScrollOffset { false }
private

Definition at line 159 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

double LOFImportFileHandle::durationFactor { 1 }
private

Definition at line 156 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

wxFileName LOFImportFileHandle::mLOFFileName
private

The name of the LOF file, which is used to interpret relative paths in it

Definition at line 147 of file ImportLOF.cpp.

Referenced by lofOpenFiles().

AudacityProject* LOFImportFileHandle::mProject { GetActiveProject() }
private

Definition at line 149 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

std::unique_ptr<wxTextFile> LOFImportFileHandle::mTextFile
private

Definition at line 146 of file ImportLOF.cpp.

Referenced by Import().

double LOFImportFileHandle::scrollOffset { 0 }
private

Definition at line 160 of file ImportLOF.cpp.

Referenced by doDurationAndScrollOffset(), and lofOpenFiles().

bool LOFImportFileHandle::windowCalledOnce { false }
private

Definition at line 152 of file ImportLOF.cpp.

Referenced by lofOpenFiles().


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