"Fossies" - the Fresh Open Source Software Archive

Member "MP3Diags-unstable-1.5.01/src/ThreadRunnerDlgImpl.h" (10 Feb 2019, 8975 Bytes) of package /linux/privat/MP3Diags-unstable-1.5.01.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ThreadRunnerDlgImpl.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.3.04_vs_1.5.01.

    1 /***************************************************************************
    2  *   MP3 Diags - diagnosis, repairs and tag editing for MP3 files          *
    3  *                                                                         *
    4  *   Copyright (C) 2009 by Marian Ciobanu                                  *
    5  *   ciobi@inbox.com                                                       *
    6  *                                                                         *
    7  *   This program is free software; you can redistribute it and/or modify  *
    8  *   it under the terms of the GNU General Public License version 2 as     *
    9  *   published by the Free Software Foundation.                            *
   10  *                                                                         *
   11  *   This program is distributed in the hope that it will be useful,       *
   12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
   13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
   14  *   GNU General Public License for more details.                          *
   15  *                                                                         *
   16  *   You should have received a copy of the GNU General Public License     *
   17  *   along with this program; if not, write to the                         *
   18  *   Free Software Foundation, Inc.,                                       *
   19  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
   20  ***************************************************************************/
   21 
   22 
   23 #ifndef ThreadRunnerDlgImplH
   24 #define ThreadRunnerDlgImplH
   25 
   26 #include <QDialog>
   27 #include <QThread>
   28 #include <QMutex>
   29 #include <QWaitCondition>
   30 #include <QTimer>
   31 
   32 #include <vector>
   33 
   34 #include "ui_ThreadRunner.h"
   35 
   36 
   37 
   38 typedef QList<QString> StrList;
   39 
   40 //=====================================================================================================================
   41 //=====================================================================================================================
   42 //=====================================================================================================================
   43 
   44 /*
   45 This class is supposed to be derived from to create the actual thread class, then instantiated and passed to a ThreadRunnerDlgImpl, which will handle the thread.
   46 
   47 Usage:
   48 
   49 A) The user thread calls "pause()", "resume()" or "abort()" as needed.
   50 
   51 B) The class derived from PausableThread must declare a CompleteNotif at the beginning of its "run()" function.
   52 
   53 C) The class derived from PausableThread should do these things periodically in run():
   54     1) have something like this: "if (isAborted()) return;"
   55     2) call "checkPause()"; this call blocks if the user called "pause()"
   56     3) emit "stepChanged()", to allow progress to be displayed in the associated dialog
   57 
   58 D) The class derived from PausableThread must call "setSuccess(true)" on the CompleteNotif variable just before exiting, if the execution was successful.
   59 
   60 
   61 Notes:
   62 - the user thread shouldn't make any assumptions about how long it would take for a step in PausableThread, but this should not be long (less than 0.1 s)
   63 - in order to help performance it is possible that one more step in PausableThread will be executed after sending pause(); (functionally this shouldn't matter, because it's the same as if pause() was called just after PausableThread checked if it should pause)
   64 
   65 Another functionality this class provides is "sleep". The sleep functions in QThread are protected but occasionally useful, so they are exposed here. //ttt2 perhaps create separate class / free functions
   66 
   67 */
   68 class PausableThread : public QThread
   69 {
   70     Q_OBJECT
   71 
   72     QMutex m_mutex;
   73     QWaitCondition m_waitCondition;
   74 
   75     bool m_bPaused;  // set by pause() / resume() ; derived classes should check it periodically by calling isPaused()
   76     bool m_bAborted; // set by abort() ; derived classes should check it periodically by calling isAborted()
   77 
   78 protected:
   79     //bool isPaused() const { return m_bPaused; } // !!! no synch needed
   80     class CompleteNotif
   81     {
   82         bool m_bSuccess;
   83         PausableThread* m_pThread;
   84     public:
   85         CompleteNotif(PausableThread* pThread) : m_bSuccess(false), m_pThread(pThread) {}
   86         ~CompleteNotif() { m_pThread->notifComplete(m_bSuccess); }
   87         void setSuccess(bool bSuccess) { m_bSuccess = bSuccess; }
   88     };
   89 
   90 public:
   91     PausableThread(/*QObject* pParent = 0*/);
   92     virtual ~PausableThread();
   93 
   94 
   95     bool isAborted() const { return m_bAborted; } // !!! no synch needed
   96     void checkPause(); // if m_bPaused is set, it waits until resume() or abort() get called; otherwise it returns immediately
   97     //void emitStepChanged(const QString& qstrLabel1, const QString& qstrLabel2 = "", const QString& qstrLabel3 = "", const QString& qstrLabel4 = "") { emit stepChanged(qstrLabel1, qstrLabel2, qstrLabel3, qstrLabel4); }
   98     void emitStepChanged(const StrList& v, int nStep = -1) { emit stepChanged(v, nStep); }
   99 
  100 //public slots:
  101 //private slots:
  102     void pause();
  103     void resume();
  104 
  105     void abort();
  106 
  107     using QThread::msleep;
  108     using QThread::sleep;
  109     using QThread::usleep;
  110 private:
  111     friend class ThreadRunnerDlgImpl;
  112     friend class PausableThread::CompleteNotif;
  113     void notifComplete(bool bSuccess) { emit completed(bSuccess); }
  114 
  115 signals:
  116     //void stepChanged(const QString& qstrLabel1, const QString& qstrLabel2, const QString& qstrLabel3, const QString& qstrLabel4);
  117     void stepChanged(const StrList& v, int nStep); // normally nStep should be -1, which causes the steps to be handled automatically;
  118     void completed(bool bSuccess);
  119 };
  120 
  121 
  122 //=====================================================================================================================
  123 //=====================================================================================================================
  124 //=====================================================================================================================
  125 
  126 
  127 /*
  128 Takes a PausableThread* on the constructor and sets itself as the owner (so the thread should be created with "new()")
  129 
  130 The thread must not be already started. It starts the thread and has buttons for pause/resume and abort.
  131 
  132 Closes itself when the thread completes.
  133 
  134 ----------
  135 
  136 There are 2 events that can't be allow to work as usual:
  137     1) clicking the top-right "Close" button
  138     2) pressing ESC (which normally triggers the closing)
  139 
  140 Allowing the window ro close would kill the thread too and leave everything in an inconsistent state. So on_m_pAbortB_clicked() is called instead.
  141 
  142 To deal with Close, closeEvent() is overridden.
  143 
  144 To prevent ESC from closing the dialog, Qt::Key_Escape is set as a shortcut for on_m_pAbortB_clicked(). (Alternatively, keyPressEvent and keyReleaseEvent could be used, but it's more complicated.)
  145 
  146 
  147 */
  148 class ThreadRunnerDlgImpl : public QDialog, private Ui::ThreadRunnerDlg
  149 {
  150     Q_OBJECT
  151 
  152     PausableThread* m_pThread;
  153     bool m_bSuccess;
  154     QTimer m_closeTimer;
  155     QTimer m_updateTimer;
  156     int m_nCounter;
  157     bool m_bShowCounter;
  158 
  159     time_t m_tRealBegin;
  160     time_t m_tRunningBegin;
  161     time_t m_tPauseBegin;
  162 
  163     StrList m_vStepInfo;
  164     bool m_bShowPauseAbort;
  165     bool m_bFirstTime;
  166 
  167 public:
  168     enum TruncatePos { TRUNCATE_BEGIN, TRUNCATE_MIDDLE, TRUNCATE_END };
  169 
  170 private:
  171     /*override*/ void closeEvent(QCloseEvent* pEvent); // needed to sort of disable the close button; the event gets ignored and on_m_pAbortB_clicked() gets called instead
  172 #if 0
  173     int m_nLastKey;
  174     /*override*/ void keyPressEvent(QKeyEvent* pEvent);
  175     /*override*/ void keyReleaseEvent(QKeyEvent* pEvent);
  176 #endif
  177     TruncatePos m_eTruncatePos;
  178 
  179     QString truncateLarge(const QString& s, int nKeepFirst = 0); // truncates strings that are too wide to display without resizing; uses m_eTruncatePos to determine where to truncate
  180 public:
  181     enum { HIDE_COUNTER, SHOW_COUNTER };
  182     enum { HIDE_PAUSE_ABORT, SHOW_PAUSE_ABORT };
  183     //ThreadRunnerDlgImpl(PausableThread* pThread, bool bShowCounter, QWidget* pParent = 0, Qt::WindowFlags fl = 0);
  184     ThreadRunnerDlgImpl(QWidget* pParent, Qt::WindowFlags flags, PausableThread* pThread, bool bShowCounter, TruncatePos eTruncatePos, bool bShowPauseAbort = true);
  185     ~ThreadRunnerDlgImpl();
  186     /*$PUBLIC_FUNCTIONS$*/
  187 
  188     //void startThread(); // !!! start automatically
  189     /*void pauseThread();
  190     void resumeThread();
  191     void abortThread();*/
  192 
  193 public slots:
  194     /*$PUBLIC_SLOTS$*/
  195 
  196 protected:
  197     /*$PROTECTED_FUNCTIONS$*/
  198 
  199 protected slots:
  200     /*$PROTECTED_SLOTS$*/
  201 
  202 private slots:
  203     void onThreadCompleted(bool bSuccess);
  204     void on_m_pPauseResumeB_clicked();
  205     void on_m_pAbortB_clicked();
  206     //void onStepChanged(const QString& qstrLabel1, const QString& qstrLabel2 = "", const QString& qstrLabel3 = "", const QString& qstrLabel4 = "");
  207     void onStepChanged(const StrList& v, int nStep);
  208     void onCloseTimer();
  209     void onUpdateTimer();
  210 
  211     void onHelp();
  212 };
  213 
  214 #endif // #ifndef ThreadRunnerDlgImplH
  215 
  216 
  217