File indexing completed on 2025-02-23 04:34:22
0001 /** 0002 * \file kid3form.h 0003 * GUI for kid3. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 8 Apr 2003 0008 * 0009 * Copyright (C) 2003-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 <QSplitter> 0030 #include <QLineEdit> 0031 #include "frame.h" 0032 0033 class QLabel; 0034 class QCheckBox; 0035 class QPushButton; 0036 class QToolButton; 0037 class QSpinBox; 0038 class QGridLayout; 0039 class QGroupBox; 0040 class QPixmap; 0041 class QComboBox; 0042 class QStackedWidget; 0043 class FormatConfig; 0044 class FrameTable; 0045 class FrameTableModel; 0046 class Kid3Application; 0047 class FileList; 0048 class ConfigurableTreeView; 0049 class PictureLabel; 0050 class BaseMainWindowImpl; 0051 class Kid3FormTagContext; 0052 class AbstractFileDecorationProvider; 0053 class SectionActions; 0054 0055 /** 0056 * Main widget. 0057 */ 0058 class KID3_GUI_EXPORT Kid3Form : public QSplitter { 0059 Q_OBJECT 0060 public: 0061 /** 0062 * Constructs an Id3Form as a child of 'parent', with the 0063 * name 'name' and widget flags set to 'f'. 0064 * @param app application 0065 * @param mainWin main window 0066 * @param parent parent widget 0067 */ 0068 Kid3Form(Kid3Application* app, BaseMainWindowImpl* mainWin, 0069 QWidget* parent = nullptr); 0070 0071 /** 0072 * Destructor. 0073 */ 0074 ~Kid3Form() override; 0075 0076 /** 0077 * Set keyboard shortcuts for section actions. 0078 * @param map map of action names to key sequences 0079 */ 0080 void setSectionActionShortcuts(const QMap<QString, QKeySequence>& map); 0081 0082 /** 0083 * Get context for tag. 0084 * @param tagNr tag number 0085 * @return tag context. 0086 */ 0087 Kid3FormTagContext* tag(Frame::TagNumber tagNr) const { 0088 return m_tagContext[tagNr]; 0089 } 0090 0091 /** 0092 * Enable or disable controls requiring tags. 0093 * @param tagNr tag number 0094 * @param enable true to enable 0095 */ 0096 void enableControls(Frame::TagNumber tagNr, bool enable); 0097 0098 /** 0099 * Display the tag format. 0100 * @param tagNr tag number 0101 * @param str string describing format, e.g. "ID3v1.1" 0102 */ 0103 void setTagFormat(Frame::TagNumber tagNr, const QString& str); 0104 0105 /** 0106 * Adjust the size of the right half box. 0107 */ 0108 void adjustRightHalfBoxSize(); 0109 0110 /** 0111 * Hide or show file controls. 0112 * 0113 * @param hide true to hide, false to show 0114 */ 0115 void hideFile(bool hide); 0116 0117 /** 0118 * Hide or show tag controls. 0119 * @param tagNr tag number 0120 * @param hide true to hide, false to show 0121 */ 0122 void hideTag(Frame::TagNumber tagNr, bool hide); 0123 0124 /** 0125 * Toggle visibility of tag controls. 0126 * @param tagNr tag number 0127 */ 0128 void showHideTag(Frame::TagNumber tagNr); 0129 0130 /** 0131 * Hide or show picture. 0132 * 0133 * @param hide true to hide, false to show 0134 */ 0135 void hidePicture(bool hide); 0136 0137 /** 0138 * Save the local settings to the configuration. 0139 */ 0140 void saveConfig(); 0141 0142 /** 0143 * Read the local settings from the configuration. 0144 */ 0145 void readConfig(); 0146 0147 /** 0148 * Save file and directory list columns to the configuration. 0149 */ 0150 void saveFileAndDirListConfig(); 0151 0152 /** 0153 * Set file and directory list columns from the configuration. 0154 */ 0155 void readFileAndDirListConfig(); 0156 0157 /** 0158 * Get filename. 0159 */ 0160 QString getFilename() const { return m_nameLineEdit->text(); } 0161 0162 /** 0163 * Set filename. 0164 * @param fn filename 0165 */ 0166 void setFilename(const QString& fn) { m_nameLineEdit->setText(fn); } 0167 0168 /** 0169 * Check if the filename line edit is enabled. 0170 * @return true if the filename line edit is enabled. 0171 */ 0172 bool isFilenameEditEnabled() const { return m_nameLineEdit->isEnabled(); } 0173 0174 /** 0175 * Enable or disable the filename line edit. 0176 * @param en true to enable 0177 */ 0178 void setFilenameEditEnabled(bool en) { m_nameLineEdit->setEnabled(en); } 0179 0180 /** 0181 * Select in the filename line edit. 0182 * @param start start position 0183 * @param length number of characters to select 0184 */ 0185 void setFilenameSelection(int start, int length) { 0186 m_nameLineEdit->setSelection(start, length); 0187 m_nameLineEdit->setFocus(); 0188 } 0189 0190 /** 0191 * Mark the filename as changed. 0192 * @param en true to mark as changed 0193 */ 0194 void markChangedFilename(bool en); 0195 0196 /** 0197 * Set preview picture data. 0198 * @param data picture data, empty if no picture is available 0199 */ 0200 void setPictureData(const QByteArray& data); 0201 0202 /** 0203 * Set details info text. 0204 * 0205 * @param str detail information summary as string 0206 */ 0207 void setDetailInfo(const QString& str); 0208 0209 /** 0210 * Get file list. 0211 * @return file list. 0212 */ 0213 FileList* getFileList() { return m_fileListBox; } 0214 0215 /** 0216 * Get directory list. 0217 * @return directory list. 0218 */ 0219 ConfigurableTreeView* getDirList() { return m_dirListBox; } 0220 0221 /** 0222 * Get frame table. 0223 * @param tagNr tag number 0224 * @return frame table. 0225 */ 0226 FrameTable* frameTable(Frame::TagNumber tagNr) { return m_frameTable[tagNr]; } 0227 0228 /** 0229 * Set a widget to be displayed at the left side instead of the file lists. 0230 * @param widget widget to be shown at the left side 0231 */ 0232 void setLeftSideWidget(QWidget* widget); 0233 0234 /** 0235 * Remove widget set with setLeftSideWidget(). 0236 * 0237 * The widget will not be deleted. 0238 * 0239 * @param widget widget to be removed 0240 */ 0241 void removeLeftSideWidget(QWidget* widget); 0242 0243 public slots: 0244 /** 0245 * Filename line edit is changed. 0246 * @param txt contents of line edit 0247 */ 0248 void nameLineEditChanged(const QString& txt); 0249 0250 /** 0251 * Directory list box directory selected. 0252 * 0253 * @param index selected item 0254 */ 0255 void dirSelected(const QModelIndex& index); 0256 0257 /** 0258 * File list box item activated. 0259 * 0260 * @param index selected item 0261 */ 0262 void fileActivated(const QModelIndex& index); 0263 0264 /** 0265 * Open the parent directory of a model index. 0266 * 0267 * @param index current root index of item view 0268 */ 0269 void openParentDirectory(const QModelIndex& index); 0270 0271 /** 0272 * Set focus on filename controls. 0273 */ 0274 void setFocusFilename(); 0275 0276 /** 0277 * Set focus on tag controls. 0278 * @param tagNr tag number 0279 */ 0280 void setFocusTag(Frame::TagNumber tagNr); 0281 0282 /** 0283 * Set focus on next tag controls. 0284 * @param tagNr current tag, Frame::Tag_NumValues if not on tag 0285 */ 0286 void setFocusNextTag(Frame::TagNumber tagNr); 0287 0288 /** 0289 * Set focus on previous tag controls. 0290 * @param tagNr current tag, Frame::Tag_NumValues if not on tag 0291 */ 0292 void setFocusPreviousTag(Frame::TagNumber tagNr); 0293 0294 /** 0295 * Set focus on file list. 0296 */ 0297 void setFocusFileList(); 0298 0299 /** 0300 * Set focus on directory list. 0301 */ 0302 void setFocusDirList(); 0303 0304 /** 0305 * Select all files. 0306 */ 0307 void selectAllFiles(); 0308 0309 /** 0310 * Deselect all files. 0311 */ 0312 void deselectAllFiles(); 0313 0314 /** 0315 * Set the next file as the current file. 0316 * 0317 * @param select true to select the file 0318 * @param onlyTaggedFiles only consider tagged files 0319 * 0320 * @return true if a next file exists. 0321 */ 0322 bool nextFile(bool select = true, bool onlyTaggedFiles = true); 0323 0324 /** 0325 * Set the previous file as the current file. 0326 * 0327 * @param select true to select the file 0328 * @param onlyTaggedFiles only consider tagged files 0329 * 0330 * @return true if a previous file exists. 0331 */ 0332 bool previousFile(bool select = true, bool onlyTaggedFiles = true); 0333 0334 /** 0335 * Select the next tagged file as the current file. 0336 * Same as nextFile() with default arguments, provided for functor-based 0337 * connections. 0338 * @return true if a next file exists. 0339 */ 0340 bool selectNextTaggedFile(); 0341 0342 /** 0343 * Select the previous tagged file as the current file. 0344 * Same as previousFile() with default arguments, provided for functor-based 0345 * connections. 0346 * @return true if a previous file exists. 0347 */ 0348 bool selectPreviousTaggedFile(); 0349 0350 /** 0351 * Set the root index of the file list. 0352 * 0353 * @param index root index of directory in file system model 0354 */ 0355 void setFileRootIndex(const QModelIndex& index); 0356 0357 /** 0358 * Set the root index of the directory list. 0359 * 0360 * @param index root index of directory in directory model 0361 */ 0362 void setDirRootIndex(const QModelIndex& index); 0363 0364 protected: 0365 /** 0366 * Accept drag. 0367 * 0368 * @param ev drag event. 0369 */ 0370 void dragEnterEvent(QDragEnterEvent* ev) override; 0371 0372 /** 0373 * Handle event when mouse is moved while dragging. 0374 * 0375 * @param ev drag event. 0376 */ 0377 void dragMoveEvent(QDragMoveEvent* ev) override; 0378 0379 /** 0380 * Handle event when mouse leaves widget while dragging. 0381 * 0382 * @param ev drag event. 0383 */ 0384 void dragLeaveEvent(QDragLeaveEvent* ev) override; 0385 0386 /** 0387 * Handle drop event. 0388 * 0389 * @param ev drop event. 0390 */ 0391 void dropEvent(QDropEvent* ev) override; 0392 0393 private slots: 0394 /** 0395 * Toggle visibility of file controls. 0396 */ 0397 void showHideFile(); 0398 0399 /** 0400 * Set format text configuration when format edit text is changed. 0401 * @param text format text 0402 */ 0403 void onFormatEditTextChanged(const QString& text); 0404 0405 /** 0406 * Set format from filename text configuration when edit text is changed. 0407 * @param text format text 0408 */ 0409 void onFormatFromFilenameEditTextChanged(const QString& text); 0410 0411 /** 0412 * Update sorting after directory is opened for the first time. 0413 * The sort order of the file list is not correct if it is not explicitly 0414 * sorted the first time. 0415 */ 0416 void onFirstDirectoryOpened(); 0417 0418 /** 0419 * Copy tags using QAction::data(). 0420 * The source and destination tag numbers are taken from the first two bytes 0421 * in QAction::data().toByteArray() if the sender() is a QAction. 0422 */ 0423 void copyTagsActionData(); 0424 0425 /** 0426 * Set items of "Format <arrow up>" combo box from file configuration. 0427 */ 0428 void setToFilenameFormats(); 0429 0430 /** 0431 * Set items of "Format <arrow down>" combo box from file configuration. 0432 */ 0433 void setFromFilenameFormats(); 0434 0435 private: 0436 /** 0437 * Format string within line edit. 0438 * 0439 * @param le line edit 0440 * @param txt text in line edit 0441 * @param fcfg format configuration 0442 */ 0443 void formatLineEdit(QLineEdit* le, const QString& txt, 0444 const FormatConfig* fcfg); 0445 0446 /** 0447 * Get frame table which is currently in editing state. 0448 * The returned frame table can be used to restore the editing state after 0449 * changing the current file. 0450 * @return frame table which is in editing state, 0 if none. 0451 */ 0452 FrameTable* getEditingFrameTable() const; 0453 0454 FileList* m_fileListBox; 0455 QComboBox* m_formatComboBox; 0456 QComboBox* m_formatFromFilenameComboBox; 0457 QLabel* m_nameLabel; 0458 QLineEdit* m_nameLineEdit; 0459 ConfigurableTreeView* m_dirListBox; 0460 Kid3FormTagContext* m_tagContext[Frame::Tag_NumValues]; 0461 FrameTable* m_frameTable[Frame::Tag_NumValues]; 0462 QStackedWidget* m_leftSideWidget; 0463 QSplitter* m_vSplitter; 0464 QWidget* m_fileWidget; 0465 QWidget* m_tagWidget[Frame::Tag_NumValues]; 0466 QToolButton* m_fileButton; 0467 QToolButton* m_tagButton[Frame::Tag_NumValues]; 0468 QLabel* m_fileLabel; 0469 QLabel* m_tagLabel[Frame::Tag_NumValues]; 0470 QPushButton* m_fnButton[Frame::Tag_NumValues]; 0471 QPushButton* m_toTagButton[Frame::Tag_NumValues]; 0472 QPushButton* m_id3PushButton[Frame::Tag_NumValues]; 0473 QWidget* m_rightHalfVBox; 0474 PictureLabel* m_pictureLabel; 0475 Kid3Application* m_app; 0476 BaseMainWindowImpl* m_mainWin; 0477 QScopedPointer<AbstractFileDecorationProvider> m_iconProvider; 0478 QList<SectionActions*> m_sectionActions; 0479 0480 /** Collapse pixmap, will be allocated in constructor */ 0481 static QPixmap* s_collapsePixmap; 0482 /** Expand pixmap, will be allocated in constructor */ 0483 static QPixmap* s_expandPixmap; 0484 }; 0485 0486 /** 0487 * Facade to have a uniform interface for different tags. 0488 */ 0489 class KID3_GUI_EXPORT Kid3FormTagContext : public QObject { 0490 Q_OBJECT 0491 public: 0492 /** 0493 * Constructor. 0494 * @param form GUI form 0495 * @param tagNr tag number 0496 */ 0497 Kid3FormTagContext(Kid3Form* form, Frame::TagNumber tagNr) : QObject(form), 0498 m_form(form), m_tagNr(tagNr) { 0499 } 0500 0501 public slots: 0502 /** 0503 * Set focus on tag controls. 0504 */ 0505 void setFocusTag() { m_form->setFocusTag(m_tagNr); } 0506 0507 /** 0508 * Toggle visibility of tag controls. 0509 */ 0510 void showHideTag() { m_form->showHideTag(m_tagNr); } 0511 0512 private: 0513 Kid3Form* const m_form; 0514 const Frame::TagNumber m_tagNr; 0515 };