File indexing completed on 2024-05-19 04:56:09

0001 /**
0002  * \file timeeventmodel.h
0003  * Time event model (synchronized lyrics or event timing codes).
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 14 Mar 2014
0008  *
0009  * Copyright (C) 2014-2024  Urs Fleisch
0010  *
0011  * This file is part of Kid3.
0012  *
0013  * Kid3 is free software; you can redistribute it and/or modify
0014  * it under the terms of the GNU General Public License as published by
0015  * the Free Software Foundation; either version 2 of the License, or
0016  * (at your option) any later version.
0017  *
0018  * Kid3 is distributed in the hope that it will be useful,
0019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0021  * GNU General Public License for more details.
0022  *
0023  * You should have received a copy of the GNU General Public License
0024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0025  */
0026 
0027 #pragma once
0028 
0029 #include <QAbstractTableModel>
0030 #include <QTime>
0031 #include "frame.h"
0032 #include "kid3api.h"
0033 
0034 class QTextStream;
0035 class CoreTaggedFileIconProvider;
0036 
0037 /**
0038  * Time event model.
0039  */
0040 class KID3_CORE_EXPORT TimeEventModel : public QAbstractTableModel {
0041   Q_OBJECT
0042 public:
0043   /** Type of data. */
0044   enum Type {
0045     SynchronizedLyrics, /**< Synchronized lyrics text */
0046     EventTimingCodes    /**< Event codes */
0047   };
0048 
0049   /** Column indexes. */
0050   enum ColumnIndex {
0051     CI_Time,
0052     CI_Data,
0053     CI_NumColumns
0054   };
0055 
0056   /** Time and data. */
0057   struct TimeEvent {
0058     /** Constructor. */
0059     TimeEvent(const QVariant& t, const QVariant& d) : time(t), data(d) {}
0060     QVariant time; /**< Time from the beginning of the file or frame integer. */
0061     QVariant data; /**< String (lyrics) or integer (event codes) */
0062 
0063     /**
0064      * Less than operator.
0065      * @param rhs right hand side to compare
0066      * @return true if this < rhs.
0067      */
0068     bool operator<(const TimeEvent& rhs) const {
0069       return time.toTime() < rhs.time.toTime();
0070     }
0071   };
0072 
0073   /**
0074    * Constructor.
0075    * @param colorProvider color provider
0076    * @param parent parent widget
0077    */
0078   explicit TimeEventModel(CoreTaggedFileIconProvider* colorProvider = nullptr,
0079                           QObject* parent = nullptr);
0080 
0081   /**
0082    * Destructor.
0083    */
0084   ~TimeEventModel() override = default;
0085 
0086   /**
0087    * Get item flags for index.
0088    * @param index model index
0089    * @return item flags
0090    */
0091   Qt::ItemFlags flags(const QModelIndex& index) const override;
0092 
0093   /**
0094    * Get data for a given role.
0095    * @param index model index
0096    * @param role item data role
0097    * @return data for role
0098    */
0099   QVariant data(const QModelIndex& index,
0100                 int role = Qt::DisplayRole) const override;
0101 
0102   /**
0103    * Set data for a given role.
0104    * @param index model index
0105    * @param value data value
0106    * @param role item data role
0107    * @return true if successful
0108    */
0109   bool setData(const QModelIndex& index, const QVariant& value,
0110                int role = Qt::EditRole) override;
0111 
0112   /**
0113    * Get data for header section.
0114    * @param section column or row
0115    * @param orientation horizontal or vertical
0116    * @param role item data role
0117    * @return header data for role
0118    */
0119   QVariant headerData(int section, Qt::Orientation orientation,
0120                       int role = Qt::DisplayRole) const override;
0121 
0122   /**
0123    * Set data for header section.
0124    * Not supported.
0125    * @return false
0126    */
0127   bool setHeaderData(int, Qt::Orientation, const QVariant&,
0128                      int = Qt::EditRole) override { return false; }
0129 
0130   /**
0131    * Get number of rows.
0132    * @param parent parent model index, invalid for table models
0133    * @return number of rows,
0134    * if parent is valid number of children (0 for table models)
0135    */
0136   int rowCount(const QModelIndex& parent = QModelIndex()) const override;
0137 
0138   /**
0139    * Get number of columns.
0140    * @param parent parent model index, invalid for table models
0141    * @return number of columns,
0142    * if parent is valid number of children (0 for table models)
0143    */
0144   int columnCount(const QModelIndex& parent = QModelIndex()) const override;
0145 
0146   /**
0147    * Insert rows.
0148    * @param row rows are inserted before this row, if 0 at the begin,
0149    * if rowCount() at the end
0150    * @param count number of rows to insert
0151    * @param parent parent model index, invalid for table models
0152    * @return true if successful
0153    */
0154   bool insertRows(int row, int count,
0155                   const QModelIndex& parent = QModelIndex()) override;
0156 
0157   /**
0158    * Remove rows.
0159    * @param row rows are removed starting with this row
0160    * @param count number of rows to remove
0161    * @param parent parent model index, invalid for table models
0162    * @return true if successful
0163    */
0164   bool removeRows(int row, int count,
0165                   const QModelIndex& parent = QModelIndex()) override;
0166 
0167   /**
0168    * Set type of data.
0169    * @param type SynchronizedLyrics (default) or EventTimingCodes
0170    */
0171   void setType(Type type) { m_type = type; }
0172 
0173   /**
0174    * Get type of data.
0175    * @return SynchronizedLyrics or EventTimingCodes.
0176    */
0177   Type getType() const { return m_type; }
0178 
0179   /**
0180    * Set the model from a list of time events.
0181    * @param events list of time events
0182    */
0183   void setTimeEvents(const QList<TimeEvent>& events);
0184 
0185   /**
0186    * Get time event list from the model.
0187    * @return list of time events.
0188    */
0189   QList<TimeEvent> getTimeEvents() const;
0190 
0191   /**
0192    * Get marked row.
0193    * @return row number.
0194    */
0195   int getMarkedRow() const { return m_markedRow; }
0196 
0197   /**
0198    * Mark row for a time stamp.
0199    * Marks the first row with time >= @a timeStamp.
0200    * @param timeStamp time
0201    * @see getMarkedRow()
0202    */
0203   void markRowForTimeStamp(const QTime& timeStamp);
0204 
0205   /**
0206    * Clear the marked row.
0207    */
0208   void clearMarkedRow();
0209 
0210   /**
0211    * Set the model from a SYLT frame.
0212    * @param fields ID3v2 SYLT frame fields
0213    */
0214   void fromSyltFrame(const Frame::FieldList& fields);
0215 
0216   /**
0217    * Get the model as a SYLT frame.
0218    * @param fields ID3v2 SYLT frame fields to set
0219    */
0220   void toSyltFrame(Frame::FieldList& fields) const;
0221 
0222   /**
0223    * Set the model from a ETCO frame.
0224    * @param fields ID3v2 ETCO frame fields
0225    */
0226   void fromEtcoFrame(const Frame::FieldList& fields);
0227 
0228   /**
0229    * Get the model as an ETCO frame.
0230    * @param fields ID3v2 ETCO frame fields to set
0231    */
0232   void toEtcoFrame(Frame::FieldList& fields) const;
0233 
0234   /**
0235    * Set the model from an LRC file.
0236    * @param stream LRC file stream
0237    */
0238   void fromLrcFile(QTextStream& stream);
0239 
0240   /**
0241    * Store the model in an LRC file.
0242    * @param stream LRC file stream
0243    * @param title optional title
0244    * @param artist optional artist
0245    * @param album optional album
0246    */
0247   void toLrcFile(QTextStream& stream,
0248                  const QString& title = QString(),
0249                  const QString& artist = QString(),
0250                  const QString& album = QString()) const;
0251 
0252   /**
0253    * Format a time suitable for a time stamp.
0254    * @param time time stamp
0255    * @return string of the format "mm:ss.zz"
0256    */
0257   static QString timeStampToString(const QTime& time);
0258 
0259 private:
0260   /**
0261    * Set the model from a text file.
0262    * @param stream text file stream
0263    */
0264   void fromTextFile(QTextStream& stream);
0265 
0266   Type m_type;
0267   int m_markedRow;
0268   QList<TimeEvent> m_timeEvents;
0269   CoreTaggedFileIconProvider* m_colorProvider;
0270 };