1 /** 2 * \file kid3application.h 3 * Kid3 application logic, independent of GUI. 4 * 5 * \b Project: Kid3 6 * \author Urs Fleisch 7 * \date 10 Jul 2011 8 * 9 * Copyright (C) 2011-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 <QPersistentModelIndex> 31 #include <QScopedPointer> 32 #include <QItemSelectionModel> 33 #include "frame.h" 34 #include "framelist.h" 35 #include "fileproxymodel.h" 36 #include "dirproxymodel.h" 37 #include "frametablemodel.h" 38 #include "genremodel.h" 39 #include "downloadclient.h" 40 #include "batchimporter.h" 41 #include "dirrenamer.h" 42 #include "frameeditorobject.h" 43 #include "taggedfileselection.h" 44 #include "trackdata.h" 45 #include "tagsearcher.h" 46 #include "generalconfig.h" 47 #include "config.h" 48 49 class QItemSelection; 50 class QModelIndex; 51 class QNetworkAccessManager; 52 class QDir; 53 class QUrl; 54 class FileSystemModel; 55 class FileProxyModelIterator; 56 class TrackDataModel; 57 class ConfigStore; 58 class PlaylistConfig; 59 class PlaylistModel; 60 class TaggedFile; 61 class IFrameEditor; 62 class ServerImporter; 63 class ServerTrackImporter; 64 class ITaggedFileFactory; 65 class TextExporter; 66 class BatchImportProfile; 67 class Kid3ApplicationTagContext; 68 class IAbortable; 69 class ICorePlatformTools; 70 class IUserCommandProcessor; 71 class ImageDataProvider; 72 class FileFilter; 73 74 /** 75 * Kid3 application logic, independent of GUI. 76 */ 77 class KID3_CORE_EXPORT Kid3Application : public QObject { 78 Q_OBJECT 79 /** File proxy model. */ 80 Q_PROPERTY(FileProxyModel* fileProxyModel READ getFileProxyModel CONSTANT) 81 /** Directory proxy model. */ 82 Q_PROPERTY(DirProxyModel* dirProxyModel READ getDirProxyModel CONSTANT) 83 /** File selection model. */ 84 Q_PROPERTY(QItemSelectionModel* fileSelectionModel READ getFileSelectionModel CONSTANT) 85 /** Directory selection model. */ 86 Q_PROPERTY(QItemSelectionModel* dirSelectionModel READ getDirSelectionModel CONSTANT) 87 /** Information about selected tagged files. */ 88 Q_PROPERTY(TaggedFileSelection* selectionInfo READ selectionInfo CONSTANT) 89 /** Root index of opened directory in file proxy model. */ 90 Q_PROPERTY(QModelIndex fileRootIndex READ getRootIndex NOTIFY fileRootIndexChanged) 91 /** Root index of opened directory in directory proxy model. */ 92 Q_PROPERTY(QModelIndex dirRootIndex READ getDirRootIndex NOTIFY dirRootIndexChanged) 93 /** Directory name. */ 94 Q_PROPERTY(QString dirName READ getDirName NOTIFY dirNameChanged) 95 /** Modification state. */ 96 Q_PROPERTY(bool modified READ isModified NOTIFY modifiedChanged) 97 /** Filtered state. */ 98 Q_PROPERTY(bool filtered READ isFiltered WRITE setFiltered NOTIFY filteredChanged) 99 /** Number of files which have passed the filter. */ 100 Q_PROPERTY(int filterPassedCount READ filterPassedCount NOTIFY fileFiltered) 101 /** Total number of files checked by filter. */ 102 Q_PROPERTY(int filterTotalCount READ filterTotalCount NOTIFY fileFiltered) 103 /** Frame editor. */ 104 Q_PROPERTY(FrameEditorObject* frameEditor READ frameEditor WRITE setFrameEditor 105 NOTIFY frameEditorChanged) 106 /** ID to get cover art image. */ 107 Q_PROPERTY(QString coverArtImageId READ coverArtImageId 108 NOTIFY coverArtImageIdChanged) 109 /** Directory renamer. */ 110 Q_PROPERTY(DirRenamer* dirRenamer READ getDirRenamer CONSTANT) 111 /** Batch importer. */ 112 Q_PROPERTY(BatchImporter* batchImporter READ getBatchImporter CONSTANT) 113 /** Download client */ 114 Q_PROPERTY(DownloadClient* downloadClient READ getDownloadClient CONSTANT) 115 Q_FLAGS(NumberTrackOption NumberTrackOptions) 116 public: 117 /** Destination for downloadImage(). */ 118 enum DownloadImageDestination { 119 ImageForSelectedFiles, /**< only for current file */ 120 ImageForAllFilesInDirectory, /**< for all files in directory */ 121 ImageForImportTrackData /**< for enabled files in m_trackDataModel */ 122 }; 123 124 /** Options for numberTracks(). */ 125 enum NumberTrackOption { 126 NumberTracksEnabled = 1, /**< Enable track numbering */ 127 NumberTracksResetCounterForEachDirectory = 2 /**< Reset counter */ 128 }; 129 Q_DECLARE_FLAGS(NumberTrackOptions, NumberTrackOption) 130 131 /** 132 * Constructor. 133 * @param platformTools platform tools 134 * @param parent parent object 135 */ 136 explicit Kid3Application(ICorePlatformTools* platformTools, 137 QObject* parent = nullptr); 138 139 /** 140 * Destructor. 141 */ 142 virtual ~Kid3Application() override; 143 144 #ifdef HAVE_QTDBUS 145 /** 146 * Activate the D-Bus interface. 147 * This method shall be called only once at initialization. 148 */ 149 void activateDbusInterface(); 150 #endif 151 152 /** 153 * Get platform tools. 154 * @return platform tools. 155 */ getPlatformTools()156 ICorePlatformTools* getPlatformTools() { return m_platformTools; } 157 158 /** 159 * Get file system model. 160 * @return file system model. 161 */ getFileSystemModel()162 FileSystemModel* getFileSystemModel() { return m_fileSystemModel; } 163 164 /** 165 * Get file proxy model. 166 * @return file proxy model. 167 */ getFileProxyModel()168 FileProxyModel* getFileProxyModel() { return m_fileProxyModel; } 169 170 /** 171 * Get file proxy model iterator. 172 * @return file proxy model iterator. 173 */ getFileProxyModelIterator()174 FileProxyModelIterator* getFileProxyModelIterator() { 175 return m_fileProxyModelIterator; 176 } 177 178 /** 179 * Get directory proxy model. 180 * @return directory proxy model. 181 */ getDirProxyModel()182 DirProxyModel* getDirProxyModel() { return m_dirProxyModel; } 183 184 /** 185 * Get track data model. 186 * @return track data model. 187 */ getTrackDataModel()188 TrackDataModel* getTrackDataModel() { return m_trackDataModel; } 189 190 /** 191 * Get selection model of files. 192 */ getFileSelectionModel()193 QItemSelectionModel* getFileSelectionModel() { return m_fileSelectionModel; } 194 195 /** 196 * Get selection model of directories. 197 */ getDirSelectionModel()198 QItemSelectionModel* getDirSelectionModel() { return m_dirSelectionModel; } 199 200 /** 201 * Store index of directory from where "directory up" (..) is activated. 202 * This directory will then be selected in the new (parent) directory. 203 * 204 * @param index model index of target directory entered when going up 205 */ setDirUpIndex(const QPersistentModelIndex & index)206 void setDirUpIndex(const QPersistentModelIndex& index) { 207 m_dirUpIndex = index; 208 } 209 210 /** 211 * Get genre model. 212 * @param tagNr tag number 213 * @return genre model. 214 */ genreModel(Frame::TagNumber tagNr)215 GenreModel* genreModel(Frame::TagNumber tagNr) const { return m_genreModel[tagNr]; } 216 217 /** 218 * Get frame table model. 219 * @param tagNr tag number 220 * @return frame table. 221 */ frameModel(Frame::TagNumber tagNr)222 FrameTableModel* frameModel(Frame::TagNumber tagNr) { return m_framesModel[tagNr]; } 223 224 /** 225 * Get selection model of frame table model. 226 * @param tagNr tag number 227 * @return selection model. 228 */ getFramesSelectionModel(Frame::TagNumber tagNr)229 QItemSelectionModel* getFramesSelectionModel(Frame::TagNumber tagNr) { 230 return m_framesSelectionModel[tagNr]; 231 } 232 233 /** 234 * Get frame list. 235 * @param tagNr tag number 236 * @return frame list. 237 */ getFrameList(Frame::TagNumber tagNr)238 FrameList* getFrameList(Frame::TagNumber tagNr) { return m_framelist[tagNr]; } 239 240 /** 241 * Get settings. 242 * @return settings. 243 */ 244 ISettings* getSettings() const; 245 246 /** 247 * Get download client. 248 * @return download client. 249 */ getDownloadClient()250 DownloadClient* getDownloadClient() { return m_downloadClient; } 251 252 /** 253 * Get text exporter. 254 * @return text exporter. 255 */ getTextExporter()256 TextExporter* getTextExporter() { return m_textExporter; } 257 258 /** 259 * Get available server importers. 260 * @return list of server importers. 261 */ getServerImporters()262 QList<ServerImporter*> getServerImporters() { return m_importers; } 263 264 /** 265 * Get names of available server track importers. 266 * @return list of server track importer names. 267 */ 268 Q_INVOKABLE QStringList getServerImporterNames() const; 269 270 /** 271 * Get available server track importers. 272 * @return list of server track importers. 273 */ getServerTrackImporters()274 QList<ServerTrackImporter*> getServerTrackImporters() { 275 return m_trackImporters; 276 } 277 278 /** 279 * Get available user command processors. 280 * @return list of user command processors. 281 */ getUserCommandProcessors()282 QList<IUserCommandProcessor*> getUserCommandProcessors() { 283 return m_userCommandProcessors; 284 } 285 286 /** 287 * Get tag searcher. 288 * @return tag searcher. 289 */ getTagSearcher()290 TagSearcher* getTagSearcher() const { return m_tagSearcher; } 291 292 /** 293 * Get directory renamer. 294 * @return directory renamer. 295 */ getDirRenamer()296 DirRenamer* getDirRenamer() { return m_dirRenamer; } 297 298 /** 299 * Get batch importer. 300 * @return batch importer. 301 */ getBatchImporter()302 BatchImporter* getBatchImporter() { return m_batchImporter; } 303 304 /** 305 * Get audio player. 306 * This method will create an audio player if it does not already exist. 307 * The returned audio player can be deleted after this call, so objects which 308 * hold a pointer must be deleted before deleteAudioPlayer() is called! 309 * @return audio player. 310 */ 311 Q_INVOKABLE QObject* getAudioPlayer(); 312 313 /** 314 * Delete audio player. 315 */ 316 void deleteAudioPlayer(); 317 318 /** 319 * Get context for tag. 320 * @param tagNr tag number 321 * @return tag context. 322 */ tag(Frame::TagNumber tagNr)323 Q_INVOKABLE Kid3ApplicationTagContext* tag(Frame::TagNumber tagNr) const { 324 return m_tagContext[tagNr]; 325 } 326 327 /** 328 * Get current index in file proxy model or root index if current index is 329 * invalid. 330 * @return current index, root index if not valid. 331 */ 332 QModelIndex currentOrRootIndex() const; 333 334 /** 335 * Apply configuration changes. 336 */ 337 Q_INVOKABLE void applyChangedConfiguration(); 338 339 /** 340 * Save settings to the configuration. 341 */ 342 Q_INVOKABLE void saveConfig(); 343 344 /** 345 * Read settings from the configuration. 346 */ 347 Q_INVOKABLE void readConfig(); 348 349 /** 350 * Open directory. 351 * When finished directoryOpened() is emitted, also if false is returned. 352 * 353 * @param paths file or directory paths, if multiple paths are given, the 354 * common directory is opened and the files are selected 355 * @param fileCheck if true, only open directory if paths exist 356 * 357 * @return true if ok. 358 */ 359 Q_INVOKABLE bool openDirectory(const QStringList& paths, bool fileCheck = false); 360 361 /** 362 * Get root index of opened directory in file proxy model. 363 * @return index of directory root. 364 */ getRootIndex()365 QPersistentModelIndex getRootIndex() const { 366 return m_fileProxyModelRootIndex; 367 } 368 369 /** 370 * Get root index of opened directory in directory proxy model. 371 * @return index of directory root. 372 */ getDirRootIndex()373 QPersistentModelIndex getDirRootIndex() const { 374 return m_dirProxyModelRootIndex; 375 } 376 377 /** 378 * Get directory path of opened directory. 379 * @return directory path. 380 */ 381 QString getDirPath() const; 382 383 /** 384 * Handle drop of URLs. 385 * 386 * @param urlList picture, tagged file and folder URLs to handle (if local) 387 * @param isInternal true if this is an internal drop 388 */ 389 void dropUrls(const QList<QUrl>& urlList, bool isInternal); 390 391 /** 392 * Open directory after resetting the file system model. 393 * When finished directoryOpened() is emitted, also if false is returned. 394 * 395 * @param paths file or directory paths, if multiple paths are given, the 396 * common directory is opened and the files are selected, if empty, the 397 * currently open directory is reopened 398 * 399 * @return true if ok. 400 */ 401 bool openDirectoryAfterReset(const QStringList& paths = QStringList()); 402 403 /** 404 * Save all changed files. 405 * longRunningOperationProgress() is emitted while saving files. 406 * 407 * @return list of files with error, empty if ok. 408 */ 409 Q_INVOKABLE QStringList saveDirectory(); 410 411 /** 412 * Update tags of selected files to contain contents of frame models. 413 */ 414 Q_INVOKABLE void frameModelsToTags(); 415 416 /** 417 * Update frame models to contain contents of selected files. 418 * The properties starting with "selection" will be set by this method. 419 */ 420 Q_INVOKABLE void tagsToFrameModels(); 421 422 /** 423 * Update frame models to contain contents of item selection. 424 * The properties starting with "selection" will be set by this method. 425 * @param selected item selection 426 */ 427 void selectedTagsToFrameModels(const QItemSelection& selected); 428 429 /** 430 * Access to information about selected tagged files. 431 * @return selection information. 432 */ selectionInfo()433 TaggedFileSelection* selectionInfo() const { return m_selection; } 434 435 /** 436 * Import. 437 * 438 * @param tagMask tag mask 439 * @param path path of file, "clipboard" for import from clipboard 440 * @param fmtIdx index of format 441 * 442 * @return true if ok. 443 */ 444 Q_INVOKABLE bool importTags(Frame::TagVersion tagMask, const QString& path, 445 int fmtIdx); 446 447 /** 448 * Import from tags. 449 * 450 * @param tagMask tag mask 451 * @param source format to get source text from tags 452 * @param extraction regular expression with frame names and captures to 453 * extract from source text 454 */ 455 Q_INVOKABLE void importFromTags(Frame::TagVersion tagMask, 456 const QString& source, 457 const QString& extraction); 458 459 /** 460 * Import from tags on selected files. 461 * 462 * @param tagMask tag mask 463 * @param source format to get source text from tags 464 * @param extraction regular expression with frame names and captures to 465 * extract from source text 466 * 467 * @return extracted values for "%{__return}(.+)", empty if not used. 468 */ 469 Q_INVOKABLE QStringList importFromTagsToSelection(Frame::TagVersion tagMask, 470 const QString& source, 471 const QString& extraction); 472 473 /** 474 * Export. 475 * 476 * @param tagVersion tag version 477 * @param path path of file, "clipboard" for export to clipboard 478 * @param fmtIdx index of format 479 * 480 * @return true if ok. 481 */ 482 Q_INVOKABLE bool exportTags(Frame::TagVersion tagVersion, 483 const QString& path, int fmtIdx); 484 485 /** 486 * Write playlist according to playlist configuration. 487 * 488 * @param cfg playlist configuration to use 489 * 490 * @return true if ok. 491 */ 492 bool writePlaylist(const PlaylistConfig& cfg); 493 494 /** 495 * Write empty playlist. 496 * @param cfg playlist configuration to use 497 * @param fileName file name for playlist 498 * @return true if ok. 499 */ 500 bool writeEmptyPlaylist(const PlaylistConfig& cfg, const QString& fileName); 501 502 /** 503 * Write playlist using current playlist configuration. 504 * 505 * @return true if ok. 506 */ 507 Q_INVOKABLE bool writePlaylist(); 508 509 /** 510 * Get items of a playlist. 511 * @param path path to playlist file 512 * @return list of absolute paths to playlist items. 513 */ 514 Q_INVOKABLE QStringList getPlaylistItems(const QString& path); 515 516 /** 517 * Set items of a playlist. 518 * @param path path to playlist file 519 * @param items list of absolute paths to playlist items 520 * @return true if ok, false if not all @a items were found and added or 521 * saving failed. 522 */ 523 Q_INVOKABLE bool setPlaylistItems(const QString& path, const QStringList& items); 524 525 /** 526 * Get playlist model for a play list file. 527 * @param path path to playlist file 528 * @return playlist model. 529 */ 530 PlaylistModel* playlistModel(const QString& path); 531 532 /** 533 * Check if any playlist model has unsaved modifications. 534 * @return true if there is a modified playlist model. 535 */ 536 bool hasModifiedPlaylistModel() const; 537 538 /** 539 * Save all modified playlist models. 540 */ 541 void saveModifiedPlaylistModels(); 542 543 /** 544 * Perform rename actions and change application directory afterwards if it 545 * was renamed. 546 * 547 * @return error messages, null string if no error occurred. 548 */ 549 Q_INVOKABLE QString performRenameActions(); 550 551 /** 552 * Reset the file system model and then try to perform the rename actions. 553 * On Windows, renaming directories fails when they have a subdirectory which 554 * is open in the file system model. This method can be used to retry in such 555 * a situation. 556 */ 557 void tryRenameActionsAfterReset(); 558 559 /** 560 * Reset the file system model and then try to rename a file. 561 * On Windows, renaming directories fails when they have a subdirectory which 562 * is open in the file system model. This method can be used to retry in such 563 * a situation. 564 * 565 * @param oldName old file name 566 * @param newName new file name 567 */ 568 void tryRenameAfterReset(const QString& oldName, const QString& newName); 569 570 /** 571 * Set the directory name from the tags. 572 * The directory must not have modified files. 573 * renameActionsScheduled() is emitted when the rename actions have been 574 * scheduled. Then performRenameActions() has to be called to effectively 575 * rename the directory. 576 * 577 * @param tagMask tag mask 578 * @param format directory name format 579 * @param create true to create, false to rename 580 * 581 * @return true if ok. 582 */ 583 Q_INVOKABLE bool renameDirectory(Frame::TagVersion tagMask, 584 const QString& format, bool create); 585 586 /** 587 * Number tracks in selected files of directory. 588 * 589 * @param nr start number 590 * @param total total number of tracks, used if >0 591 * @param tagVersion determines on which tags the numbers are set 592 * @param options options for numbering operation 593 */ 594 Q_INVOKABLE void numberTracks(int nr, int total, Frame::TagVersion tagVersion, 595 Kid3Application::NumberTrackOptions options = {}); 596 597 /** 598 * Set track data with tagged files of directory. 599 * 600 * @param tagVersion tag version 601 * @param trackDataList is filled with track data 602 */ 603 void filesToTrackData(Frame::TagVersion tagVersion, 604 ImportTrackDataVector& trackDataList); 605 606 /** 607 * Set track data model with tagged files of directory. 608 * 609 * @param tagVersion tag version 610 */ 611 void filesToTrackDataModel(Frame::TagVersion tagVersion); 612 613 /** 614 * Set tagged files of directory from track data model. 615 * 616 * @param tagVersion tags to set 617 */ 618 void trackDataModelToFiles(Frame::TagVersion tagVersion); 619 620 /** 621 * Download an image file. 622 * 623 * @param url URL of image 624 * @param dest specifies affected files 625 */ 626 void downloadImage(const QUrl& url, DownloadImageDestination dest); 627 628 /** 629 * Download an image file. 630 * 631 * @param url URL of image 632 * @param allFilesInDir true to add the image to all files in the directory 633 */ 634 Q_INVOKABLE void downloadImage(const QString& url, bool allFilesInDir); 635 636 /** 637 * Get value of frame. 638 * To get binary data like a picture, the name of a file to write can be 639 * added after the @a name, e.g. "Picture:/path/to/file". 640 * 641 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 642 * @param name name of frame (e.g. "artist") 643 * 644 * @return value of frame. 645 */ 646 Q_INVOKABLE QString getFrame(Frame::TagVersion tagMask, 647 const QString& name) const; 648 649 /** 650 * Get names and values of all frames. 651 * 652 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 653 * 654 * @return map containing frame values. 655 */ 656 Q_INVOKABLE QVariantMap getAllFrames(Frame::TagVersion tagMask) const; 657 658 /** 659 * Set value of frame. 660 * For tag 2 (@a tagMask 2), if no frame with @a name exists, a new frame 661 * is added, if @a value is empty, the frame is deleted. 662 * To add binary data like a picture, a file can be added after the 663 * @a name, e.g. "Picture:/path/to/file". 664 * 665 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 666 * @param name name of frame (e.g. "artist") 667 * @param value value of frame 668 * 669 * @return true if ok. 670 */ 671 Q_INVOKABLE bool setFrame(Frame::TagVersion tagMask, const QString& name, 672 const QString& value); 673 674 /** 675 * Get data from picture frame. 676 * @return picture data, empty if not found. 677 */ 678 Q_INVOKABLE QByteArray getPictureData() const; 679 680 /** 681 * Set data in picture frame. 682 * @param data picture data 683 */ 684 Q_INVOKABLE void setPictureData(const QByteArray& data); 685 686 /** 687 * Format frames if format while editing is switched on. 688 * 689 * @param frames frames 690 */ 691 void formatFramesIfEnabled(FrameCollection& frames) const; 692 693 /** 694 * Add picture on drop. 695 * 696 * @param frame dropped picture frame 697 */ 698 void dropImage(Frame* frame); 699 700 /** 701 * Handle URL on drop. 702 * 703 * @param url dropped URL. 704 */ 705 void dropUrl(const QUrl& url); 706 707 /** 708 * Get number of tracks in current directory. 709 * 710 * @return number of tracks, 0 if not found. 711 */ 712 Q_INVOKABLE int getTotalNumberOfTracksInDir(); 713 714 /** 715 * Get name of selected file. 716 * 717 * @return absolute file name, ends with "/" if it is a directory. 718 */ 719 QString getFileNameOfSelectedFile(); 720 721 /** 722 * Create a filter string for the file dialog. 723 * The filter string contains entries for all supported types. 724 * 725 * @return filter string. 726 */ 727 Q_INVOKABLE QString createFilterString() const; 728 729 730 /** 731 * Remove the file filter if necessary to open the files. 732 * @param filePaths paths to files or directories 733 */ 734 void resetFileFilterIfNotMatching(const QStringList& filePaths); 735 736 /** 737 * Get image destination set by downloadImage(). 738 * @return image destination. 739 */ getDownloadImageDestination()740 DownloadImageDestination getDownloadImageDestination() const { 741 return m_downloadImageDest; 742 } 743 744 /** 745 * Check modification state. 746 * 747 * @return true if a file is modified. 748 */ 749 bool isModified() const; 750 751 /** 752 * Set filter state. 753 * 754 * @param val true if list is filtered 755 */ 756 void setFiltered(bool val); 757 758 /** 759 * Check filter state. 760 * 761 * @return true if list is filtered. 762 */ isFiltered()763 bool isFiltered() const { return m_filtered; } 764 765 /** 766 * Get number of files which have passed the filter. 767 * 768 * This number is only valid if isFiltered() is true. 769 * 770 * @return number of files which have passed the filter. 771 */ filterPassedCount()772 int filterPassedCount() const { return m_filterPassed; } 773 774 /** 775 * Get total number of files which have been checked by the filter. 776 * 777 * This number is only valid if isFiltered() is true. 778 * 779 * @return total number of files checked by filter. 780 */ filterTotalCount()781 int filterTotalCount() const { return m_filterTotal; } 782 783 /** 784 * Get the selected file. 785 * 786 * @return the selected file, 787 * 0 if not exactly one file is selected 788 */ 789 TaggedFile* getSelectedFile(); 790 791 /** 792 * Get the stored current selection. 793 * @return stored selection. 794 */ getCurrentSelection()795 const QList<QPersistentModelIndex>& getCurrentSelection() const { 796 return m_currentSelection; 797 } 798 799 /** 800 * Update the stored current selection with the list of all selected items. 801 */ 802 void updateCurrentSelection(); 803 804 /** 805 * Get directory name. 806 * @return directory. 807 */ getDirName()808 QString getDirName() const { return m_dirName; } 809 810 /** 811 * Get frame editor set with setFrameEditor(). 812 * @return frame editor, null if no frame editor is set 813 */ frameEditor()814 FrameEditorObject* frameEditor() const { return m_frameEditor; } 815 816 /** 817 * Set a frame editor object to act as the frame editor. 818 * @param frameEditor frame editor object, null to disable 819 */ 820 void setFrameEditor(FrameEditorObject* frameEditor); 821 822 /** 823 * Remove frame editor. 824 * Has to be called in the destructor of the frame editor to avoid a dangling 825 * pointer to a deleted object. 826 * @param frameEditor frame editor 827 */ 828 void removeFrameEditor(IFrameEditor* frameEditor); 829 830 /** 831 * Get ID to get cover art image. 832 * @return ID for cover art image. 833 */ coverArtImageId()834 QString coverArtImageId() const { return m_coverArtImageId; } 835 836 /** 837 * Set the image provider. 838 * @param imageProvider image provider 839 */ 840 void setImageProvider(ImageDataProvider* imageProvider); 841 842 /** 843 * Get the numbers of the selected rows in a list suitable for scripting. 844 * @return list with row numbers. 845 */ 846 Q_INVOKABLE QVariantList getFileSelectionRows(); 847 848 /** 849 * Set the file selection from a list of model indexes. 850 * @param indexes list of model indexes suitable for scripting 851 */ 852 Q_INVOKABLE void setFileSelectionIndexes(const QVariantList& indexes); 853 854 /** 855 * Get paths to all selected files. 856 * @param onlyTaggedFiles only consider tagged files 857 * @return list of absolute file paths. 858 */ 859 Q_INVOKABLE QStringList getSelectedFilePaths(bool onlyTaggedFiles = true) 860 const; 861 862 /** 863 * Set picture data for image provider. 864 * @param picture picture data 865 */ 866 Q_INVOKABLE void setCoverArtImageData(const QByteArray& picture); 867 868 /** 869 * Open a file select dialog to get a file name. 870 * For script support, is only supported when a GUI is available. 871 * @param caption dialog caption 872 * @param dir working directory 873 * @param filter file type filter 874 * @param saveFile true to open a save file dialog 875 * @return selected file, empty if canceled. 876 */ 877 Q_INVOKABLE QString selectFileName( 878 const QString& caption = QString(), const QString& dir = QString(), 879 const QString& filter = QString(), bool saveFile = false); 880 881 /** 882 * Open a file select dialog to get a directory name. 883 * For script support, is only supported when a GUI is available. 884 * @param caption dialog caption 885 * @param dir working directory 886 * @return selected directory, empty if canceled. 887 */ 888 Q_INVOKABLE QString selectDirName( 889 const QString& caption = QString(), const QString& dir = QString()); 890 891 /** 892 * Notify the tagged file factories about the changed configuration. 893 */ 894 static void notifyConfigurationChange(); 895 896 /** 897 * Find directory containing plugins. 898 * @param pluginsDir the plugin directory is returned here 899 * @return true if found. 900 */ 901 static bool findPluginsDirectory(QDir& pluginsDir); 902 903 /** 904 * Set fallback path for directory containing plugins. 905 * @param path path to be searched for plugins if they are not found at the 906 * standard location relative to the application directory 907 */ 908 static void setPluginsPathFallback(const QString& path); 909 910 /** 911 * Load plugins. 912 * @return list of plugin instances. 913 */ 914 static QObjectList loadPlugins(); 915 916 public slots: 917 /** 918 * Open directory or add pictures on drop. 919 * 920 * @param paths paths of directories or files in directory 921 */ 922 void openDrop(const QStringList& paths); 923 924 /** 925 * Handle drop of URLs. 926 * 927 * @param urlList picture, tagged file and folder URLs to handle (if local) 928 */ 929 void openDropUrls(const QList<QUrl>& urlList); 930 931 /** 932 * Unload all tags. 933 * The tags of all files which are not modified or selected are freed to 934 * reclaim their memory. 935 */ 936 void unloadAllTags(); 937 938 /** 939 * Revert file modifications. 940 * Acts on selected files or all files if no file is selected. 941 */ 942 void revertFileModifications(); 943 944 /** 945 * Set name of selected file. 946 * Exactly one file has to be selected. 947 * 948 * @param name file name. 949 */ 950 void setFileNameOfSelectedFile(const QString& name); 951 952 /** 953 * Apply filename format. 954 */ 955 void applyFilenameFormat(); 956 957 /** 958 * Apply tag format. 959 */ 960 void applyTagFormat(); 961 962 /** 963 * Apply text encoding. 964 * Set the text encoding selected in the settings Tags/ID3v2/Text encoding 965 * for all selected files which have an ID3v2 tag. 966 */ 967 void applyTextEncoding(); 968 969 /** 970 * Convert ID3v2.3 to ID3v2.4 tags. 971 */ 972 void convertToId3v24(); 973 974 /** 975 * Convert ID3v2.4 to ID3v2.3 tags. 976 */ 977 void convertToId3v23(); 978 979 /** 980 * Copy tags into copy buffer. 981 * 982 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 983 */ 984 void copyTags(Frame::TagVersion tagMask); 985 986 /** 987 * Paste from copy buffer to tags. 988 * 989 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 990 */ 991 void pasteTags(Frame::TagVersion tagMask); 992 993 /** 994 * Set tag from other tag. 995 * 996 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 997 */ 998 void copyToOtherTag(Frame::TagVersion tagMask); 999 1000 /** 1001 * Copy from a tag to another tag. 1002 * @param srcTagNr source tag number 1003 * @param dstTagNr destination tag number 1004 */ 1005 void copyTag(Frame::TagNumber srcTagNr, Frame::TagNumber dstTagNr); 1006 1007 /** 1008 * Remove tags in selected files. 1009 * 1010 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 1011 */ 1012 void removeTags(Frame::TagVersion tagMask); 1013 1014 /** 1015 * Set tags according to filename. 1016 * 1017 * @param tagMask tag bit (1 for tag 1, 2 for tag 2) 1018 */ 1019 void getTagsFromFilename(Frame::TagVersion tagMask); 1020 1021 /** 1022 * Set filename according to tags. 1023 * If a single file is selected the tags in the GUI controls 1024 * are used, else the tags in the multiple selected files. 1025 * 1026 * @param tagVersion tag version 1027 */ 1028 void getFilenameFromTags(Frame::TagVersion tagVersion); 1029 1030 /** 1031 * Edit selected frame. 1032 * @param tagNr tag number 1033 */ 1034 void editFrame(Frame::TagNumber tagNr); 1035 1036 /** 1037 * Delete selected frame. 1038 * @param tagNr tag number 1039 * @param frameName name of frame to delete, empty to delete selected frame 1040 * @param index 0 for first frame with @a frameName, 1 for second, etc. 1041 */ 1042 void deleteFrame(Frame::TagNumber tagNr, 1043 const QString& frameName = QString(), int index = 0); 1044 1045 /** 1046 * Select a frame type and add such a frame to the frame list. 1047 * @param tagNr tag number 1048 */ 1049 void selectAndAddFrame(Frame::TagNumber tagNr); 1050 1051 /** 1052 * Edit a picture frame if one exists or add a new one. 1053 */ 1054 void editOrAddPicture(); 1055 1056 /** 1057 * Add a downloaded image. 1058 * 1059 * @param data HTTP response of download 1060 * @param mimeType MIME type of data 1061 * @param url URL of downloaded data 1062 */ 1063 void imageDownloaded(const QByteArray& data, 1064 const QString& mimeType, const QString& url); 1065 1066 /** 1067 * Set the first file as the current file. 1068 * 1069 * @param select true to select the file 1070 * @param onlyTaggedFiles only consider tagged files 1071 * 1072 * @return true if a file exists. 1073 */ 1074 bool firstFile(bool select = true, bool onlyTaggedFiles = false); 1075 1076 /** 1077 * Set the next file as the current file. 1078 * 1079 * @param select true to select the file 1080 * @param onlyTaggedFiles only consider tagged files 1081 * 1082 * @return true if a next file exists. 1083 */ 1084 bool nextFile(bool select = true, bool onlyTaggedFiles = false); 1085 1086 /** 1087 * Set the previous file as the current file. 1088 * 1089 * @param select true to select the file 1090 * @param onlyTaggedFiles only consider tagged files 1091 * 1092 * @return true if a previous file exists. 1093 */ 1094 bool previousFile(bool select = true, bool onlyTaggedFiles = false); 1095 1096 /** 1097 * Select or deselect the current file. 1098 * 1099 * @param select true to select the file, false to deselect it 1100 * 1101 * @return true if a current file exists. 1102 */ 1103 bool selectCurrentFile(bool select = true); 1104 1105 /** 1106 * Select all files. 1107 */ 1108 void selectAllFiles(); 1109 1110 /** 1111 * Deselect all files. 1112 */ 1113 void deselectAllFiles(); 1114 1115 /** 1116 * Select all files in the current directory. 1117 */ 1118 void selectAllInDirectory(); 1119 1120 /** 1121 * Invert current selection. 1122 */ 1123 void invertSelection(); 1124 1125 /** 1126 * Set a specific file as the current file. 1127 * 1128 * @param filePath path to file 1129 * @param select true to select the file 1130 * 1131 * @return true if file exists. 1132 */ 1133 bool selectFile(const QString& filePath, bool select = true); 1134 1135 /** 1136 * Fetch entries of directory if not already fetched. 1137 * This works like FileList::expand(), but without expanding tree view 1138 * items and independent of the GUI. The processing is done in the background 1139 * by FileSystemModel, so the fetched items are not immediately available 1140 * after calling this method. 1141 * 1142 * @param index index of directory item 1143 */ 1144 void fetchDirectory(const QModelIndex& index); 1145 1146 /** 1147 * Fetch entries of directory and toggle expanded state if GUI available. 1148 * @param index index of directory item 1149 */ 1150 void expandDirectory(const QModelIndex& index); 1151 1152 /** 1153 * Expand the whole file list if GUI available. 1154 */ 1155 void requestExpandFileList(); 1156 1157 /** 1158 * Called when operation for requestExpandFileList() is finished. 1159 */ 1160 void notifyExpandFileListFinished(); 1161 1162 /** 1163 * Process change of selection. 1164 * The GUI is signaled to update the current selection and the controls. 1165 * @param selected selected items 1166 * @param deselected deselected items 1167 */ 1168 void fileSelected(const QItemSelection& selected, 1169 const QItemSelection& deselected); 1170 1171 /** 1172 * Search in tags for a given text. 1173 * @param params search parameters 1174 */ 1175 void findText(const TagSearcher::Parameters& params); 1176 1177 /** 1178 * Replace found text. 1179 * @param params search parameters 1180 */ 1181 void replaceText(const TagSearcher::Parameters& params); 1182 1183 /** 1184 * Replace all occurrences. 1185 * @param params search parameters 1186 */ 1187 void replaceAll(const TagSearcher::Parameters& params); 1188 1189 /** 1190 * Schedule actions to rename a directory. 1191 * When finished renameActionsScheduled() is emitted. 1192 */ 1193 void scheduleRenameActions(); 1194 1195 /** 1196 * Apply a file filter. 1197 * 1198 * @param fileFilter filter to apply. 1199 */ 1200 void applyFilter(FileFilter& fileFilter); 1201 1202 /** 1203 * Apply a file filter. 1204 * 1205 * @param expression filter expression 1206 */ 1207 void applyFilter(const QString& expression); 1208 1209 /** 1210 * Abort expression file filter. 1211 */ 1212 void abortFilter(); 1213 1214 /** 1215 * Perform a batch import for the selected directories. 1216 * @param profile batch import profile 1217 * @param tagVersion import destination tag versions 1218 */ 1219 void batchImport(const BatchImportProfile& profile, 1220 Frame::TagVersion tagVersion); 1221 1222 /** 1223 * Perform a batch import for the selected directories. 1224 * @param profileName batch import profile name 1225 * @param tagVersion import destination tag versions 1226 * @return true if profile with @a profileName found. 1227 */ 1228 bool batchImport(const QString& profileName, Frame::TagVersion tagVersion); 1229 1230 /** 1231 * Play audio file. 1232 */ 1233 void playAudio(); 1234 1235 /** 1236 * Show play tool bar. 1237 */ 1238 void showAudioPlayer(); 1239 1240 #ifdef HAVE_QTDBUS 1241 /** 1242 * Activate the MPRIS D-Bus Interface if not already active. 1243 */ 1244 void activateMprisInterface(); 1245 1246 /** 1247 * Deactivate the MPRIS D-Bus Interface if it is active. 1248 */ 1249 void deactivateMprisInterface(); 1250 #endif 1251 1252 /** 1253 * Close the file handle of a tagged file. 1254 * @param filePath path to file 1255 */ 1256 void closeFileHandle(const QString& filePath); 1257 1258 signals: 1259 /** 1260 * Emitted when the file proxy model root index changes. 1261 * @param index new root index 1262 */ 1263 void fileRootIndexChanged(const QModelIndex& index); 1264 1265 /** 1266 * Emitted when the directory proxy model root index changes. 1267 * @param index new root index 1268 */ 1269 void dirRootIndexChanged(const QModelIndex& index); 1270 1271 /** 1272 * Emitted when the directory has been opened, the file and directory proxy 1273 * model root indexes changed and the selection updated. 1274 */ 1275 void directoryOpened(); 1276 1277 /** 1278 * Emitted when a confirmed opening of a directory or file is requested. 1279 * @param paths directory or file paths 1280 */ 1281 void confirmedOpenDirectoryRequested(const QStringList& paths); 1282 1283 /** 1284 * Emitted before an operation on the selected files is performed. 1285 * The GUI should update the files of the current selection when 1286 * receiving this signal. 1287 */ 1288 void fileSelectionUpdateRequested(); 1289 1290 /** 1291 * Emitted after an operation on the selected files has been performed. 1292 * The GUI should update its controls from the tags in the files when 1293 * receiving this signal. 1294 */ 1295 void selectedFilesUpdated(); 1296 1297 /** 1298 * Emitted after the file selection is changed. 1299 * The GUI should update its controls from the tags of the new file selection 1300 * when receiving this signal. 1301 * @param selected selected items 1302 * @param deselected deselected items 1303 */ 1304 void selectedFilesChanged(const QItemSelection& selected, 1305 const QItemSelection& deselected); 1306 1307 /** 1308 * Emitted after a frame of a tagged file has been modified. 1309 * The GUI should update the corresponding controls when receiving this 1310 * signal. 1311 * 1312 * @param taggedFile tagged file with modified frame 1313 * @param tagNr tag number 1314 */ 1315 void frameModified(TaggedFile* taggedFile, Frame::TagNumber tagNr); 1316 1317 /** 1318 * Emitted when modification state is changed. 1319 * @param modified true if any file is modified 1320 * @see isModified() 1321 */ 1322 void modifiedChanged(bool modified); 1323 1324 /** 1325 * Emitted when filtered state is changed. 1326 * @param filtered true if file list is filtered 1327 * @see isFiltered(), setFiltered() 1328 */ 1329 void filteredChanged(bool filtered); 1330 1331 /** 1332 * Emitted when the directory name is changed. 1333 * @param name current directory name 1334 */ 1335 void dirNameChanged(const QString& name); 1336 1337 /** 1338 * Emitted when a file is filtered. 1339 * @param type filter event type, enum FileFilter::FilterEventType 1340 * @param fileName name of filtered file 1341 * @param passed number of files which passed the filter 1342 * @param total total number of files checked 1343 */ 1344 void fileFiltered(int type, const QString& fileName, int passed, int total); 1345 1346 /** 1347 * Emitted before an audio file is played. 1348 * The GUI can display a player when receiving this signal. 1349 */ 1350 void aboutToPlayAudio(); 1351 1352 /** 1353 * Emitted when all rename actions have been scheduled. 1354 * @see scheduleRenameActions() 1355 */ 1356 void renameActionsScheduled(); 1357 1358 /** 1359 * Emitted to request toggling of the expanded state of a directory in the 1360 * file list. 1361 * @param index index of directory item 1362 */ 1363 void toggleExpandedRequested(const QModelIndex& index); 1364 1365 /** 1366 * Emitted to request expanding of all directories in the file list. 1367 */ 1368 void expandFileListRequested(); 1369 1370 /** 1371 * Emitted when operation requested by requestExpandFileList() 1372 * (signal expandFileListRequested()) is finished. 1373 */ 1374 void expandFileListFinished(); 1375 1376 /** 1377 * Emitted when the file selection is changed. 1378 * @see getFileSelectionRows() 1379 */ 1380 void fileSelectionChanged(); 1381 1382 /** 1383 * Emitted when a new cover art image is available 1384 * @param id ID of image. 1385 */ 1386 void coverArtImageIdChanged(const QString& id); 1387 1388 /** 1389 * Emitted when the frame editor is changed. 1390 */ 1391 void frameEditorChanged(); 1392 1393 /** 1394 * Emitted to report progress about a long running operation. 1395 * 1396 * This signal is used to report different states of a long running operation. 1397 * - Operation is started: done is -1, 1398 * - Operation is finished: done == total and total is not 0, 1399 * - Operation in progress: done < total or both done and total are 0 1400 * 1401 * @param name name of operation 1402 * @param done amount of work done 1403 * @param total total amount of work 1404 * @param abort if not 0, can be set to true to abort the operation 1405 */ 1406 void longRunningOperationProgress(const QString& name, int done, int total, 1407 bool* abort); 1408 1409 private slots: 1410 /** 1411 * Apply file filter after the file system model has been reset. 1412 */ 1413 void applyFilterAfterReset(); 1414 1415 /** 1416 * Apply single file to file filter. 1417 * 1418 * @param index index of file in file proxy model 1419 */ 1420 void filterNextFile(const QPersistentModelIndex& index); 1421 1422 /** 1423 * Apply single file to batch import. 1424 * 1425 * @param index index of file in file proxy model 1426 */ 1427 void batchImportNextFile(const QPersistentModelIndex& index); 1428 1429 /** 1430 * Schedule rename action for a file. 1431 * 1432 * @param index index of file in file proxy model 1433 */ 1434 void scheduleNextRenameAction(const QPersistentModelIndex& index); 1435 1436 /** 1437 * Perform rename actions after the file system model has been reset. 1438 */ 1439 void performRenameActionsAfterReset(); 1440 1441 /** 1442 * Rename after the file system model has been reset. 1443 */ 1444 void renameAfterReset(); 1445 1446 /** 1447 * Update selection and emit signals when directory is opened. 1448 */ 1449 void onDirectoryOpened(); 1450 1451 /** 1452 * Called when the gatherer thread has finished to load the directory. 1453 */ 1454 void onDirectoryLoaded(); 1455 1456 /** 1457 * Called when a frame is edited. 1458 * @param frame edited frame, 0 if canceled 1459 */ 1460 void onFrameEdited(const Frame* frame); 1461 1462 /** 1463 * Called when a frame is added. 1464 * @param frame added frame, 0 if canceled 1465 * @param tagNr tag number used if slot is not invoked by framelist signal 1466 */ 1467 void onFrameAdded(const Frame* frame, Frame::TagNumber tagNr = Frame::Tag_2); 1468 1469 /** 1470 * Called by framelist when a frame is added. 1471 * Same as onFrameAdded() with default argument, provided for functor-based 1472 * connections. 1473 * @param frame added frame, 0 if canceled 1474 */ 1475 void onTag2FrameAdded(const Frame* frame); 1476 1477 /** 1478 * If an image provider is used, update its picture and change the 1479 * coverArtImageId property if the picture of the selection changed. 1480 * This can be used to change a QML image. 1481 */ 1482 void updateCoverArtImageId(); 1483 1484 /** 1485 * Save config when suspended, check intents when activated. 1486 * @param state application state 1487 */ 1488 void onApplicationStateChanged(Qt::ApplicationState state); 1489 1490 private: 1491 /** 1492 * Load and initialize plugins depending on configuration. 1493 */ 1494 void initPlugins(); 1495 1496 /** 1497 * Check type of a loaded plugin and register it. 1498 * @param plugin instance returned by plugin loader 1499 */ 1500 void checkPlugin(QObject* plugin); 1501 1502 /** 1503 * Update frame models to contain contents of selected files. 1504 * @param indexes tagged file indexes 1505 * @param startSelection true if a new selection is started, false to add to 1506 * the existing selection 1507 * @return true if ok, false if selection operation is already running. 1508 */ 1509 bool addTaggedFilesToSelection( 1510 const QList<QPersistentModelIndex>& indexes, bool startSelection); 1511 1512 /** 1513 * Select a frame type and add such a frame to frame list. 1514 * @param tagNr tag number 1515 * @param frame frame to add, if 0 the user has to select and edit the frame 1516 * @param edit if true and a frame is set, the user can edit the frame before 1517 * it is added 1518 */ 1519 void addFrame(Frame::TagNumber tagNr, const Frame* frame, bool edit = false); 1520 1521 /** 1522 * Open directory or add pictures on drop. 1523 * 1524 * @param paths paths of directories or files in directory 1525 * @param isInternal true if this is an internal drop 1526 */ 1527 void dropLocalFiles(const QStringList& paths, bool isInternal); 1528 1529 /** 1530 * Second stage for applyFilter(). 1531 */ 1532 void proceedApplyingFilter(); 1533 1534 /** 1535 * Set the coverArtImageId property to a new value. 1536 * This can be used to trigger an update of QML images. 1537 */ 1538 void setNextCoverArtImageId(); 1539 1540 void setAllFilesFileFilter(); 1541 1542 ICorePlatformTools* m_platformTools; 1543 /** Configuration */ 1544 QScopedPointer<ConfigStore> m_configStore; 1545 /** model of filesystem */ 1546 FileSystemModel* m_fileSystemModel; 1547 FileProxyModel* m_fileProxyModel; 1548 FileProxyModelIterator* m_fileProxyModelIterator; 1549 DirProxyModel* m_dirProxyModel; 1550 QItemSelectionModel* m_fileSelectionModel; 1551 QItemSelectionModel* m_dirSelectionModel; 1552 /** Track data model */ 1553 TrackDataModel* m_trackDataModel; 1554 GenreModel* m_genreModel[Frame::Tag_NumValues]; 1555 FrameTableModel* m_framesModel[Frame::Tag_NumValues]; 1556 QItemSelectionModel* m_framesSelectionModel[Frame::Tag_NumValues]; 1557 QMap<QString, PlaylistModel*> m_playlistModels; 1558 /** Frame list */ 1559 FrameList* m_framelist[Frame::Tag_NumValues]; 1560 /** Tag context */ 1561 Kid3ApplicationTagContext* m_tagContext[Frame::Tag_NumValues]; 1562 /** Network access manager */ 1563 QNetworkAccessManager* m_netMgr; 1564 /** Download client */ 1565 DownloadClient* m_downloadClient; 1566 /** Text exporter */ 1567 TextExporter* m_textExporter; 1568 /** Tag searcher */ 1569 TagSearcher* m_tagSearcher; 1570 /** Directory renamer */ 1571 DirRenamer* m_dirRenamer; 1572 /** Batch importer */ 1573 BatchImporter* m_batchImporter; 1574 /** Audio player */ 1575 QObject* m_player; 1576 #ifdef HAVE_QTDBUS 1577 QString m_mprisServiceName; 1578 #endif 1579 FileFilter* m_expressionFileFilter; 1580 /** Information about selected tagged files */ 1581 TaggedFileSelection* m_selection; 1582 /** Affected files to add frame when downloading image */ 1583 DownloadImageDestination m_downloadImageDest; 1584 /** Copy buffer */ 1585 FrameCollection m_copyTags; 1586 /** Root index in file proxy model */ 1587 QPersistentModelIndex m_fileProxyModelRootIndex; 1588 /** Root index in directory proxy model */ 1589 QPersistentModelIndex m_dirProxyModelRootIndex; 1590 /** Indexes of opened file in file proxy model */ 1591 QList<QPersistentModelIndex> m_fileProxyModelFileIndexes; 1592 /** Importers for different servers */ 1593 QList<ServerImporter*> m_importers; 1594 /** Importer for MusicBrainz fingerprints */ 1595 QList<ServerTrackImporter*> m_trackImporters; 1596 /** Processors for user commands */ 1597 QList<IUserCommandProcessor*> m_userCommandProcessors; 1598 /** Current directory */ 1599 QString m_dirName; 1600 /** Stored current selection with the list of all selected items */ 1601 QList<QPersistentModelIndex> m_currentSelection; 1602 /** directory from where "directory up" (..) was activated. */ 1603 QPersistentModelIndex m_dirUpIndex; 1604 1605 /* Context for filterNextFile() */ 1606 FileFilter* m_fileFilter; 1607 QString m_lastProcessedDirName; 1608 int m_filterPassed; 1609 int m_filterTotal; 1610 /* Context for batchImportNextFile() */ 1611 QScopedPointer<BatchImportProfile> m_namedBatchImportProfile; 1612 const BatchImportProfile* m_batchImportProfile; 1613 Frame::TagVersion m_batchImportTagVersion; 1614 QList<ImportTrackDataVector> m_batchImportAlbums; 1615 ImportTrackDataVector m_batchImportTrackDataList; 1616 1617 /* Context for renameAfterReset() */ 1618 QString m_renameAfterResetOldName; 1619 QString m_renameAfterResetNewName; 1620 1621 /* Context for editFrame() */ 1622 TaggedFile* m_editFrameTaggedFile; 1623 QString m_editFrameName; 1624 1625 /* Context for addFrame() */ 1626 TaggedFile* m_addFrameTaggedFile; 1627 1628 /* Support for frame editor object */ 1629 FrameEditorObject* m_frameEditor; 1630 IFrameEditor* m_storedFrameEditor; 1631 /* Support for image provider */ 1632 ImageDataProvider* m_imageProvider; 1633 QString m_coverArtImageId; 1634 1635 #ifdef Q_OS_ANDROID 1636 bool m_pendingIntentsChecked; 1637 #endif 1638 #ifdef HAVE_QTDBUS 1639 /** true if D-Bus is enabled */ 1640 bool m_dbusEnabled; 1641 #endif 1642 /** true if list is filtered */ 1643 bool m_filtered; 1644 /** true if a selection operation is running */ 1645 bool m_selectionOperationRunning; 1646 1647 /** Fallback for path to search for plugins */ 1648 static QString s_pluginsPathFallback; 1649 }; 1650 1651 /** 1652 * Facade to have a uniform interface for different tags. 1653 */ 1654 class KID3_CORE_EXPORT Kid3ApplicationTagContext : public QObject { 1655 Q_OBJECT 1656 /** Genre model. */ Q_PROPERTY(GenreModel * genreModel READ genreModel CONSTANT)1657 Q_PROPERTY(GenreModel* genreModel READ genreModel CONSTANT) 1658 /** Frame table model. */ 1659 Q_PROPERTY(FrameTableModel* frameModel READ frameModel CONSTANT) 1660 /** Frame selection model. */ 1661 Q_PROPERTY(QItemSelectionModel* frameSelectionModel READ frameSelectionModel CONSTANT) 1662 /** Frame list. */ 1663 Q_PROPERTY(FrameList* frameList READ frameList CONSTANT) 1664 public: 1665 /** 1666 * Constructor. 1667 * @param app application 1668 * @param tagNr tag number 1669 */ 1670 Kid3ApplicationTagContext(Kid3Application* app, Frame::TagNumber tagNr) 1671 : QObject(app), m_app(app), m_tagNr(tagNr), 1672 m_tagVersion(Frame::tagVersionFromNumber(tagNr)) { 1673 } 1674 1675 public slots: 1676 /** 1677 * Copy tags into copy buffer. 1678 */ copyTags()1679 void copyTags() { m_app->copyTags(m_tagVersion); } 1680 1681 /** 1682 * Paste from copy buffer to tags. 1683 */ pasteTags()1684 void pasteTags() { m_app->pasteTags(m_tagVersion); } 1685 1686 /** 1687 * Copy tags to other tags of selected files. 1688 */ copyToOtherTag()1689 void copyToOtherTag() { m_app->copyToOtherTag(m_tagVersion); } 1690 1691 /** 1692 * Remove tags in selected files. 1693 */ removeTags()1694 void removeTags() { m_app->removeTags(m_tagVersion); } 1695 1696 /** 1697 * Set tags from filename. 1698 */ getTagsFromFilename()1699 void getTagsFromFilename() { m_app->getTagsFromFilename(m_tagVersion); } 1700 1701 /** 1702 * Set filename from tags. 1703 */ getFilenameFromTags()1704 void getFilenameFromTags() { m_app->getFilenameFromTags(m_tagVersion); } 1705 1706 /** 1707 * Edit selected frame of tag. 1708 */ editFrame()1709 void editFrame() { m_app->editFrame(m_tagNr); } 1710 1711 /** 1712 * Delete selected frame from tag. 1713 */ deleteFrame()1714 void deleteFrame() { m_app->deleteFrame(m_tagNr); } 1715 1716 /** 1717 * Select a frame type and add such a frame to the frame list. 1718 */ addFrame()1719 void addFrame() { m_app->selectAndAddFrame(m_tagNr); } 1720 1721 private: 1722 /** 1723 * Get genre model. 1724 * @return genre model. 1725 */ genreModel()1726 GenreModel* genreModel() const { return m_app->genreModel(m_tagNr); } 1727 1728 /** 1729 * Get frame table model. 1730 * @return frame table. 1731 */ frameModel()1732 FrameTableModel* frameModel() { return m_app->frameModel(m_tagNr); } 1733 1734 /** 1735 * Get selection model of frame table model. 1736 */ frameSelectionModel()1737 QItemSelectionModel* frameSelectionModel() { 1738 return m_app->getFramesSelectionModel(m_tagNr); 1739 } 1740 1741 /** 1742 * Get frame list. 1743 */ frameList()1744 FrameList* frameList() { return m_app->getFrameList(m_tagNr); } 1745 1746 Kid3Application* const m_app; 1747 const Frame::TagNumber m_tagNr; 1748 const Frame::TagVersion m_tagVersion; 1749 }; 1750