Ticket #4168: 4168-v1.patch

File 4168-v1.patch, 24.9 KB (added by danielk, 16 years ago)

Possible fix

  • mythplugins/mythmusic/mythmusic/playbackbox.cpp

     
    19681968            OutputEvent *aoe = (OutputEvent *) event;
    19691969
    19701970            VERBOSE(VB_IMPORTANT, QString("%1 %2").arg(statusString)
    1971                 .arg(*aoe->errorMessage()));
    1972             MythPopupBox::showOkPopup(gContext->GetMainWindow(),
    1973                                       statusString,
    1974                                       QString("MythMusic has encountered the following error:\n%1")
    1975                                       .arg(*aoe->errorMessage()));
     1971                    .arg(aoe->GetErrorMessage()));
     1972
     1973            MythPopupBox::showOkPopup(
     1974                gContext->GetMainWindow(),
     1975                statusString,
     1976                tr("MythMusic has encountered the following error") +
     1977                QString(":\n%1").arg(aoe->GetErrorMessage()));
     1978
    19761979            stopAll();
    19771980
    19781981            break;
  • mythplugins/mythmusic/mythmusic/musicplayer.cpp

     
    466466                OutputEvent *aoe = (OutputEvent *) event;
    467467
    468468                VERBOSE(VB_IMPORTANT, QString("Output Error - %1")
    469                         .arg(*aoe->errorMessage()));
    470                 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
    471                         "Output Error:",
    472                         QString("MythMusic has encountered the following error:\n%1")
    473                                 .arg(*aoe->errorMessage()));
     469                        .arg(aoe->GetErrorMessage()));
     470
     471                MythPopupBox::showOkPopup(
     472                    gContext->GetMainWindow(),
     473                    tr("Output Error") + ":",
     474                    tr("MythMusic has encountered the following error") +
     475                    QString(":\n%1").arg(aoe->GetErrorMessage()));
     476
    474477                stop(true);
    475478
    476479                break;
  • mythtv/libs/libmythtv/programinfo.cpp

     
    278278#define LONGLONG_TO_LIST(x)  INT_TO_LIST((int)((x) >> 32))  \
    279279                             INT_TO_LIST((int)((x) & 0xffffffffLL))
    280280
    281 #define STR_TO_LIST(x)       if ((x).isNull()) list << ""; else list << (x);
     281#define STR_TO_LIST(x)       if ((x).isNull()) list << ""; else list << QDeepCopy<QString>(x);
    282282#define DATE_TO_LIST(x)      STR_TO_LIST((x).toString(Qt::ISODate))
    283283
    284284#define FLOAT_TO_LIST(x)     sprintf(tmp, "%f", (x)); list << tmp;
     
    368368                                   VERBOSE(VB_IMPORTANT, listerror); \
    369369                                   return false;      \
    370370                               }                      \
    371                                ts = *it++;            \
     371                               ts = QDeepCopy<QString>(*it++); \
    372372                               if (ts.isNull())       \
    373373                                   ts = "";           
    374374                               
  • mythtv/libs/libmyth/output.h

     
     1// -*- Mode: c++ -*-
    12// Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
    23//
    34// Use, modification and distribution is allowed without limitation,
     
    1011class OutputListeners;
    1112class OutputEvent;
    1213
    13 #include <qthread.h>
    14 #include <qevent.h>
    15 #include <qptrlist.h>
    1614#include "mythobservable.h"
    1715
    1816class QObject;
     
    2422
    2523class MPUBLIC OutputEvent : public MythEvent
    2624{
    27 public:
    28     enum Type { Playing = (User + 200), Buffering, Info, Paused,
    29                 Stopped, Error };
     25  public:
     26    enum Type
     27    {
     28        Playing = MythOutputEventBegin,
     29        Buffering,
     30        Info,
     31        Paused,
     32        Stopped,
     33        Error,
     34    };
    3035
    31     OutputEvent(Type t)
    32         : MythEvent(t), error_msg(0), elasped_seconds(0), written_bytes(0),
    33           brate(0), freq(0), prec(0), chan(0)
     36    OutputEvent(Type t) :
     37        MythEvent(t), error_msg(QString::null),
     38        elapsed_seconds(0), written_bytes(0),
     39        brate(0), freq(0), prec(0), chan(0)
    3440    { ; }
    3541
    36     OutputEvent(long s, unsigned long w, int b, int f, int p, int c)
    37         : MythEvent(Info), error_msg(0), elasped_seconds(s), written_bytes(w),
    38           brate(b), freq(f), prec(p), chan(c)
     42    OutputEvent(long s, unsigned long w, int b, int f, int p, int c) :
     43        MythEvent(Info), error_msg(QString::null), elapsed_seconds(s),
     44        written_bytes(w), brate(b), freq(f), prec(p), chan(c)
    3945    { ; }
    4046
    41     OutputEvent(const QString &e)
    42         : MythEvent(Error), elasped_seconds(0), written_bytes(0),
    43           brate(0), freq(0), prec(0), chan(0)
    44     {
    45         error_msg = new QString(e.utf8());
    46     }
     47    OutputEvent(const QString &e);
    4748
     49    virtual MythEvent *clone(void) const { return new OutputEvent(*this); }
    4850
    49     ~OutputEvent()
    50     {
    51         if (error_msg)
    52             delete error_msg;
    53     }
     51    virtual ~OutputEvent() {}
    5452
    55     const QString *errorMessage() const { return error_msg; }
     53    QString GetErrorMessage(void)    const;
     54    long elapsedSeconds(void)        const { return elapsed_seconds; }
     55    unsigned long writtenBytes(void) const { return written_bytes;   }
     56    int bitrate(void)                const { return brate; }
     57    int frequency(void)              const { return freq;  }
     58    int precision(void)              const { return prec;  }
     59    int channels(void)               const { return chan;  }
    5660
    57     const long &elapsedSeconds() const { return elasped_seconds; }
    58     const unsigned long &writtenBytes() const { return written_bytes; }
    59     const int &bitrate() const { return brate; }
    60     const int &frequency() const { return freq; }
    61     const int &precision() const { return prec; }
    62     const int &channels() const { return chan; }
     61  protected:
     62    OutputEvent(const OutputEvent&);
     63    OutputEvent(void);                            // prevent default ctor
     64    OutputEvent &operator=(const OutputEvent &o); // prevent default copy ctor
    6365
    64     virtual OutputEvent *clone() { return new OutputEvent(*this); };
    65 
    66 private:
    67     QString *error_msg;
    68 
    69     long elasped_seconds;
     66  protected:
     67    QString       error_msg;
     68    long          elapsed_seconds;
    7069    unsigned long written_bytes;
    71     int brate, freq, prec, chan;
     70    int           brate;
     71    int           freq;
     72    int           prec;
     73    int           chan;
    7274};
    7375
    7476
    7577class MPUBLIC OutputListeners : public MythObservable
    7678{
    77 public:
    78     OutputListeners();
    79     virtual ~OutputListeners();
     79  public:
     80    OutputListeners() : m_bufsize(0) {}
     81    virtual ~OutputListeners() {}
    8082
    8183    void addVisual(MythTV::Visual *);
    8284    void removeVisual(MythTV::Visual *);
    83    
    84     QMutex *mutex() { return &mtx; }
    8585
    86     void setBufferSize(unsigned int sz) { bufsize = sz; }
    87     unsigned int bufferSize() const { return bufsize; }
     86    void setBufferSize(unsigned int sz) { m_bufsize = sz; }
     87    unsigned int bufferSize(void) const { return m_bufsize; }
    8888
    89 protected:
     89  protected:
    9090    void error(const QString &e);
    91     void dispatchVisual(uchar *b, unsigned long b_len,
    92                        unsigned long written, int chan, int prec);
    93     void prepareVisuals();
     91    void dispatchVisual(
     92        uchar *buffer, unsigned long b_len,
     93        unsigned long written, int chan, int prec);
     94    void prepareVisuals(void);
    9495
    95 private:
    96     QMutex mtx;
    97     QPtrList<MythTV::Visual> visuals;
    98    
    99     unsigned int bufsize;
     96  private:
     97    typedef vector<MythTV::Visual*> VisualList;
     98    VisualList   m_visuals;
     99    unsigned int m_bufsize;
    100100};
    101101
    102102
  • mythtv/libs/libmyth/mythcontext.cpp

     
    39913991    return QDeepCopy<QString>(x11_display);
    39923992}
    39933993
    3994 void MythContext::dispatch(MythEvent &event)
     3994void MythContext::dispatch(const MythEvent &event)
    39953995{
    39963996    if (print_verbose_messages & VB_NETWORK)
    39973997        VERBOSE(VB_NETWORK, QString("MythEvent: %1").arg(event.Message()));
     
    39993999    MythObservable::dispatch(event);
    40004000}
    40014001
    4002 void MythContext::dispatchNow(MythEvent &event)
     4002void MythContext::dispatchNow(const MythEvent &event)
    40034003{
    40044004    if (print_verbose_messages & VB_NETWORK)
    40054005        VERBOSE(VB_NETWORK, QString("MythEvent: %1").arg(event.Message()));
  • mythtv/libs/libmyth/mythcontext.h

     
    106106
    107107/// Update this whenever the plug-in API changes.
    108108/// Including changes in the libmythtv class methods used by plug-ins.
    109 #define MYTH_BINARY_VERSION "0.21.20080224-1"
     109#define MYTH_BINARY_VERSION "0.21.20080226-1"
    110110
    111111/** \brief Increment this whenever the MythTV network protocol changes.
    112112 *
     
    318318    QString removeCurrentLocation(void);
    319319    QString getCurrentLocation(void);
    320320
    321     void dispatch(MythEvent &event);
    322     void dispatchNow(MythEvent &event);
     321    void dispatch(const MythEvent &event);
     322    void dispatchNow(const MythEvent &event);
    323323
    324324    void sendPlaybackStart(void);
    325325    void sendPlaybackEnd(void);
  • mythtv/libs/libmyth/output.cpp

     
    1 // Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
    2 //
    3 // Use, modification and distribution is allowed without limitation,
    4 // warranty, or liability of any kind.
    5 //
     1// -*- Mode: c++ -*-
     2/*
     3 * Copyright (c) 2000-2001 Brad Hughes <bhughes@trolltech.com>
     4 * Copyright (c) 2008 Daniel Kristjansson <danielk@cuymedia.net>
     5 *
     6 *   This program is free software; you can redistribute it and/or modify
     7 *   it under the terms of the GNU General Public License as published by
     8 *   the Free Software Foundation; either version 2 of the License, or
     9 *   (at your option) any later version.
     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 Free Software
     18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     19 */
    620
     21#include <algorithm> // for find
     22using namespace std;
     23
    724#include <qobject.h>
    825#include <qapplication.h>
     26#include <qdeepcopy.h>
    927
    1028#include "output.h"
    1129#include "visual.h"
    1230
    13 OutputListeners::OutputListeners()
     31OutputEvent::OutputEvent(const OutputEvent &other) :
     32    MythEvent(other), error_msg(QString::null),
     33    elapsed_seconds(other.elapsed_seconds),
     34    written_bytes(other.written_bytes),
     35    brate(other.brate), freq(other.freq),
     36    prec(other.prec), chan(other.chan)
    1437{
    15     bufsize=0;
     38    if (!other.error_msg.isNull())
     39        error_msg = QDeepCopy<QString>(other.error_msg);
    1640}
    1741
     42OutputEvent::OutputEvent(const QString &e) :
     43    MythEvent(Error), error_msg(QString::null),
     44    elapsed_seconds(0), written_bytes(0),
     45    brate(0), freq(0), prec(0), chan(0)
     46{
     47    error_msg = QDeepCopy<QString>(QString(e.utf8()));
     48}
    1849
    19 OutputListeners::~OutputListeners()
     50QString OutputEvent::GetErrorMessage(void) const
    2051{
     52    return QDeepCopy<QString>(error_msg);
    2153}
    2254
     55void OutputListeners::error(const QString &e)
     56{
     57    QMutexLocker locker(&m_lock);
    2358
    24 void OutputListeners::error(const QString &e) {
    25     QObject *object = firstListener();
    26     while (object) {
    27         QApplication::postEvent(object, new OutputEvent(e));
    28         object = nextListener();
    29     }
     59    ListenerList::iterator it = m_listeners.begin();
     60    for ( ; it != m_listeners.end(); ++it)
     61        QApplication::postEvent(*it, new OutputEvent(e));
    3062}
    3163
    32 void OutputListeners::addVisual(MythTV::Visual *v)
     64void OutputListeners::addVisual(MythTV::Visual *visual)
    3365{
    34     if (visuals.find(v) == -1) {
    35        visuals.append(v);
    36     }
     66    QMutexLocker locker(&m_lock);
     67
     68    VisualList::iterator it =
     69        find(m_visuals.begin(), m_visuals.end(), visual);
     70
     71    if (it == m_visuals.end())
     72        m_visuals.push_back(visual);
    3773}
    3874
    39 void OutputListeners::removeVisual(MythTV::Visual *v)
     75void OutputListeners::removeVisual(MythTV::Visual *visual)
    4076{
    41     visuals.remove(v);
     77    QMutexLocker locker(&m_lock);
     78
     79    VisualList::iterator it =
     80        find(m_visuals.begin(), m_visuals.end(), visual);
     81
     82    if (it != m_visuals.end())
     83        m_visuals.erase(it);
    4284}
    4385
    44 void OutputListeners::dispatchVisual(uchar *buffer, unsigned long b_len,
    45                         unsigned long written, int chan, int prec)
     86void OutputListeners::dispatchVisual(
     87    uchar *buffer, unsigned long b_len,
     88    unsigned long written, int chan, int prec)
    4689{
    47     if (! buffer)
    48        return;
     90    if (!buffer)
     91        return;
    4992
    50     MythTV::Visual *visual = visuals.first();
    51     while (visual) {
    52        visual->mutex()->lock();
    53        visual->add(buffer, b_len, written, chan, prec);
    54        visual->mutex()->unlock();
     93    QMutexLocker locker(&m_lock);
    5594
    56        visual = visuals.next();
     95    VisualList::iterator it = m_visuals.begin();
     96    for ( ; it != m_visuals.end(); ++it)
     97    {
     98       (*it)->mutex()->lock();
     99       (*it)->add(buffer, b_len, written, chan, prec);
     100       (*it)->mutex()->unlock();
    57101    }
    58102}
    59103
    60 void OutputListeners::prepareVisuals()
     104void OutputListeners::prepareVisuals(void)
    61105{
    62     MythTV::Visual *visual = visuals.first();
    63     while (visual) {
    64        visual->mutex()->lock();
    65        visual->prepare();
    66        visual->mutex()->unlock();
     106    QMutexLocker locker(&m_lock);
    67107
    68        visual = visuals.next();
     108    VisualList::iterator it = m_visuals.begin();
     109    for ( ; it != m_visuals.end(); ++it)
     110    {
     111       (*it)->mutex()->lock();
     112       (*it)->prepare();
     113       (*it)->mutex()->unlock();
    69114    }
    70115}
  • mythtv/libs/libmyth/mythobservable.cpp

     
     1// -*- Mode: c++ -*-
     2/*
     3 * Copyright (c) 2008 Daniel Kristjansson <danielk@cuymedia.net>
     4 *
     5 *   This program is free software; you can redistribute it and/or modify
     6 *   it under the terms of the GNU General Public License as published by
     7 *   the Free Software Foundation; either version 2 of the License, or
     8 *   (at your option) any later version.
     9 *
     10 *   This program is distributed in the hope that it will be useful,
     11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 *   GNU General Public License for more details.
     14 *
     15 *   You should have received a copy of the GNU General Public License
     16 *   along with this program; if not, write to the Free Software
     17 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     18 */
     19
     20#include <algorithm> // for find
     21using namespace std;
     22
    123#include <qobject.h>
    224#include <qapplication.h>
     25
    326#include "mythobservable.h"
    427
    5 MythObservable::MythObservable()
     28MythObservable::MythObservable() : m_lock(true)
    629{
    730}
    831
     
    1235
    1336void MythObservable::addListener(QObject *listener)
    1437{
    15     if (m_listeners.find(listener) == -1)
    16         m_listeners.append(listener);
     38    QMutexLocker locker(&m_lock);
     39
     40    ListenerList::iterator it =
     41        find(m_listeners.begin(), m_listeners.end(), listener);
     42
     43    if (it == m_listeners.end())
     44        m_listeners.push_back(listener);
    1745}
    1846
    1947void MythObservable::removeListener(QObject *listener)
    2048{
    21     if (m_listeners.find(listener) != -1)
    22         m_listeners.remove(listener);
    23 }
     49    QMutexLocker locker(&m_lock);
    2450
    25 QObject* MythObservable::firstListener()
    26 {
    27     return m_listeners.first();
     51    ListenerList::iterator it =
     52        find(m_listeners.begin(), m_listeners.end(), listener);
     53
     54    if (it != m_listeners.end())
     55        m_listeners.erase(it);
    2856}
    2957
    30 QObject* MythObservable::nextListener()
     58void MythObservable::dispatch(const MythEvent &event)
    3159{
    32     return m_listeners.next();
    33 }
     60    QMutexLocker locker(&m_lock);
    3461
    35 QPtrList<QObject> MythObservable::getListeners()
    36 {
    37     return m_listeners;
     62    ListenerList::iterator it = m_listeners.begin();
     63    for ( ; it != m_listeners.end(); ++it)
     64        QApplication::postEvent(*it, event.clone());
    3865}
    3966
    40 void MythObservable::dispatch(MythEvent &event)
     67void MythObservable::dispatchNow(const MythEvent &event)
    4168{
    42     QObject *listener = firstListener();
    43     while (listener)
    44     {
    45         QApplication::postEvent(listener, event.clone());
    46         listener = nextListener();
    47     }
    48 }
     69    QMutexLocker locker(&m_lock);
    4970
    50 void MythObservable::dispatchNow(MythEvent &event)
    51 {
    52     QObject *listener = firstListener();
    53     while (listener)
     71    ListenerList::iterator it = m_listeners.begin();
     72    for ( ; it != m_listeners.end(); ++it)
    5473    {
    5574        // Note: unlike postEvent, send event does not take
    5675        // ownership of pointer and will not delete it.
    57         QApplication::sendEvent(listener, &event);
    58         listener = nextListener();
     76        MythEvent *tmp = event.clone();
     77        QApplication::sendEvent(*it, tmp);
     78        delete tmp;
    5979    }
    6080}
    61 
  • mythtv/libs/libmyth/mythevent.h

     
     1// -*- Mode: c++ -*-
    12#ifndef MYTHEVENT_H_
    23#define MYTHEVENT_H_
    34
     
    1617class MPUBLIC MythEvent : public QCustomEvent
    1718{
    1819  public:
    19     enum Type { MythEventMessage = (User + 1000) };
     20    enum Type
     21    {
     22        MythEventBegin       = (User + 200),
     23        MythEventMessage     = MythEventBegin,
     24        MythEventEnd         = (User + 299),
     25        MythOutputEventBegin = (User + 300),
     26        // defined in output.h
     27        MythOutputEventEnd   = (User + 399),
     28    };
    2029
    2130    MythEvent(int t);
    2231    MythEvent(const QString &lmessage);
    2332    MythEvent(const QString &lmessage, const QStringList &lextradata);
     33    virtual MythEvent *clone(void) const { return new MythEvent(*this); }
    2434   
    2535    virtual ~MythEvent();
    2636
    27     const QString& Message() const { return message; }
    28     const QString& ExtraData(int idx = 0) const;
    29     const QStringList& ExtraDataList() const { return extradata; }
    30     int ExtraDataCount() const { return extradata.size(); }
     37    QString Message(void) const;
     38    QString ExtraData(int idx = 0) const;
     39    QStringList ExtraDataList(void) const;
     40    unsigned int ExtraDataCount(void) const;
    3141
    32     virtual MythEvent* clone() { return new MythEvent(message, extradata); }
     42    /// Note: do not assign the strings from this except with QDeepCopy
     43    const QStringList &ExtraDataListUnsafe(void) const;
    3344
    34   private:
    35     QString message;
     45  protected:
     46    MythEvent(const MythEvent &other);
     47    MythEvent(void);                          // prevent default ctor
     48    MythEvent &operator=(const MythEvent &o); // prevent default copy ctor
     49
     50  protected:
     51    QString     message;
    3652    QStringList extradata;
    3753};
    3854
  • mythtv/libs/libmyth/mythevent.cpp

     
    11// -*- Mode: c++ -*-
     2/*
     3 * Copyright (c) 2008 Daniel Kristjansson <danielk@cuymedia.net>
     4 *
     5 *   This program is free software; you can redistribute it and/or modify
     6 *   it under the terms of the GNU General Public License as published by
     7 *   the Free Software Foundation; either version 2 of the License, or
     8 *   (at your option) any later version.
     9 *
     10 *   This program is distributed in the hope that it will be useful,
     11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 *   GNU General Public License for more details.
     14 *
     15 *   You should have received a copy of the GNU General Public License
     16 *   along with this program; if not, write to the Free Software
     17 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     18 */
    219
    320#include "mythevent.h"
    421#include <qdeepcopy.h>
    522
     23MythEvent::MythEvent(const MythEvent &other) :
     24    QCustomEvent(MythEventMessage)
     25{
     26    message   = QDeepCopy<QString>(other.message);
     27    extradata = QDeepCopy<QStringList>(other.extradata);
     28}
     29
    630MythEvent::MythEvent(int t) :
    731    QCustomEvent(t), message(QString::null), extradata("empty")
    832{
     
    2650{
    2751}
    2852
    29 const QString &MythEvent::ExtraData(int idx) const
     53QString MythEvent::Message(void) const
    3054{
     55    return QDeepCopy<QString>(message);
     56}
     57
     58QString MythEvent::ExtraData(int idx) const
     59{
    3160    if (((uint)idx) < extradata.size())
    32         return extradata[idx];
     61        return QDeepCopy<QString>(extradata[idx]);
    3362    return QString::null;
    3463}
     64
     65QStringList MythEvent::ExtraDataList(void) const
     66{
     67    return QDeepCopy<QStringList>(extradata);
     68}
     69
     70const QStringList &MythEvent::ExtraDataListUnsafe(void) const
     71{
     72    return extradata;
     73}
     74
     75unsigned int MythEvent::ExtraDataCount(void) const
     76{
     77    return extradata.size();
     78}
  • mythtv/libs/libmyth/mythobservable.h

     
    11#ifndef MYTHOBSERVABLE_H_
    22#define MYTHOBSERVABLE_H_
    33
    4 #include <qptrlist.h>
     4// C++ headers
     5#include <vector>
     6using namespace std;
     7
     8// Qt headers
     9#include <qmutex.h>
     10
     11// MythTV headers
    512#include "mythexp.h"
    613#include "mythevent.h"
    714
     
    1421    listeners and iterating across them. It is typically used to post
    1522    events to listening QObjects.
    1623
    17        For example, to post a custom event with event id 100 to all listeners :
    18 
    19        \code
    20        void dispatch()
    21        {
    22            QObject *listener = firstListener();
    23                while (listener) {
    24                    QApplication::postEvent (listener, new QCustomEvent(100));
    25                listener = nextListener(); 
    26            }
    27        }
    28        \endcode
    29 
    3024    MythEvents can be dispatched to all listeners by calling dispatch
    3125    or dispatchNow. The former is much preferred as it uses
    3226    QApplication::postEvent() while the latter uses the blocking
     
    6155    */
    6256    void removeListener(QObject *listener);
    6357
    64     /** \brief Begin iteration across listeners
    65 
    66         If you simply need to iterate across the listeners, use \p
    67         firstListener and \p nextListener to iterate across the
    68         listeners. Ie. instead of
    69 
    70         \code
    71         {
    72             QPtrList<QObject> listeners = getListeners();
    73             QObject *listener = listeners.first();
    74             while (listener) {
    75                 // use listener...
    76                 listener = listeners.next();
    77             }
    78         }
    79         \endcode
    80 
    81         you can avoid the copy and just do
    82 
    83         \code
    84         {
    85             QObject *listener = firstListener();
    86             while (listener) {
    87                 // use listener...
    88                 listener = nextListener();
    89             }
    90         }
    91         \endcode
    92 
    93         \returns pointer to the first listener, NULL if there are no listeners
    94     */
    95     QObject* firstListener();
    96 
    97     /** \brief Continue iteration to the next listener
    98 
    99         See firstListener. Returns NULL if there are no more listeners.
    100 
    101         \returns pointer to the next listener, NULL if there are no more listeners
    102     */
    103     QObject* nextListener();
    104 
    105     /** \brief Get a copy of the list of listener
    106 
    107         If you need access to more than just iteration via
    108         firstListener/nextListerner, you can call this to obtain a
    109         QPtrList with all the listeners.
    110 
    111         \returns a copy of the list of listener
    112     */
    113     QPtrList<QObject> getListeners(void);
    114 
    11558    /** \brief Dispatch an event to all listeners
    11659                       
    11760        Makes a copy of the event on the heap by calling
     
    12063               
    12164        \param event a MythEvent to dispatch.
    12265    */
    123     void dispatch(MythEvent &event);
     66    void dispatch(const MythEvent &event);
    12467
    12568    /** \brief Dispatch an event to all listeners
    12669                       
     
    13174
    13275        \param event a MythEvent to dispatch.
    13376    */
    134     void dispatchNow(MythEvent &event);
     77    void dispatchNow(const MythEvent &event);
    13578
    136   private:
    137     QPtrList<QObject> m_listeners;
     79  protected:
     80    typedef vector<QObject*> ListenerList;
     81
     82    mutable QMutex   m_lock;
     83    ListenerList     m_listeners;
    13884};
    13985
    14086#endif /* MYTHOBSERVABLE_H */