File indexing completed on 2024-05-05 04:51:41

0001 /*
0002     SPDX-FileCopyrightText: 2004-2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-FileCopyrightText: 2010-2011 Michal Malek <michalm@jabster.pl>
0004     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef _K3B_AUDIO_EDITOR_WIDGET_H_
0009 #define _K3B_AUDIO_EDITOR_WIDGET_H_
0010 
0011 #include "k3bmsf.h"
0012 
0013 #include <QList>
0014 #include <QMouseEvent>
0015 #include <QFrame>
0016 
0017 
0018 class QPainter;
0019 
0020 
0021 namespace K3b {
0022 class AudioEditorWidget : public QFrame
0023 {
0024     Q_OBJECT
0025 
0026 public:
0027     explicit AudioEditorWidget( QWidget* parent = 0 );
0028     ~AudioEditorWidget() override;
0029 
0030     QSize sizeHint() const override;
0031     QSize minimumSizeHint() const override;
0032 
0033     /**
0034      * For now the Editor has only one parameter: the length data.
0035      */
0036     void setLength( const K3b::Msf& length );
0037 
0038     const K3b::Msf length() const;
0039 
0040     /**
0041      * Add a user editable range.
0042      * @param startFixed if true the range's start cannot be changed by the user, only with modifyRange
0043      * @param endFixed if true the range's end cannot be changed by the user, only with modifyRange
0044      * @param brush if not specified or it has the NoBrush style one is chosen automatically.
0045      *
0046      * @return -1 on error or an identifier on success (be aware that the highest value for end is length-1)
0047      */
0048     int addRange( const K3b::Msf& start, const K3b::Msf& end,
0049                   bool startFixed = false, bool endFixed = false,
0050                   const QString& toolTip = QString(),
0051                   const QBrush& brush = QBrush() );
0052 
0053     /**
0054      * \returns the identifier of the range which spans over x position \a pos or
0055      * 0 if no range is defined in this region.
0056      */
0057     int findRange( int pos ) const;
0058 
0059     /**
0060      * Searches for a range edge at x position \a pos.
0061      * \return The ranges identifier if an edge could be found or 0 if there is no
0062      * range edge at the position.
0063      */
0064     int findRangeEdge( int pos, bool* end = 0 ) const;
0065 
0066     /**
0067      * @returns false if the range does not exist or end was bigger than start.
0068      */
0069     bool modifyRange( int identifier, const K3b::Msf& start, const K3b::Msf& end );
0070 
0071     /**
0072      * @returns false if the range does not exist.
0073      */
0074     bool removeRange( int identifier );
0075 
0076     K3b::Msf rangeStart( int identifier ) const;
0077     K3b::Msf rangeEnd( int identifier ) const;
0078 
0079     /**
0080      * \return A list of all ranges' identifiers sorted ascending by start
0081      * offset
0082      */
0083     QList<int> allRanges() const;
0084 
0085     void setMaxNumberOfMarkers( int );
0086 
0087     /**
0088      * @param fixed if true the marker cannot be changed by the user, only with moveMarker
0089      * @return -1 on error or an identifier on success.
0090      */
0091     int addMarker( const K3b::Msf& pos, bool fixed = false,
0092                    const QString& toolTip = QString(), const QColor& color = QColor() );
0093 
0094     /**
0095      * @return false if the marker does not exist.
0096      */
0097     bool removeMarker( int identifier );
0098 
0099     /**
0100      * @return false if the marker does not exist.
0101      */
0102     bool moveMarker( int identifier, const K3b::Msf& );
0103 
0104     void enableMouseAtSignal( bool b );
0105 
0106     /**
0107      * By default ranges can overlap. If overlapping ranges are not allowed
0108      * the editor widget will modify and delete ranges accordingly.
0109      *
0110      * Caution: So far setting this will not check if ranges already overlap.
0111      */
0112     void setAllowOverlappingRanges( bool b );
0113 
0114     /**
0115      * Range selection is by default disabled. If it is enabled the editor visually
0116      * highlights the last clicked range.
0117      *
0118      * \sa setSelectedRange
0119      */
0120     void enableRangeSelection( bool b );
0121 
0122     bool allowOverlappingRanges() const;
0123     bool rangeSelectedEnabled() const;
0124 
0125     void setSelectedRange( int id );
0126 
0127     /**
0128      * \return The identifier of the currently selected range or 0
0129      * if none is selected.
0130      */
0131     int selectedRange() const;
0132 
0133     K3b::Msf posToMsf( int x ) const;
0134     int msfToPos( const K3b::Msf& msf ) const;
0135 
0136     /**
0137      * Set the brush to paint the selected range. Default is QColorGroup::Highlight
0138      */
0139     void setSelectedRangeBrush( const QBrush& );
0140     const QBrush& selectedRangeBrush() const;
0141 
0142 Q_SIGNALS:
0143     /**
0144      * Emitted when enabled.
0145      */
0146     void mouseAt( const K3b::Msf& );
0147 
0148     /**
0149      * Emitted when the user changed a range.
0150      * This signal is not emitted when a range is changed via modifyRange.
0151      */
0152     void rangeChanged( int identifier, const K3b::Msf& start, const K3b::Msf& end );
0153     void rangeRemoved( int );
0154 
0155     void selectedRangeChanged( int );
0156 
0157     /**
0158      * Emitted when the user moves a marker.
0159      * This signal is not emitted when a marker is changed via moveMarker.
0160      */
0161     void markerMoved( int identifier, const K3b::Msf& pos );
0162     void markerAdded( int identifier, const K3b::Msf& pos );
0163     void markerRemoved( int identifier );
0164 
0165 protected:
0166     void paintEvent( QPaintEvent* e ) override;
0167     void mousePressEvent( QMouseEvent* e ) override;
0168     void mouseReleaseEvent( QMouseEvent* e ) override;
0169     void mouseDoubleClickEvent( QMouseEvent* e ) override;
0170     void mouseMoveEvent( QMouseEvent* e ) override;
0171     bool event( QEvent* e ) override;
0172 
0173 private:
0174     class Range;
0175     class Marker;
0176     struct SortByStart;
0177 
0178     class Private;
0179     Private* d;
0180 
0181     void drawAll( QPainter*, const QRect& );
0182     void drawRange( QPainter* p, const QRect&, const Range& r );
0183     void drawMarker( QPainter* p, const QRect&, const Marker& m );
0184 
0185     /**
0186      * Makes sure that \a r does not overlap any other range by modifying and
0187      * deleting other ranges.
0188      */
0189     void fixupOverlappingRanges( int rangeId );
0190 
0191     Range* getRange( int i ) const;
0192     Marker* getMarker( int i ) const;
0193     Range* findRange( const QPoint& p ) const;
0194     Range* findRangeEdge( const QPoint& p, bool* end = 0 ) const;
0195     Marker* findMarker( const QPoint& p ) const;
0196 };
0197 }
0198 
0199 #endif