File indexing completed on 2024-05-12 05:12:39

0001 /*
0002     Copyright (C) 2012  Kevin Krammer <krammer@kde.org>
0003 
0004     This program is free software; you can redistribute it and/or modify
0005     it under the terms of the GNU General Public License as published by
0006     the Free Software Foundation; either version 2 of the License, or
0007     (at your option) any later version.
0008 
0009     This program is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012     GNU General Public License for more details.
0013 
0014     You should have received a copy of the GNU General Public License along
0015     with this program; if not, write to the Free Software Foundation, Inc.,
0016     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0017 */
0018 
0019 #ifndef ABSTRACTCOMMAND_H
0020 #define ABSTRACTCOMMAND_H
0021 
0022 #include <QObject>
0023 #include <QCommandLineParser>
0024 
0025 
0026 class KJob;
0027 class CollectionResolveJob;
0028 
0029 
0030 class AbstractCommand : public QObject
0031 {
0032     Q_OBJECT
0033 
0034 public:
0035     enum Errors {
0036         DefaultError = -1,
0037         NoError = 0,
0038         InvalidUsage = 1,
0039         RuntimeError = 2
0040     };
0041 
0042     explicit AbstractCommand(QObject *parent = nullptr);
0043     virtual ~AbstractCommand() = default;
0044 
0045     int init(const QStringList &parsedArgs, bool showHelp = false);
0046 
0047     virtual QString name() const = 0;
0048 
0049 public Q_SLOTS:
0050     virtual void start() = 0;
0051 
0052 Q_SIGNALS:
0053     void finished(AbstractCommand::Errors exitCode = AbstractCommand::DefaultError);
0054     void error(const QString &message);
0055 
0056 protected:
0057     virtual void setupCommandOptions(QCommandLineParser *parser) = 0;
0058     // TODO: return type should be the enum
0059     virtual int initCommand(QCommandLineParser *parser) = 0;
0060 
0061     void emitErrorSeeHelp(const QString &msg);
0062     bool allowDangerousOperation() const;
0063 
0064     void addOptionsOption(QCommandLineParser *parser);
0065     void addCollectionItemOptions(QCommandLineParser *parser);
0066     void addDryRunOption(QCommandLineParser *parser);
0067 
0068     bool getCommonOptions(QCommandLineParser *parser);
0069     bool checkArgCount(const QStringList &args, int min, const QString &errorText);
0070 
0071     bool isDryRun() const           { return (mDryRun); }
0072     bool wantCollection() const         { return (mWantCollection); }
0073     bool wantItem() const           { return (mWantItem); }
0074 
0075     bool getResolveJob(const QString &arg);
0076     CollectionResolveJob *resolveJob() const    { Q_ASSERT(mResolveJob!=nullptr); return (mResolveJob); }
0077 
0078     /**
0079      * Check the result status of a KIO job.
0080      *
0081      * Call this first of all in a slot connected to
0082      * a job's @c result() signal.  If the job had an error then
0083      * the @c error() signal will be emitted, and then @c processNext()
0084      * called to process the next loop argument.  If the processing
0085      * loop is not being used then the @c finished() signal will
0086      * be emitted to end the command.
0087      *
0088      * @param job The job that has just run
0089      * @param message An error message, or a null string to use the
0090      * job's @c errorString() message.
0091      * @result @c true if the job completed without error,
0092      * @c false otherwise.
0093      **/
0094     bool checkJobResult(KJob *job, const QString &message = QString());
0095 
0096     /**
0097      * Prepare to run a loop to process multiple command arguments.
0098      *
0099      * @param args The list of arguments to be processed, usually
0100      * the @c positionalArguments() from the @c CommandParser after
0101      * removing any initial ones with special meaning.
0102      * @param finishedMessage A progress message to display when the
0103      * loop is finished.  A null string means to display nothing.
0104      **/
0105     void initProcessLoop(const QStringList &args, const QString &finishedMessage = QString());
0106 
0107     /**
0108      * Run a loop to process multiple command arguments.
0109      *
0110      * The @p slot function will be called to start processing.
0111      * While processing, the current argument can be accessed
0112      * by @c currentArg().  The processing may run any number of
0113      * asynchronous jobs or event loops, and when finished should
0114      * call @c processNext() to continue with the next command argument.
0115      * Any errors should be reported via the @c error() signal, which
0116      * will track the overall return code and report it when finished.
0117      *
0118      * @param slot The name of the processing slot to perform an
0119      * action for a single argument.
0120      **/
0121     void startProcessLoop(const char *slot);
0122 
0123     /**
0124      * Process the next command argument, if there are any remaining.
0125      *
0126      * If there are arguments remaining, then the @c slot specified
0127      * to @c startProcessLoop() will be called again.  If the arguments
0128      * are all processed then the @c finished() signal will be emitted
0129      * to indicate that the command is finished.
0130      **/
0131     void processNext();
0132 
0133     /**
0134      * Get the command argument currently being processed.
0135      *
0136      * @return the current argument.
0137      **/
0138     const QString &currentArg() const           { return (mCurrentArg); };
0139 
0140     /**
0141      * Check whether the processing loop is finished.
0142      *
0143      * @return @c true if there are no more arguments to process,
0144      * @c false if there are any more remaining.
0145      **/
0146     bool isProcessLoopFinished() const          { return (mProcessLoopArgs.isEmpty()); }
0147 
0148 private:
0149     bool mDryRun;
0150     bool mWantCollection;
0151     bool mWantItem;
0152 
0153     bool mSetDryRun;
0154     bool mSetCollectionItem;
0155 
0156     CollectionResolveJob *mResolveJob;
0157 
0158     QStringList mProcessLoopArgs;
0159     const char *mProcessLoopSlot;
0160     QString mCurrentArg;
0161     QString mFinishedLoopMessage;
0162 };
0163 
0164 #endif // ABSTRACTCOMMAND_H