text: //============================================================================
  // Copyright 2009-2020 ECMWF.
  // This software is licensed under the terms of the Apache Licence version 2.0
  // which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
  // In applying this licence, ECMWF does not waive the privileges and immunities
  // granted to it by virtue of its status as an intergovernmental organisation
  // nor does it submit to any jurisdiction.
  //
  //============================================================================
  
  #include "CommandOutput.hpp"
  
  #include "CommandOutputDialog.hpp"
  #include "VConfig.hpp"
  
  CommandOutputHandler* CommandOutputHandler::instance_=nullptr;
  
  //===============================================
  //
  // CommandOutput
  //
  //==============================================
  
  CommandOutput::CommandOutput(QString cmd,QString cmdDef,QDateTime runTime) :
      enabled_(true), command_(cmd), commandDef_(cmdDef),
      runTime_(runTime), status_(RunningStatus)
  {
  
  }
  
  void CommandOutput::appendOutput(QString txt,int maxSize,bool& trimmed)
  {
      output_+=txt;
      trimmed=false;
      if(output_.size() > maxSize)
      {
          output_=output_.right(maxSize-100);
          trimmed=true;
      }
  }
  
  void CommandOutput::appendError(QString txt,int maxSize,bool& trimmed)
  {
      error_+=txt;
      trimmed=false;
      if(error_.size() > maxSize)
      {
          error_=error_.right(maxSize-100);
          trimmed=true;
      }
  }
  
  QString CommandOutput::statusStr() const
  {
      static QString finishedStr("finished");
      static QString failedStr("failed");
      static QString runningStr("running");
  
      switch(status_)
      {
      case FinishedStatus:
          return finishedStr;
      case FailedStatus:
          return failedStr;
      case RunningStatus:
          return runningStr;
      default:
          return QString();
      }
  
      return QString();
  }
  
  QColor CommandOutput::statusColour() const
  {
      static QColor redColour(255,0,0);
      static QColor greenColour(9,160,63);
      static QColor blackColour(0,0,0);
  
      switch(status_)
      {
      case CommandOutput::FinishedStatus:
          return blackColour;
      case CommandOutput::FailedStatus:
          return redColour;
      case CommandOutput::RunningStatus:
          return greenColour;
      default:
          return blackColour;
      }
  
      return blackColour;
  }
  
  //===============================================
  //
  // CommandOutputHandler
  //
  //===============================================
  
  CommandOutputHandler::CommandOutputHandler(QObject* parent) :
      QObject(parent)
  {
      showDialogStdOutProp_ = VConfig::instance()->find("view.shellCommand.showPopupOnStdOut");
      showDialogStdErrProp_ = VConfig::instance()->find("view.shellCommand.showPopupOnStdErr");
  }
  
  CommandOutputHandler* CommandOutputHandler::instance()
  {
      if(!instance_)
          instance_=new CommandOutputHandler(nullptr);
  
      return instance_;
  }
  
  int CommandOutputHandler::indexOfItem(CommandOutput_ptr item) const
  {
      if(!item)
          return -1;
  
      for(int i=0; i < items_.count(); i++)
      {
          if(item.get() == items_[i].get())
              return i;
      }
  
      return -1;
  }
  
  void CommandOutputHandler::appendOutput(CommandOutput_ptr item,QString txt)
  {
      if(item)
      {
          bool trimmed=false;
          item->appendOutput(txt,maxOutputSize_,trimmed);
          if (needToShowStdOut()) {
              CommandOutputDialog::showDialog();
          }
          if(trimmed==false)
              Q_EMIT itemOutputAppend(item,txt);
          else
              Q_EMIT itemOutputReload(item);
      }
  }
  
  void CommandOutputHandler::appendError(CommandOutput_ptr item,QString txt)
  {
      if(item)
      {
          bool trimmed=false;
          item->appendError(txt,maxErrorSize_,trimmed);
          if (needToShowStdErr()) {
              CommandOutputDialog::showDialog();
          }
          if(trimmed==false)
              Q_EMIT itemErrorAppend(item,txt);
          else
              Q_EMIT itemErrorReload(item);
      }
  }
  
  void CommandOutputHandler::finished(CommandOutput_ptr item)
  {
      if(item)
      {
          item->setStatus(CommandOutput::FinishedStatus);
          Q_EMIT itemStatusChanged(item);
      }
  }
  
  void CommandOutputHandler::failed(CommandOutput_ptr item)
  {
      if(item)
      {
          item->setStatus(CommandOutput::FailedStatus);
          Q_EMIT itemStatusChanged(item);
          if (needToShowStdErr()) {
              CommandOutputDialog::showDialog();
          }
      }
  }
  
  CommandOutput_ptr CommandOutputHandler::addItem(QString cmd,QString cmdDef,QDateTime runTime, CreateContext context)
  {
      if( (needToShowStdOut() && context == StdOutContext) ||
          (needToShowStdErr() && context == StdErrContext) ) {
          CommandOutputDialog::showDialog();
      }
      CommandOutput_ptr item=
              CommandOutput_ptr(new CommandOutput(cmd,cmdDef,runTime));
      Q_EMIT itemAddBegin();
      items_ << item;
      checkItems();
      Q_EMIT itemAddEnd();
      return item;
  }
  
  void CommandOutputHandler::checkItems()
  {
      Q_ASSERT(maxNum_ >0);
      while(items_.count() > maxNum_)
      {
          Q_ASSERT(items_.count() > 0);
          CommandOutput_ptr item=items_.first();
          item->setEnabled(false);
          items_.remove(0);
      }
  }
  
  bool CommandOutputHandler::needToShowStdOut()
  {
       return (showDialogStdOutProp_)?(showDialogStdOutProp_->value().toBool()):true;
  }
  
  bool CommandOutputHandler::needToShowStdErr()
  {
       return (showDialogStdErrProp_)?(showDialogStdErrProp_->value().toBool()):true;
  }
  