File indexing completed on 2024-04-28 04:49:53

0001 /*
0002     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "k3bthreadwidget.h"
0007 #include "k3bdeviceselectiondialog.h"
0008 #include "k3bdevice.h"
0009 
0010 #include <QCoreApplication>
0011 #include <QEvent>
0012 #include <QMutex>
0013 #include <QWaitCondition>
0014 
0015 
0016 class K3b::ThreadWidget::Data
0017 {
0018 public:
0019     int id;
0020     void* data;
0021     QWaitCondition con;
0022 };
0023 
0024 
0025 class K3b::ThreadWidget::DeviceSelectionEvent : public QEvent
0026 {
0027 public:
0028     DeviceSelectionEvent( QWidget* parent, const QString& text, int id )
0029         : QEvent( QEvent::User ),
0030           m_parent(parent),
0031           m_text(text),
0032           m_id(id) {
0033     }
0034 
0035     QWidget* parent() const { return m_parent; }
0036     const QString& text() const { return m_text; }
0037     int id() const { return m_id; }
0038 
0039 private:
0040     QWidget* m_parent;
0041     QString m_text;
0042     int m_id;
0043 };
0044 
0045 
0046 K3b::ThreadWidget* K3b::ThreadWidget::s_instance = 0;
0047 
0048 
0049 K3b::ThreadWidget::ThreadWidget()
0050     : QObject(),
0051       m_idCounter(1)
0052 {
0053     s_instance = this;
0054 }
0055 
0056 
0057 K3b::ThreadWidget::~ThreadWidget()
0058 {
0059     qDeleteAll( m_dataMap );
0060     s_instance = 0;
0061 }
0062 
0063 
0064 int K3b::ThreadWidget::getNewId()
0065 {
0066     // create new data
0067     Data* data = new Data;
0068     data->id = m_idCounter++;
0069     data->data = 0;
0070     m_dataMap.insert( data->id, data );
0071     return data->id;
0072 }
0073 
0074 
0075 void K3b::ThreadWidget::clearId( int id )
0076 {
0077     m_dataMap.remove( id );
0078 }
0079 
0080 
0081 K3b::ThreadWidget::Data* K3b::ThreadWidget::data( int id )
0082 {
0083     return m_dataMap[id];
0084 }
0085 
0086 
0087 K3b::ThreadWidget* K3b::ThreadWidget::instance()
0088 {
0089     if( !s_instance )
0090         s_instance = new K3b::ThreadWidget();
0091     return s_instance;
0092 }
0093 
0094 
0095 // static
0096 K3b::Device::Device* K3b::ThreadWidget::selectDevice( QWidget* parent,
0097                                                   const QString& text )
0098 {
0099     // request a new data set
0100     Data* data = K3b::ThreadWidget::instance()->data( K3b::ThreadWidget::instance()->getNewId() );
0101 
0102     // inform the instance about the request
0103     QCoreApplication::postEvent( K3b::ThreadWidget::instance(),
0104                              new K3b::ThreadWidget::DeviceSelectionEvent( parent, text, data->id ) );
0105 
0106     // wait for the result to be ready
0107     QMutex mutex;
0108     mutex.lock();
0109     data->con.wait( &mutex );
0110     mutex.unlock();
0111 
0112     K3b::Device::Device* dev = static_cast<K3b::Device::Device*>( data->data );
0113 
0114     // delete the no longer needed data
0115     K3b::ThreadWidget::instance()->clearId( data->id );
0116 
0117     return dev;
0118 }
0119 
0120 
0121 void K3b::ThreadWidget::customEvent( QEvent* e )
0122 {
0123     if( DeviceSelectionEvent* dse = dynamic_cast<DeviceSelectionEvent*>(e) ) {
0124         // create dialog
0125         K3b::Device::Device* dev = K3b::DeviceSelectionDialog::selectDevice( dse->parent(), dse->text() );
0126 
0127         // return it to the thread
0128         Data* dat = data( dse->id() );
0129         dat->data = static_cast<void*>( dev );
0130 
0131         // wake the thread
0132         dat->con.wakeAll();
0133     }
0134 }
0135 
0136 #include "moc_k3bthreadwidget.cpp"