2010-01-23 19:44:49 +00:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
|
|
|
|
LabelTrack.h
|
|
|
|
|
|
|
|
Dominic Mazzoni
|
|
|
|
James Crook
|
|
|
|
Jun Wan
|
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifndef _LABELTRACK_
|
|
|
|
#define _LABELTRACK_
|
|
|
|
|
2014-10-05 17:10:09 +00:00
|
|
|
#include "SelectedRegion.h"
|
2010-01-23 19:44:49 +00:00
|
|
|
#include "Track.h"
|
|
|
|
|
|
|
|
|
2018-11-14 20:01:44 +00:00
|
|
|
class wxFont;
|
2010-01-23 19:44:49 +00:00
|
|
|
class wxKeyEvent;
|
|
|
|
class wxMouseEvent;
|
|
|
|
class wxTextFile;
|
|
|
|
class wxWindow;
|
|
|
|
class wxIcon;
|
|
|
|
class wxBitmap;
|
|
|
|
class TrackList;
|
|
|
|
|
|
|
|
class AudacityProject;
|
|
|
|
class DirManager;
|
|
|
|
class TimeWarper;
|
2015-04-20 04:17:26 +00:00
|
|
|
class ZoomInfo;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
|
2017-06-18 01:37:41 +00:00
|
|
|
struct LabelTrackHit;
|
2017-06-23 23:28:38 +00:00
|
|
|
struct TrackPanelDrawingContext;
|
2017-06-18 01:37:41 +00:00
|
|
|
|
2014-06-03 20:30:19 +00:00
|
|
|
class LabelStruct
|
2010-01-23 19:44:49 +00:00
|
|
|
{
|
|
|
|
public:
|
2018-11-08 21:53:45 +00:00
|
|
|
LabelStruct() = default;
|
2014-10-05 17:10:09 +00:00
|
|
|
// Copies region
|
|
|
|
LabelStruct(const SelectedRegion& region, const wxString &aTitle);
|
|
|
|
// Copies region but then overwrites other times
|
|
|
|
LabelStruct(const SelectedRegion& region, double t0, double t1,
|
|
|
|
const wxString &aTitle);
|
2016-06-23 19:03:30 +00:00
|
|
|
void DrawLines( wxDC & dc, const wxRect & r) const;
|
|
|
|
void DrawGlyphs
|
|
|
|
( wxDC & dc, const wxRect & r, int GlyphLeft, int GlyphRight) const;
|
|
|
|
void DrawText( wxDC & dc, const wxRect & r) const;
|
|
|
|
void DrawTextBox( wxDC & dc, const wxRect & r) const;
|
2016-06-30 19:56:57 +00:00
|
|
|
void DrawHighlight( wxDC & dc, int xPos1, int xPos2, int charHeight) const;
|
2016-02-27 17:12:40 +00:00
|
|
|
void getXPos( wxDC & dc, int * xPos1, int cursorPos) const;
|
2015-04-10 03:37:39 +00:00
|
|
|
const SelectedRegion &getSelectedRegion() const { return selectedRegion; }
|
2014-10-05 17:10:09 +00:00
|
|
|
double getDuration() const { return selectedRegion.duration(); }
|
|
|
|
double getT0() const { return selectedRegion.t0(); }
|
|
|
|
double getT1() const { return selectedRegion.t1(); }
|
|
|
|
// Returns true iff the label got inverted:
|
|
|
|
bool AdjustEdge( int iEdge, double fNewTime);
|
2010-02-07 11:11:35 +00:00
|
|
|
void MoveLabel( int iEdge, double fNewTime);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2016-07-10 23:09:48 +00:00
|
|
|
struct BadFormatException {};
|
2016-07-13 02:16:15 +00:00
|
|
|
static LabelStruct Import(wxTextFile &file, int &index);
|
2016-07-10 23:09:48 +00:00
|
|
|
|
|
|
|
void Export(wxTextFile &file) const;
|
|
|
|
|
2010-09-18 17:41:15 +00:00
|
|
|
/// Relationships between selection region and labels
|
|
|
|
enum TimeRelations
|
|
|
|
{
|
|
|
|
BEFORE_LABEL,
|
|
|
|
AFTER_LABEL,
|
|
|
|
SURROUNDS_LABEL,
|
|
|
|
WITHIN_LABEL,
|
|
|
|
BEGINS_IN_LABEL,
|
|
|
|
ENDS_IN_LABEL
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Returns relationship between a region described and this label; if
|
|
|
|
/// parent is set, it will consider point labels at the very beginning
|
|
|
|
/// and end of parent to be within a region that borders them (this makes
|
2016-02-14 23:50:45 +00:00
|
|
|
/// it possible to DELETE capture all labels with a Select All).
|
2010-09-18 17:41:15 +00:00
|
|
|
TimeRelations RegionRelation(double reg_t0, double reg_t1,
|
2016-06-23 19:03:30 +00:00
|
|
|
const LabelTrack *parent = NULL) const;
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
public:
|
2014-10-05 17:10:09 +00:00
|
|
|
SelectedRegion selectedRegion;
|
2010-01-23 19:44:49 +00:00
|
|
|
wxString title; /// Text of the label.
|
2018-11-08 21:53:45 +00:00
|
|
|
mutable int width{}; /// width of the text in pixels.
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Working storage for on-screen layout.
|
2018-11-08 21:53:45 +00:00
|
|
|
mutable int x{}; /// Pixel position of left hand glyph
|
|
|
|
mutable int x1{}; /// Pixel position of right hand glyph
|
|
|
|
mutable int xText{}; /// Pixel position of left hand side of text box
|
|
|
|
mutable int y{}; /// Pixel position of label.
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-11-08 21:53:45 +00:00
|
|
|
bool updated{}; /// flag to tell if the label times were updated
|
2010-01-23 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
2016-06-30 19:56:57 +00:00
|
|
|
using LabelArray = std::vector<LabelStruct>;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
const int NUM_GLYPH_CONFIGS = 3;
|
|
|
|
const int NUM_GLYPH_HIGHLIGHTS = 4;
|
|
|
|
const int MAX_NUM_ROWS =80;
|
|
|
|
|
2016-02-24 06:06:39 +00:00
|
|
|
class AUDACITY_DLL_API LabelTrack final : public Track
|
2013-08-22 20:52:56 +00:00
|
|
|
{
|
2019-06-16 15:12:06 +00:00
|
|
|
friend class LabelTrackView;
|
2010-01-23 19:44:49 +00:00
|
|
|
friend class LabelStruct;
|
|
|
|
|
|
|
|
public:
|
2018-10-22 12:51:16 +00:00
|
|
|
static void DoEditLabels(
|
|
|
|
AudacityProject &project, LabelTrack *lt = nullptr, int index = -1);
|
|
|
|
static int DialogForLabelName(
|
|
|
|
AudacityProject &project, const SelectedRegion& region,
|
|
|
|
const wxString& initialValue, wxString& value);
|
|
|
|
|
2019-06-09 00:35:21 +00:00
|
|
|
bool IsTextSelected() const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
void CreateCustomGlyphs();
|
2016-08-13 04:38:31 +00:00
|
|
|
LabelTrack(const std::shared_ptr<DirManager> &projDirManager);
|
2010-01-23 19:44:49 +00:00
|
|
|
LabelTrack(const LabelTrack &orig);
|
|
|
|
|
|
|
|
virtual ~ LabelTrack();
|
2015-07-07 03:12:16 +00:00
|
|
|
|
2018-11-08 21:53:45 +00:00
|
|
|
void SetLabel( size_t iLabel, const LabelStruct &newLabel );
|
|
|
|
|
2016-02-24 06:06:47 +00:00
|
|
|
void SetOffset(double dOffset) override;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-06-23 17:45:22 +00:00
|
|
|
static const int DefaultFontSize = 12;
|
|
|
|
|
|
|
|
static wxFont GetFont(const wxString &faceName, int size = DefaultFontSize);
|
2010-01-23 19:44:49 +00:00
|
|
|
static void ResetFont();
|
|
|
|
|
2018-11-03 17:34:48 +00:00
|
|
|
void Draw( TrackPanelDrawingContext &context, const wxRect & r ) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-12-06 20:27:03 +00:00
|
|
|
int GetSelectedIndex() const;
|
2018-11-08 21:53:45 +00:00
|
|
|
void SetSelectedIndex( int index );
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-02-24 06:06:47 +00:00
|
|
|
double GetOffset() const override;
|
|
|
|
double GetStartTime() const override;
|
|
|
|
double GetEndTime() const override;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-11-19 04:07:05 +00:00
|
|
|
using Holder = std::shared_ptr<LabelTrack>;
|
2018-11-19 01:15:26 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
Track::Holder Clone() const override;
|
2015-08-23 23:02:06 +00:00
|
|
|
|
2018-11-19 01:15:26 +00:00
|
|
|
public:
|
2016-02-24 06:06:47 +00:00
|
|
|
bool HandleXMLTag(const wxChar *tag, const wxChar **attrs) override;
|
|
|
|
XMLTagHandler *HandleXMLChild(const wxChar *tag) override;
|
2017-02-22 19:23:35 +00:00
|
|
|
void WriteXML(XMLWriter &xmlFile) const override;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
#if LEGACY_PROJECT_FILE_SUPPORT
|
2016-02-24 06:06:47 +00:00
|
|
|
bool Load(wxTextFile * in, DirManager * dirManager) override;
|
|
|
|
bool Save(wxTextFile * out, bool overwrite) override;
|
2010-01-23 19:44:49 +00:00
|
|
|
#endif
|
|
|
|
|
2016-03-02 20:36:44 +00:00
|
|
|
Track::Holder Cut (double t0, double t1) override;
|
2016-11-26 13:48:08 +00:00
|
|
|
Track::Holder Copy (double t0, double t1, bool forClipboard = true) const override;
|
2017-03-23 15:10:14 +00:00
|
|
|
void Clear(double t0, double t1) override;
|
|
|
|
void Paste(double t, const Track * src) override;
|
2010-01-23 19:44:49 +00:00
|
|
|
bool Repeat(double t0, double t1, int n);
|
|
|
|
|
2017-03-23 15:10:14 +00:00
|
|
|
void Silence(double t0, double t1) override;
|
|
|
|
void InsertSilence(double t, double len) override;
|
2017-06-18 01:37:41 +00:00
|
|
|
void OverGlyph(LabelTrackHit &hit, int x, int y) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
static wxBitmap & GetGlyph( int i);
|
|
|
|
|
|
|
|
|
2015-08-17 21:49:00 +00:00
|
|
|
struct Flags {
|
|
|
|
int mInitialCursorPos, mCurrentCursorPos, mSelIndex;
|
|
|
|
bool mRightDragging, mDrawCursor;
|
|
|
|
};
|
2010-01-23 19:44:49 +00:00
|
|
|
void ResetFlags();
|
2015-08-17 21:49:00 +00:00
|
|
|
Flags SaveFlags() const
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
mInitialCursorPos, mCurrentCursorPos, mSelIndex,
|
|
|
|
mRightDragging, mDrawCursor
|
|
|
|
};
|
|
|
|
}
|
|
|
|
void RestoreFlags( const Flags& flags );
|
|
|
|
|
2015-08-18 01:26:34 +00:00
|
|
|
int OverATextBox(int xx, int yy) const;
|
|
|
|
bool OverTextBox(const LabelStruct *pLabel, int x, int y) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
bool CutSelectedText();
|
|
|
|
bool CopySelectedText();
|
|
|
|
bool PasteSelectedText(double sel0, double sel1);
|
|
|
|
static bool IsTextClipSupported();
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2015-08-17 21:49:00 +00:00
|
|
|
void HandleGlyphClick
|
2017-06-18 01:37:41 +00:00
|
|
|
(LabelTrackHit &hit,
|
|
|
|
const wxMouseEvent & evt, const wxRect & r, const ZoomInfo &zoomInfo,
|
2015-08-17 21:49:00 +00:00
|
|
|
SelectedRegion *newSel);
|
|
|
|
void HandleTextClick
|
|
|
|
(const wxMouseEvent & evt, const wxRect & r, const ZoomInfo &zoomInfo,
|
|
|
|
SelectedRegion *newSel);
|
2017-06-18 01:37:41 +00:00
|
|
|
bool HandleGlyphDragRelease
|
|
|
|
(LabelTrackHit &hit,
|
|
|
|
const wxMouseEvent & evt, wxRect & r, const ZoomInfo &zoomInfo,
|
|
|
|
SelectedRegion *newSel);
|
2015-08-11 00:02:24 +00:00
|
|
|
void HandleTextDragRelease(const wxMouseEvent & evt);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
void Import(wxTextFile & f);
|
2016-06-23 19:03:30 +00:00
|
|
|
void Export(wxTextFile & f) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
void Unselect();
|
|
|
|
|
2018-11-08 16:07:42 +00:00
|
|
|
// Whether any label box is selected -- not, whether the track is selected.
|
|
|
|
bool HasSelection() const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
|
|
|
int GetNumLabels() const;
|
|
|
|
const LabelStruct *GetLabel(int index) const;
|
2019-06-09 00:35:21 +00:00
|
|
|
const LabelArray &GetLabels() const { return mLabels; }
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-12-05 21:16:31 +00:00
|
|
|
void OnLabelAdded( const wxString &title, int pos );
|
2010-01-23 19:44:49 +00:00
|
|
|
//This returns the index of the label we just added.
|
2018-12-05 21:16:31 +00:00
|
|
|
int AddLabel(const SelectedRegion ®ion, const wxString &title);
|
2010-01-23 19:44:49 +00:00
|
|
|
//And this tells us the index, if there is a label already there.
|
|
|
|
int GetLabelIndex(double t, double t1);
|
|
|
|
|
|
|
|
//This deletes the label at given index.
|
|
|
|
void DeleteLabel(int index);
|
|
|
|
|
2016-06-23 18:39:14 +00:00
|
|
|
//get current cursor position,
|
|
|
|
// relative to the left edge of the track panel
|
|
|
|
bool CalcCursorX(int * x) const;
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2016-06-23 23:49:31 +00:00
|
|
|
void CalcHighlightXs(int *x1, int *x2) const;
|
|
|
|
|
2017-06-18 01:37:41 +00:00
|
|
|
void MayAdjustLabel
|
|
|
|
( LabelTrackHit &hit,
|
|
|
|
int iLabel, int iEdge, bool bAllowSwapping, double fNewTime);
|
2010-02-07 11:11:35 +00:00
|
|
|
void MayMoveLabel( int iLabel, int iEdge, double fNewTime);
|
|
|
|
|
2010-02-16 20:50:38 +00:00
|
|
|
// This pastes labels without shifting existing ones
|
2016-02-27 17:54:57 +00:00
|
|
|
bool PasteOver(double t, const Track *src);
|
2016-02-23 19:27:43 +00:00
|
|
|
|
|
|
|
// PRL: These functions were not used because they were not overrides! Was that right?
|
2016-03-02 20:36:44 +00:00
|
|
|
//Track::Holder SplitCut(double b, double e) /* not override */;
|
2016-02-23 19:27:43 +00:00
|
|
|
//bool SplitDelete(double b, double e) /* not override */;
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
void ShiftLabelsOnInsert(double length, double pt);
|
|
|
|
void ChangeLabelsOnReverse(double b, double e);
|
|
|
|
void ScaleLabels(double b, double e, double change);
|
|
|
|
double AdjustTimeStampOnScale(double t, double b, double e, double change);
|
|
|
|
void WarpLabels(const TimeWarper &warper);
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
// Returns tab-separated text of all labels completely within given region
|
2016-06-23 19:03:30 +00:00
|
|
|
wxString GetTextOfLabels(double t0, double t1) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-10-18 14:50:42 +00:00
|
|
|
int FindNextLabel(const SelectedRegion& currentSelection);
|
|
|
|
int FindPrevLabel(const SelectedRegion& currentSelection);
|
|
|
|
|
2010-01-23 19:44:49 +00:00
|
|
|
public:
|
2017-06-18 01:37:41 +00:00
|
|
|
void SortLabels(LabelTrackHit *pHit = nullptr);
|
2010-01-23 19:44:49 +00:00
|
|
|
private:
|
2017-01-06 18:55:57 +00:00
|
|
|
TrackKind GetKind() const override { return TrackKind::Label; }
|
|
|
|
|
2015-07-30 15:38:03 +00:00
|
|
|
void ShowContextMenu();
|
|
|
|
void OnContextMenu(wxCommandEvent & evt);
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2018-12-06 20:27:03 +00:00
|
|
|
mutable int mSelIndex; /// Keeps track of the currently selected label
|
2010-01-23 19:44:49 +00:00
|
|
|
int mxMouseDisplacement; /// Displacement of mouse cursor from the centre being dragged.
|
|
|
|
LabelArray mLabels;
|
|
|
|
|
|
|
|
static int mIconHeight;
|
|
|
|
static int mIconWidth;
|
|
|
|
static int mTextHeight;
|
|
|
|
static bool mbGlyphsReady;
|
|
|
|
static wxBitmap mBoundaryGlyphs[NUM_GLYPH_CONFIGS * NUM_GLYPH_HIGHLIGHTS];
|
|
|
|
|
|
|
|
static int mFontHeight;
|
2016-06-23 19:12:46 +00:00
|
|
|
int mCurrentCursorPos; /// current cursor position
|
|
|
|
int mInitialCursorPos; /// initial cursor position
|
2016-06-23 19:03:30 +00:00
|
|
|
|
|
|
|
bool mRightDragging; /// flag to tell if it's a valid dragging
|
2016-06-23 19:12:46 +00:00
|
|
|
bool mDrawCursor; /// flag to tell if drawing the
|
|
|
|
/// cursor or not
|
2016-06-23 19:03:30 +00:00
|
|
|
int mRestoreFocus; /// Restore focus to this track
|
|
|
|
/// when done editing
|
2014-06-03 20:30:19 +00:00
|
|
|
|
2010-02-16 20:50:38 +00:00
|
|
|
// Set in copied label tracks
|
2010-01-23 19:44:49 +00:00
|
|
|
double mClipLen;
|
|
|
|
|
2016-10-18 14:50:42 +00:00
|
|
|
int miLastLabel; // used by FindNextLabel and FindPrevLabel
|
|
|
|
|
2016-02-27 17:12:40 +00:00
|
|
|
void ComputeLayout(const wxRect & r, const ZoomInfo &zoomInfo) const;
|
|
|
|
void ComputeTextPosition(const wxRect & r, int index) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
|
2016-06-23 19:12:46 +00:00
|
|
|
public:
|
2016-07-11 17:59:29 +00:00
|
|
|
int FindCurrentCursorPosition(int xPos);
|
2016-06-23 19:12:46 +00:00
|
|
|
void SetCurrentCursorPosition(int xPos);
|
|
|
|
|
|
|
|
private:
|
2016-02-27 17:12:40 +00:00
|
|
|
void calculateFontHeight(wxDC & dc) const;
|
2010-01-23 19:44:49 +00:00
|
|
|
void RemoveSelectedText();
|
|
|
|
|
|
|
|
static wxFont msFont;
|
2015-07-07 03:12:16 +00:00
|
|
|
|
|
|
|
protected:
|
2018-11-07 23:16:22 +00:00
|
|
|
std::shared_ptr<TrackView> DoGetView() override;
|
2018-11-06 16:02:03 +00:00
|
|
|
std::shared_ptr<TrackControls> DoGetControls() override;
|
2010-01-23 19:44:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|