File indexing completed on 2024-05-26 04:57:37

0001 /**
0002  * \file abstractcli.cpp
0003  * Abstract base class for command line interface.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 10 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 #include "abstractcli.h"
0028 #include <QTimer>
0029 #include <QCoreApplication>
0030 
0031 /**
0032  * Destructor.
0033  */
0034 AbstractCliIO::~AbstractCliIO()
0035 {
0036   cleanup();
0037 }
0038 
0039 /**
0040  * Can be reimplemented for cleanup, e.g. restoring the terminal.
0041  * Is called from the destructor.
0042  */
0043 void AbstractCliIO::cleanup()
0044 {
0045 }
0046 
0047 
0048 /**
0049  * Constructor.
0050  * @param io I/O handler
0051  * @param parent parent object
0052  */
0053 AbstractCli::AbstractCli(AbstractCliIO* io, QObject* parent) : QObject(parent),
0054   m_io(io), m_returnCode(0), m_terminating(false)
0055 {
0056   // To make sure cleanup is called when application is terminated by D-Bus.
0057   connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
0058           this, [this] {
0059     if (!m_terminating) {
0060       m_io->cleanup();
0061     }
0062   });
0063 }
0064 
0065 /**
0066  * Prompt next line from standard input.
0067  * Has to be called when the processing in readLine() is finished and
0068  * the user shall be prompted for the next line.
0069  */
0070 void AbstractCli::promptNextLine()
0071 {
0072   m_io->readLine();
0073 }
0074 
0075 /**
0076  * Set return code of application.
0077  * @param code return code, 0 means success
0078  */
0079 void AbstractCli::setReturnCode(int code)
0080 {
0081   m_returnCode = code;
0082 }
0083 
0084 /**
0085  * Exit application with return code.
0086  */
0087 void AbstractCli::quitApplicationWithReturnCode()
0088 {
0089   QCoreApplication::exit(m_returnCode);
0090 }
0091 
0092 /**
0093  * Execute process.
0094  */
0095 void AbstractCli::execute()
0096 {
0097   connect(m_io, &AbstractCliIO::lineReady,
0098           this, &AbstractCli::readLine, Qt::QueuedConnection);
0099   m_io->start();
0100 }
0101 
0102 /**
0103  * Terminate command line processor.
0104  */
0105 void AbstractCli::terminate()
0106 {
0107   m_terminating = true;
0108   flushStandardOutput();
0109   m_io->stop();
0110   if (m_returnCode == 0) {
0111     QTimer::singleShot(0, qApp, &QCoreApplication::quit);
0112   } else {
0113     QTimer::singleShot(0, this, &AbstractCli::quitApplicationWithReturnCode);
0114   }
0115 }
0116 
0117 /**
0118  * Write a line to standard output.
0119  * @param line line to write
0120  */
0121 void AbstractCli::writeLine(const QString& line)
0122 {
0123   m_io->writeLine(line);
0124 }
0125 
0126 /**
0127  * Write a line to standard error.
0128  * @param line line to write
0129  */
0130 void AbstractCli::writeErrorLine(const QString& line)
0131 {
0132   m_io->writeErrorLine(line);
0133 }
0134 
0135 /**
0136  * Flush the standard output.
0137  */
0138 void AbstractCli::flushStandardOutput()
0139 {
0140   m_io->flushStandardOutput();
0141 }