1 /**
2  * \file framelist.h
3  * List of frames.
4  *
5  * \b Project: Kid3
6  * \author Urs Fleisch
7  * \date 9 Jan 2003
8  *
9  * Copyright (C) 2003-2018  Urs Fleisch
10  *
11  * This file is part of Kid3.
12  *
13  * Kid3 is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * Kid3 is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #pragma once
28 
29 #include <QObject>
30 #include "frame.h"
31 
32 class QItemSelectionModel;
33 class FrameTableModel;
34 class TaggedFile;
35 class IFrameEditor;
36 
37 /**
38  * List of frames.
39  */
40 class KID3_CORE_EXPORT FrameList : public QObject {
41   Q_OBJECT
42 public:
43   /**
44    * Constructor.
45    *
46    * @param tagNr tag number
47    * @param ftm frame table model
48    * @param selModel item selection model
49    */
50   FrameList(Frame::TagNumber tagNr,
51             FrameTableModel* ftm, QItemSelectionModel* selModel);
52 
53   /**
54    * Destructor.
55    */
56   virtual ~FrameList() override = default;
57 
58   /**
59    * Get editor for frames.
60    * @return frame editor.
61    */
frameEditor()62   IFrameEditor* frameEditor() const { return m_frameEditor; }
63 
64   /**
65    * Set editor for frames.
66    *
67    * @param frameEditor frame editor
68    */
69   void setFrameEditor(IFrameEditor* frameEditor);
70 
71   /**
72    * Set tagged file.
73    *
74    * @param taggedFile file
75    */
setTaggedFile(TaggedFile * taggedFile)76   void setTaggedFile(TaggedFile* taggedFile) { m_taggedFile = taggedFile; }
77 
78   /**
79    * Get tagged file.
80    * @return tagged file.
81    */
getTaggedFile()82   TaggedFile* getTaggedFile() const { return m_taggedFile; }
83 
84   /**
85    * Delete selected frame.
86    *
87    * @return false if frame not found.
88    */
89   bool deleteFrame();
90 
91   /**
92    * Let the user select and edit a frame type and then edit the frame.
93    * Add the frame if the edits are accepted.
94    * frameEdited() is emitted with the added frame.
95    */
96   void selectAddAndEditFrame();
97 
98   /**
99    * Add and edit a new frame.
100    * frameEdited() is emitted with the added frame.
101    */
102   void addAndEditFrame();
103 
104   /**
105    * Edit the current frame.
106    * The frame and its file have to be set using setFrame() and setTaggedFile().
107    */
108   void editFrame();
109 
110   /**
111    * Paste the selected frame from the copy buffer.
112    *
113    * @return true if frame pasted.
114    */
115   bool pasteFrame();
116 
117   /**
118    * Get the frame in the copy buffer.
119    * @return frame from copy buffer.
120    */
getFrame()121   const Frame& getFrame() const { return m_frame; }
122 
123   /**
124    * Set the frame in the copy buffer.
125    * @param frame frame to set
126    */
setFrame(const Frame & frame)127   void setFrame(const Frame& frame) { m_frame = frame; }
128 
129   /**
130    * Add a suitable field list for the frame in the copy buffer if missing.
131    */
132   void addFrameFieldList();
133 
134   /**
135    * Check if the frame in the copy buffer is a picture frame.
136    * @return true if picture frame.
137    */
isPictureFrame()138   bool isPictureFrame() const { return m_frame.getType() == Frame::FT_Picture; }
139 
140   /**
141    * Get the name of the selected frame.
142    *
143    * @return name, QString::null if nothing selected.
144    */
145   QString getSelectedName() const;
146 
147   /**
148    * Select a frame with a given name.
149    *
150    * @param name name of frame
151    *
152    * @return true if a frame with that name could be selected.
153    */
154   bool selectByName(const QString& name);
155 
156   /**
157    * Select a frame by row number in the frame table.
158    *
159    * @param row row of frame
160    *
161    * @return true if a frame could be selected.
162    */
163   Q_INVOKABLE bool selectByRow(int row);
164 
165   /**
166    * Get ID of selected frame list item.
167    *
168    * @return ID of selected item,
169    *         -1 if not item is selected.
170    */
171   int getSelectedId() const;
172 
173   /**
174    * Select the frame by ID.
175    *
176    * @param id ID of frame to select
177    */
178   void setSelectedId(int id);
179 
180   /**
181    * Get number of tag containing the frames of this frame list.
182    * @return tag number.
183    */
tagNumber()184   Frame::TagNumber tagNumber() const { return m_tagNr; }
185 
186   /**
187    * Save the current cursor position.
188    */
189   void saveCursor();
190 
191   /**
192    * Restore the cursor position saved with saveCursor().
193    */
194   void restoreCursor();
195 
196 signals:
197   /**
198    * Emitted when the dialog to add and edit a frame is closed and an
199    * existing frame was edited.
200    * @param frame edited frame if dialog was accepted, else 0
201    */
202   void frameEdited(const Frame* frame);
203 
204   /**
205    * Emitted when the dialog to add and edit a frame is closed and a new
206    * frame was added.
207    * @param frame edited frame if dialog was accepted, else 0
208    */
209   void frameAdded(const Frame* frame);
210 
211 private slots:
212   void onFrameSelected(Frame::TagNumber tagNr, const Frame* frame);
213   void onFrameEdited(Frame::TagNumber tagNr, const Frame* frame);
214 
215 private:
216   FrameList(const FrameList&);
217   FrameList& operator=(const FrameList&);
218 
219   /**
220    * Get frame of selected frame list item.
221    *
222    * @param frame the selected frame is returned here
223    *
224    * @return false if not item is selected.
225    */
226   bool getSelectedFrame(Frame& frame) const;
227 
228   /**
229    * Set the frame table model from the tagged file.
230    */
231   void setModelFromTaggedFile();
232 
233   /** Set of old changed frames stored while in the edit dialog */
234   quint64 m_oldChangedFrames;
235   /** File containing tags */
236   TaggedFile* m_taggedFile;
237   /** Editor for frames */
238   IFrameEditor* m_frameEditor;
239   /** Frame used to add, edit and paste */
240   Frame m_frame;
241 
242   FrameTableModel* m_frameTableModel;
243   QItemSelectionModel* m_selectionModel;
244 
245   int m_cursorRow;
246   int m_cursorColumn;
247   const Frame::TagNumber m_tagNr;
248 
249   /** true while a frame is added */
250   bool m_addingFrame;
251 };
252