File indexing completed on 2024-05-19 04:55:49

0001 /**
0002  * \file clicommand.h
0003  * Command line interface commands.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 11 Aug 2013
0008  *
0009  * Copyright (C) 2013-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 <QObject>
0030 #include <QScopedPointer>
0031 #include "frame.h"
0032 #include "externalprocess.h"
0033 
0034 class QModelIndex;
0035 class Kid3Cli;
0036 
0037 /**
0038  * Base class for command line interface command.
0039  */
0040 class CliCommand : public QObject {
0041   Q_OBJECT
0042 public:
0043   /**
0044    * Destructor.
0045    */
0046   ~CliCommand() override = default;
0047 
0048   /**
0049    * Reset state to defaults.
0050    */
0051   virtual void clear();
0052 
0053   /**
0054    * Execute command.
0055    */
0056   virtual void execute();
0057 
0058   /**
0059    * Get command name.
0060    * @return name with which command is invoked.
0061    */
0062   QString name() const { return m_name; }
0063 
0064   /**
0065    * Get help text for command.
0066    * @return help text for command.
0067    */
0068   QString help() const { return m_help; }
0069 
0070   /**
0071    * Get argument specification
0072    * @return argument specification for command.
0073    */
0074   QString argumentSpecification() const { return m_argspec; }
0075 
0076   /**
0077    * Get description of error.
0078    * @return error message, empty if no error occurred.
0079    */
0080   QString getErrorMessage() const { return m_errorMsg; }
0081 
0082   /**
0083    * Check if an error occurred.
0084    * @return true if an error exists.
0085    */
0086   bool hasError() const { return !m_errorMsg.isEmpty(); }
0087 
0088   /**
0089    * Set error message.
0090    * @param errorMsg error message, null string to clear error
0091    */
0092   void setError(const QString& errorMsg) { m_errorMsg = errorMsg; }
0093 
0094   /**
0095    * Get timeout for operation.
0096    * @return timeout in milliseconds.
0097    */
0098   int getTimeout() const { return m_timeoutMs; }
0099 
0100   /**
0101    * Set timeout for operation.
0102    * @param msec timeout in milliseconds, -1 for no timeout
0103    */
0104   void setTimeout(int msec) { m_timeoutMs = msec; }
0105 
0106   /**
0107    * Get processor handling commands.
0108    * @return processor.
0109    */
0110   Kid3Cli* cli() const { return m_processor; }
0111 
0112   /**
0113    * Get list of arguments.
0114    * @return arguments, the first element is the command name.
0115    */
0116   const QStringList& args() const { return m_args; }
0117 
0118   /**
0119    * Set list of arguments.
0120    * @param args arguments, the first element must be the command name
0121    */
0122   void setArgs(const QStringList& args) { m_args = args; }
0123 
0124   /**
0125    * Get result code of command.
0126    * @return result code, default is 0 for OK.
0127    */
0128   int result() const { return m_result; }
0129 
0130   /**
0131    * Set result code of command.
0132    * @param result result code
0133    */
0134   void setResult(int result) { m_result = result; }
0135 
0136 signals:
0137   /**
0138    * Emitted when the command is finished.
0139    */
0140   void finished();
0141 
0142 protected slots:
0143   /**
0144    * Terminate command.
0145    * Must be invoked when command is finished, which is set up in
0146    * connectResultSignal().
0147    */
0148   void terminate();
0149 
0150 protected:
0151   /**
0152    * Constructor.
0153    * @param processor command line processor
0154    * @param name name with which command is invoked
0155    * @param help help text for command
0156    * @param argspec argument specification
0157    */
0158   CliCommand(Kid3Cli* processor, const QString& name, const QString& help,
0159              const QString& argspec = QString());
0160 
0161   /**
0162    * Called on timeout.
0163    * @param event timer event
0164    */
0165   void timerEvent(QTimerEvent* event) override;
0166 
0167   /**
0168    * Start specific command.
0169    * This method has to be implemented by the specific subclasses
0170    * to execute the specific command. It should invoke terminate()
0171    * when the command is finished.
0172    */
0173   virtual void startCommand() = 0;
0174 
0175   /**
0176    * Connect signals used to emit finished().
0177    * This method is called after startCommand(). The default implementation
0178    * invokes terminate() in the event loop. It can be overridden to connect
0179    * signals connected to terminate() to signal termination of the command.
0180    */
0181   virtual void connectResultSignal();
0182 
0183   /**
0184    * Stop command.
0185    * This method is called from terminate(). The default implementation
0186    * does nothing. It can be overridden to disconnect signals connected
0187    * in startCommand().
0188    */
0189   virtual void disconnectResultSignal();
0190 
0191   /**
0192    * Get parameter for task mask.
0193    * @param nr index in args()
0194    * @param useDefault if true use cli()->tagMask() if no parameter found
0195    * @return tag versions.
0196    */
0197   Frame::TagVersion getTagMaskParameter(int nr,
0198                                         bool useDefault = true) const;
0199 
0200   /**
0201    * Show usage of command.
0202    */
0203   void showUsage();
0204 
0205 private:
0206   Kid3Cli* m_processor;
0207   const QString m_name;
0208   const QString m_help;
0209   const QString m_argspec;
0210   QStringList m_args;
0211   QString m_errorMsg;
0212   int m_timerId;
0213   int m_timeoutMs;
0214   int m_result;
0215 };
0216 
0217 
0218 /** Display help. */
0219 class HelpCommand : public CliCommand {
0220   Q_OBJECT
0221 public:
0222   /** Constructor. */
0223   explicit HelpCommand(Kid3Cli* processor);
0224 
0225 protected:
0226   void startCommand() override;
0227 };
0228 
0229 
0230 /** Overwrite timeout. */
0231 class TimeoutCommand : public CliCommand {
0232   Q_OBJECT
0233 public:
0234   /** Constructor. */
0235   explicit TimeoutCommand(Kid3Cli* processor);
0236 
0237 protected:
0238   void startCommand() override;
0239 };
0240 
0241 
0242 /** Quit application. */
0243 class QuitCommand : public CliCommand {
0244   Q_OBJECT
0245 public:
0246   /** Constructor. */
0247   explicit QuitCommand(Kid3Cli* processor);
0248 
0249 protected:
0250   void startCommand() override;
0251   void connectResultSignal() override;
0252 };
0253 
0254 
0255 /** Change directory. */
0256 class CdCommand : public CliCommand {
0257   Q_OBJECT
0258 public:
0259   /** Constructor. */
0260   explicit CdCommand(Kid3Cli* processor);
0261 
0262 protected:
0263   void startCommand() override;
0264   void connectResultSignal() override;
0265   void disconnectResultSignal() override;
0266 };
0267 
0268 
0269 /** Print current working directory. */
0270 class PwdCommand : public CliCommand {
0271   Q_OBJECT
0272 public:
0273   /** Constructor. */
0274   explicit PwdCommand(Kid3Cli* processor);
0275 
0276 protected:
0277   void startCommand() override;
0278 };
0279 
0280 
0281 /** List directory. */
0282 class LsCommand : public CliCommand {
0283   Q_OBJECT
0284 public:
0285   /** Constructor. */
0286   explicit LsCommand(Kid3Cli* processor);
0287 
0288 protected:
0289   void startCommand() override;
0290 };
0291 
0292 
0293 /** Save changes. */
0294 class SaveCommand : public CliCommand {
0295   Q_OBJECT
0296 public:
0297   /** Constructor. */
0298   explicit SaveCommand(Kid3Cli* processor);
0299 
0300 protected:
0301   void startCommand() override;
0302 };
0303 
0304 
0305 /** Select file. */
0306 class SelectCommand : public CliCommand {
0307   Q_OBJECT
0308 public:
0309   /** Constructor. */
0310   explicit SelectCommand(Kid3Cli* processor);
0311 
0312 protected:
0313   void startCommand() override;
0314 };
0315 
0316 
0317 /** Display or set tag mask. */
0318 class TagCommand : public CliCommand {
0319   Q_OBJECT
0320 public:
0321   /** Constructor. */
0322   explicit TagCommand(Kid3Cli* processor);
0323 
0324 protected:
0325   void startCommand() override;
0326 };
0327 
0328 
0329 /** Get tag frame or file information. */
0330 class GetCommand : public CliCommand {
0331   Q_OBJECT
0332 public:
0333   /** Constructor. */
0334   explicit GetCommand(Kid3Cli* processor);
0335 
0336 protected:
0337   void startCommand() override;
0338 };
0339 
0340 
0341 /** Set tag frame. */
0342 class SetCommand : public CliCommand {
0343   Q_OBJECT
0344 public:
0345   /** Constructor. */
0346   explicit SetCommand(Kid3Cli* processor);
0347 
0348 protected:
0349   void startCommand() override;
0350 };
0351 
0352 
0353 /** Revert changes. */
0354 class RevertCommand : public CliCommand {
0355   Q_OBJECT
0356 public:
0357   /** Constructor. */
0358   explicit RevertCommand(Kid3Cli* processor);
0359 
0360 protected:
0361   void startCommand() override;
0362 };
0363 
0364 
0365 /** Import from file. */
0366 class ImportCommand : public CliCommand {
0367   Q_OBJECT
0368 public:
0369   /** Constructor. */
0370   explicit ImportCommand(Kid3Cli* processor);
0371 
0372 protected:
0373   void startCommand() override;
0374 };
0375 
0376 /** Automatic import from servers. */
0377 class BatchImportCommand : public CliCommand {
0378   Q_OBJECT
0379 public:
0380   /** Constructor. */
0381   explicit BatchImportCommand(Kid3Cli* processor);
0382 
0383 protected:
0384   void startCommand() override;
0385   void connectResultSignal() override;
0386   void disconnectResultSignal() override;
0387 
0388 private slots:
0389   void onReportImportEvent(int type, const QString& text);
0390 };
0391 
0392 /** Download album cover art. */
0393 class AlbumArtCommand : public CliCommand {
0394   Q_OBJECT
0395 public:
0396   /** Constructor. */
0397   explicit AlbumArtCommand(Kid3Cli* processor);
0398 
0399 protected:
0400   void startCommand() override;
0401   void connectResultSignal() override;
0402   void disconnectResultSignal() override;
0403 
0404 private slots:
0405   void onDownloadFinished(const QByteArray& data,
0406                           const QString& mimeType, const QString& url);
0407 };
0408 
0409 /** Export to file. */
0410 class ExportCommand : public CliCommand {
0411   Q_OBJECT
0412 public:
0413   /** Constructor. */
0414   explicit ExportCommand(Kid3Cli* processor);
0415 
0416 protected:
0417   void startCommand() override;
0418 };
0419 
0420 /** Create playlist file. */
0421 class PlaylistCommand : public CliCommand {
0422   Q_OBJECT
0423 public:
0424   /** Constructor. */
0425   explicit PlaylistCommand(Kid3Cli* processor);
0426 
0427 protected:
0428   void startCommand() override;
0429 };
0430 
0431 /** Apply file name format. */
0432 class FilenameFormatCommand : public CliCommand {
0433   Q_OBJECT
0434 public:
0435   /** Constructor. */
0436   explicit FilenameFormatCommand(Kid3Cli* processor);
0437 
0438 protected:
0439   void startCommand() override;
0440 };
0441 
0442 /** Apply tag format. */
0443 class TagFormatCommand : public CliCommand {
0444   Q_OBJECT
0445 public:
0446   /** Constructor. */
0447   explicit TagFormatCommand(Kid3Cli* processor);
0448 
0449 protected:
0450   void startCommand() override;
0451 };
0452 
0453 /** Apply text encoding. */
0454 class TextEncodingCommand : public CliCommand {
0455   Q_OBJECT
0456 public:
0457   /** Constructor. */
0458   explicit TextEncodingCommand(Kid3Cli* processor);
0459 
0460 protected:
0461   void startCommand() override;
0462 };
0463 
0464 /** Rename directory. */
0465 class RenameDirectoryCommand : public CliCommand {
0466   Q_OBJECT
0467 public:
0468   /** Constructor. */
0469   explicit RenameDirectoryCommand(Kid3Cli* processor);
0470 
0471 protected:
0472   void startCommand() override;
0473   void connectResultSignal() override;
0474   void disconnectResultSignal() override;
0475 
0476 private slots:
0477   void onActionScheduled(const QStringList& actionStrs);
0478   void onRenameActionsScheduled();
0479 
0480 private:
0481   bool m_dryRun;
0482 };
0483 
0484 /** Number tracks. */
0485 class NumberTracksCommand : public CliCommand {
0486   Q_OBJECT
0487 public:
0488   /** Constructor. */
0489   explicit NumberTracksCommand(Kid3Cli* processor);
0490 
0491 protected:
0492   void startCommand() override;
0493 };
0494 
0495 /** Filter files. */
0496 class FilterCommand : public CliCommand {
0497   Q_OBJECT
0498 public:
0499   /** Constructor. */
0500   explicit FilterCommand(Kid3Cli* processor);
0501 
0502 protected:
0503   void startCommand() override;
0504   void connectResultSignal() override;
0505   void disconnectResultSignal() override;
0506 
0507 private slots:
0508   void onFileFiltered(int type, const QString& fileName);
0509 };
0510 
0511 /** Convert ID3v2.3 to ID3v2.4. */
0512 class ToId3v24Command : public CliCommand {
0513   Q_OBJECT
0514 public:
0515   /** Constructor. */
0516   explicit ToId3v24Command(Kid3Cli* processor);
0517 
0518 protected:
0519   void startCommand() override;
0520 };
0521 
0522 /** Convert ID3v2.4 to ID3v2.3. */
0523 class ToId3v23Command : public CliCommand {
0524   Q_OBJECT
0525 public:
0526   /** Constructor. */
0527   explicit ToId3v23Command(Kid3Cli* processor);
0528 
0529 protected:
0530   void startCommand() override;
0531 };
0532 
0533 /** Set file name from tags. */
0534 class TagToFilenameCommand : public CliCommand {
0535   Q_OBJECT
0536 public:
0537   /** Constructor. */
0538   explicit TagToFilenameCommand(Kid3Cli* processor);
0539 
0540 protected:
0541   void startCommand() override;
0542 };
0543 
0544 /** Set tags from file name. */
0545 class FilenameToTagCommand : public CliCommand {
0546   Q_OBJECT
0547 public:
0548   /** Constructor. */
0549   explicit FilenameToTagCommand(Kid3Cli* processor);
0550 
0551 protected:
0552   void startCommand() override;
0553 };
0554 
0555 /** Copy between tag 1 and tag 2. */
0556 class TagToOtherTagCommand : public CliCommand {
0557   Q_OBJECT
0558 public:
0559   /** Constructor. */
0560   explicit TagToOtherTagCommand(Kid3Cli* processor);
0561 
0562 protected:
0563   void startCommand() override;
0564 };
0565 
0566 /** Copy to clipboard. */
0567 class CopyCommand : public CliCommand {
0568   Q_OBJECT
0569 public:
0570   /** Constructor. */
0571   explicit CopyCommand(Kid3Cli* processor);
0572 
0573 protected:
0574   void startCommand() override;
0575 };
0576 
0577 /** Paste from clipboard. */
0578 class PasteCommand : public CliCommand {
0579   Q_OBJECT
0580 public:
0581   /** Constructor. */
0582   explicit PasteCommand(Kid3Cli* processor);
0583 
0584 protected:
0585   void startCommand() override;
0586 };
0587 
0588 /** Remove tags. */
0589 class RemoveCommand : public CliCommand {
0590   Q_OBJECT
0591 public:
0592   /** Constructor. */
0593   explicit RemoveCommand(Kid3Cli* processor);
0594 
0595 protected:
0596   void startCommand() override;
0597 };
0598 
0599 /** Get or set configuration options. */
0600 class ConfigCommand : public CliCommand {
0601   Q_OBJECT
0602 public:
0603   /** Constructor. */
0604   explicit ConfigCommand(Kid3Cli* processor);
0605 
0606 protected:
0607   void startCommand() override;
0608 };
0609 
0610 /** Execute command. */
0611 class ExecuteCommand : public CliCommand,
0612                        public ExternalProcess::IOutputViewer {
0613   Q_OBJECT
0614 public:
0615   /** Constructor. */
0616   explicit ExecuteCommand(Kid3Cli* processor);
0617 
0618   void setCaption(const QString& title) override;
0619   void append(const QString& text) override;
0620   void scrollToBottom() override;
0621 
0622 protected:
0623   void startCommand() override;
0624   void connectResultSignal() override;
0625   void disconnectResultSignal() override;
0626 
0627 private:
0628   QScopedPointer<ExternalProcess> m_process;
0629 };