/****************************************************************************
 ** Copyright (C) 2008-2013 Grigory A. Mozhaev <zcrendel@gmail.com>
 **
 ** This file is part of QMultiRecord (http://qt-apps.org/content/show.php?content=106254).
 **
 ** This file may be used under the terms of the GNU General Public
 ** License version 2.0 as published by the Free Software Foundation
 ** and appearing in the file LICENSE.GPL included in the packaging of
 ** this file.  Please review the following information to ensure GNU
 ** General Public Licensing requirements will be met:
 ** http://www.trolltech.com/products/qt/opensource.html
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 ****************************************************************************/
//! -*- coding: UTF-8 -*-
#define SOURCE_CODING "UTF-8"

/* libburn */
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

#include <libburn.h>
/***/


#include <QtCore>
#include <QtDBus>
#include <QtDBus/QDBusInterface>

#include "dvdmodel.h"

#define UDISKS_SERVICE           "org.freedesktop.UDisks"
#define UDISKS_PATH              "/org/freedesktop/UDisks"
#define UDISKS_INTERFACE         "org.freedesktop.UDisks"
#define UDISKS_DEVCHG            "DeviceChanged"
#define UDISKS_DEVICE_SIGNATURE  "o"
#define UDISKS_DEVICE_INTERFACE   "org.freedesktop.UDisks.Device"

/* libburn */
static quint64 libburn_capacity(char *drive_adr) {
    struct burn::burn_drive_info *drive_list;
    struct burn::burn_drive *drive;
    char libburn_drive_adr[BURN_DRIVE_ADR_LEN];

    int ret;
    char text[] = "qmultirecord : ";
    off_t free_space = 0;

    burn::burn_initialize();
    burn::burn_allow_drive_role_4(1);

    burn::burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
    burn::burn_set_signal_handling(text, NULL, 0x0);

    ret = burn::burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
    if (ret <= 0) {
        qWarning() << "libburn_capacity: address does not lead to CD device: '" << drive_adr << "'";
        return -1;
    }

    qDebug() << "libburn_capacity: aquiring drive '" << libburn_drive_adr << " ...";
    ret = burn::burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 0);
    if (ret <= 0) {
        qWarning() << "libburn_capacity: error - can't grab cd device using persistent address '" << libburn_drive_adr << "'";

        return -2;
    }
    drive = drive_list[0].drive;

    qDebug() << "Done";

    free_space= burn::burn_disc_available_space(drive, NULL);

    qDebug() << "libburn_capacity: blank capacity = " << free_space;

    burn::burn_drive_release(drive, 0);
    burn::burn_drive_info_free(drive_list);
    burn::burn_finish();

    return free_space;
}
/******/

//!
class DvdModelPrivate {
public:
    bool m_enabled;

    QString m_udisksDrive; // udisks dbus drive path
    QString m_deviceFile; // device file (e.g. /dev/sr0)
    QString m_deviceInfo; // model/vendor

    bool m_mediaIn;

    DvdModel::DeviceType  m_deviceType;
    DvdModel::DvdStatus   m_status;    
    DvdModel::ProcessMode m_processMode;    

    quint64 m_capacity;

    // minor
    BurnThread *m_burnThread;

    CheckThread *m_checkThread;
    QString m_hash;

    // very minor
    int m_speed;
    QString m_buffer;
    QString m_isoFileName;
    quint64 m_isoSize;

    bool m_streamRecording;

    DvdModelPrivate() {
        m_enabled = false;
        m_deviceFile  = QString::null;
        m_deviceInfo = QString::null;
        m_udisksDrive  = QString::null;

        m_mediaIn = false;
        m_status  = DvdModel::dsUndefined;
        m_deviceType = DvdModel::dtUndefined;
        m_processMode = DvdModel::pmNone;
        m_burnThread = 0;
        m_checkThread = 0;
        m_hash = QString::null;
        m_capacity = 0;

        m_speed = -1;
        m_buffer = QLatin1String("32m");
        m_isoFileName = QString::null;
        m_isoSize = 0;

        m_streamRecording = false;
    }

    ~DvdModelPrivate() {
    }

    static QMap<QString, DvdModel *> s_devices; // file, device
};

QMap<QString, DvdModel *> DvdModelPrivate::s_devices; // id, device

DvdModel::DvdModel(const QString &dbusPath, const QString &deviceFile, const QString &deviceInfo, int type)
    : m_data(0)
{
    if (!m_data) {
        m_data = new DvdModelPrivate;
    }

    Q_ASSERT(m_data!=0);

    m_data->m_udisksDrive = dbusPath;
    m_data->m_deviceFile = deviceFile;
    m_data->m_deviceInfo = deviceInfo;
    m_data->m_deviceType = static_cast<DvdModel::DeviceType>(type);
    m_data->m_mediaIn = false;
    m_data->m_status = DvdModel::dsNoDisc;
    m_data->m_capacity = 0;


    (void)QDBusConnection::systemBus().connect(UDISKS_SERVICE,
                                               m_data->m_udisksDrive,
                                               "org.freedesktop.UDisks.Device",
                                               "Changed",
                                               this, SLOT(deviceChanged()));
}

//!
DvdModel::~DvdModel() {
    if (m_data) {
        delete m_data;
        m_data = 0;
    }
}

bool DvdModel::enabled() const {
    return m_data->m_enabled;
}

void DvdModel::setEnabled(bool enabled) {
    m_data->m_enabled = enabled;
}

QList<DvdModel *> DvdModel::devices() {
    return DvdModelPrivate::s_devices.values();
}

DvdModel *DvdModel::devicesByFile(const QString &file) {
    if (DvdModelPrivate::s_devices.contains(file)) {
        return DvdModelPrivate::s_devices[file];
    }

    return 0;
}



void DvdModel::setBuffer(const QString &buffer) {
    if (m_data) {
        m_data->m_buffer = buffer;
    }
}

QString DvdModel::buffer() const {
    if (m_data) {
        return m_data->m_buffer;
    }

    return QString();
}

void DvdModel::setStreamRecording(bool enabled) {
    if (m_data) {
        m_data->m_streamRecording = enabled;
    }
}

bool DvdModel::streamRecording() const {
    if (m_data) {
        return m_data->m_streamRecording;
    }

    return true;
}

/*
QString DvdModel::deviceId() const {
    return m_data->m_deviceUniqueId;
}
*/
//!
bool isMediumBd(QDBusInterface &dbusInterface) {
    QStringList mediaTypes;
    mediaTypes << QLatin1String("optical_bd_r")
               << QLatin1String("optical_bd_re");

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DriveMedia");
    if (reply.isValid()) {
        QString media = reply.value().toString();
        if (mediaTypes.indexOf(media) >= 0) {
            return true;
        }
    }

    return false;
}

//!
bool isMediumDvd(QDBusInterface &dbusInterface) {
    QStringList mediaTypes;
    mediaTypes << QLatin1String("optical_dvd_r")
               << QLatin1String("optical_dvd_rw")
               << QLatin1String("optical_dvd_plus_r")
               << QLatin1String("optical_dvd_plus_rw")
               << QLatin1String("optical_dvd_plus_r_dl")
               << QLatin1String("optical_dvd_plus_rw_dl");

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DriveMedia");
    if (reply.isValid()) {
        QString media = reply.value().toString();
        if (mediaTypes.indexOf(media) >= 0) {
            return true;
        }
    }

    return false;
}

//!
bool isMediumCdrom(QDBusInterface &dbusInterface) {
    QStringList mediaTypes;
    mediaTypes << QLatin1String("optical_cd_r")
               << QLatin1String("optical_cd_rw");

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DriveMedia");
    if (reply.isValid()) {
        QString media = reply.value().toString();
        if (mediaTypes.indexOf(media) >= 0) {
            return true;
        }
    }

    return false;
}

//!
bool isDeviceCdrom(QDBusInterface &dbusInterface) {
    QStringList mediaTypes;
    mediaTypes << QLatin1String("optical_cd_r")
               << QLatin1String("optical_cd_rw");

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DriveMediaCompatibility");
    if (reply.isValid()) {
        QStringList compatible = reply.value().toStringList();
        foreach (QString media, mediaTypes) {
            if (compatible.indexOf(media) >= 0) {
                return true;
            }
        }
    }

    return false;
}

//!
bool isDeviceDvdrom(QDBusInterface &dbusInterface) {
    QStringList mediaTypes;
    mediaTypes << QLatin1String("optical_dvd_r")
               << QLatin1String("optical_dvd_rw")
               << QLatin1String("optical_dvd_plus_r")
               << QLatin1String("optical_dvd_plus_rw")
               << QLatin1String("optical_dvd_plus_r_dl")
               << QLatin1String("optical_dvd_plus_rw_dl");

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DriveMediaCompatibility");
    if (reply.isValid()) {
        QStringList compatible = reply.value().toStringList();
        foreach (QString media, mediaTypes) {
            if (compatible.indexOf(media) >= 0) {
                return true;
            }
        }
    }

    return false;
}

bool isDeviceBdrom(QDBusInterface &dbusInterface) {
    QStringList mediaTypes;
    mediaTypes << QLatin1String("optical_bd_r")
               << QLatin1String("optical_bd_re");

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DriveMediaCompatibility");
    if (reply.isValid()) {
        QStringList compatible = reply.value().toStringList();
        foreach (QString media, mediaTypes) {
            if (compatible.indexOf(media) >= 0) {
                return true;
            }
        }
    }

    return false;
}

//!
bool isEmpty(QDBusInterface &dbusInterface) {
    QDBusReply<QVariant> reply = dbusInterface.call( "Get", UDISKS_INTERFACE, "OpticalDiscIsBlank");
    if ((reply.isValid()) && (reply.value().toBool())) {
        return true;
    }

    return false;
}

//!
void DvdModel::initialize() {
    QSettings settings;
    QStringList activeDevices = settings.value("drives").toStringList();

    QDBusInterface dbusInterface( UDISKS_SERVICE, UDISKS_PATH, UDISKS_INTERFACE,
                                  QDBusConnection::systemBus());

    QDBusReply<QList<QDBusObjectPath> > reply = dbusInterface.call( "EnumerateDevices" );
    if (reply.isValid()) {
        foreach (QDBusObjectPath device, reply.value()) {
            QDBusInterface dbusDeviceInterface( UDISKS_SERVICE,
                                                device.path(),
                                                "org.freedesktop.DBus.Properties",
                                                QDBusConnection::systemBus() );

//            qDebug() << "Device " << device.path() << " found";
/*
            QDBusReply<QVariant> reply = dbusDeviceInterface.call( "Get", UDISKS_INTERFACE, "DeviceFileById");
            if (!reply.isValid()) {
                 continue;
            }

            QString id = reply.value().toString();
            if (uniqueIdList.indexOf(id) >= 0) {
                continue;
            }
            uniqueIdList << id;
*/
            bool isCdromDev = isDeviceCdrom(dbusDeviceInterface);
            bool isDvdromDev = isDeviceDvdrom(dbusDeviceInterface);
            bool isBdromDev = isDeviceBdrom(dbusDeviceInterface);
            if (isCdromDev || isDvdromDev || isBdromDev) {
                DeviceType type = DvdModel::dtCdWriter;

                if (isDvdromDev) type = DvdModel::dtDvdWriter;
                if (isBdromDev)  type = DvdModel::dtBdWriter;

                // device file
                QDBusReply<QVariant> deviceFile = dbusDeviceInterface.call( "Get", UDISKS_INTERFACE, "DeviceFile");
                if (deviceFile.isValid()) {
                    QString deviceInfo;

                    // product
                    QDBusReply<QVariant> product = dbusDeviceInterface.call( "Get", UDISKS_INTERFACE, "DriveModel");
                    if (product.isValid()) {
                        deviceInfo = product.value().toString();
                    }

                    qDebug() << "DeviceFile: " << deviceFile.value().toString();
                    qDebug() << "Can write: cd=" << isCdromDev << "dvd=" << isDvdromDev << "bd=" << isBdromDev;

                    DvdModel *model = new DvdModel(device.path(), deviceFile.value().toString(), deviceInfo, type);
                    DvdModelPrivate::s_devices.insert(deviceFile.value().toString(), model);

                    bool enabled = (activeDevices.indexOf(deviceFile.value().toString()) >= 0);
                    qDebug() << "Enabled by user: " << enabled;

                    if (enabled) {
                        model->setEnabled(true);
                    }
                }
            }
        }
    }
}

void DvdModel::finalize() {
    QList<DvdModel *> devices = DvdModelPrivate::s_devices.values();
    for (int i=0; i < devices.size(); i++) {
        devices.at(i)->cancel();
    }
    qApp->processEvents();
    usleep(100000);
    for (int i=0; i < devices.size(); i++) {
        devices.at(i)->deleteLater();
    }
    DvdModelPrivate::s_devices.clear();
}

void DvdModel::deviceChanged() {
    qDebug() << "DvdModel::deviceChanged [" << m_data->m_enabled << "] : id = " << m_data->m_udisksDrive;
    if (m_data->m_enabled) {
        checkMedia();
    }
}

/*
//!
void DvdModel::checkDevice(const QString &dbusPath) {
    Q_ASSERT(m_data);

    if (!m_data->m_deviceUniqueId.isEmpty()) return ;

    QDBusInterface dbusInterface( UDISKS_SERVICE,
                                  dbusPath,
                                  "org.freedesktop.DBus.Properties",
                                  QDBusConnection::systemBus());

    QDBusReply<QVariant> file = dbusInterface.call( "Get", UDISKS_INTERFACE, "DeviceFile");
    if (file.isValid() && (file.value().toString().compare(m_data->m_deviceFile) == 0) &&
            (m_data->m_deviceType == DvdModel::dtUndefined)) {

        m_data->m_udisksDrive = dbusPath;

        QDBusReply<QVariant> reply = dbusInterface.call( "Get", UDISKS_INTERFACE, "DeviceFileById");
        if (reply.isValid()) {
            m_data->m_deviceUniqueId = reply.value().toStringList().at(0);
        }

        bool isCdromDev = isDeviceCdrom(dbusInterface);
        bool isDvdromDev = isDeviceDvdrom(dbusInterface);
        bool isBdromDev = isDeviceBdrom(dbusInterface);

        if (isCdromDev || isDvdromDev | isBdromDev) {
            if (isCdromDev)  m_data->m_deviceType = DvdModel::dtCdWriter;
            if (isDvdromDev) m_data->m_deviceType = DvdModel::dtDvdWriter;
            if (isBdromDev)  m_data->m_deviceType = DvdModel::dtBdWriter;

            m_data->m_mediaIn = false;
            m_data->m_status = DvdModel::dsNoDisc;
            m_data->m_capacity = 0;

            //checkMedia(dbusPath);
            (void)QDBusConnection::systemBus().connect(UDISKS_SERVICE,
                                                       m_data->m_udisksDrive,
                                                       "org.freedesktop.UDisks.Device",
                                                       "Changed",
                                                       this, SLOT(deviceChanged()));

            checkMedia();
        } else {
            m_data->m_deviceType = DvdModel::dtUnsupported;
        }
    }
}
*/

void DvdModel::checkMedia() {
    Q_ASSERT(m_data);

    if (m_data->m_deviceType ==  DvdModel::dtUnsupported) {
        return ;
    }

    QDBusInterface dbusInterface( UDISKS_SERVICE,
                                  m_data->m_udisksDrive,
                                  "org.freedesktop.DBus.Properties",
                                  QDBusConnection::systemBus());

    QDBusReply<QVariant> reply = dbusInterface.call("Get", UDISKS_DEVICE_INTERFACE, "DeviceIsMediaAvailable");
    if (reply.isValid()) {
        bool mediaIn = reply.value().toBool();
        if (m_data->m_mediaIn == mediaIn) {
            return ;
        }
        qDebug() << "DvdModel::checkMedia : media status changed " << m_data->m_mediaIn << " --> " << mediaIn;
        m_data->m_mediaIn = mediaIn;
    } else {
        return ;
    }

    bool isCdrom = isMediumCdrom(dbusInterface);
    bool isDvd   = isMediumDvd(dbusInterface);
    bool isBd    = isMediumBd(dbusInterface);

    if (isCdrom || isDvd || isBd) {
        bool empty = isEmpty(dbusInterface);
        if (empty) {
            m_data->m_processMode = DvdModel::pmNone;

            if (isCdrom) {
                m_data->m_status = DvdModel::dsEmptyCd;
            } else
            if (isDvd) {
                m_data->m_status = DvdModel::dsEmptyDvd;
            } else {
                m_data->m_status = DvdModel::dsEmptyBd;
            }

            qApp->processEvents();
            qint64 capacity = libburn_capacity(m_data->m_deviceFile.toLatin1().data());
            if (capacity >= 0) {
                m_data->m_capacity = capacity;
            } else {
                m_data->m_capacity = 0;
            }

        } else {
            if (isCdrom) {
                m_data->m_status = DvdModel::dsDataCd;
            } else
            if (isDvd) {
                m_data->m_status = DvdModel::dsDataDvd;
            } else {
                m_data->m_status = DvdModel::dsDataBd;
            }

            QDBusReply<QVariant> capacity= dbusInterface.call( "Get", UDISKS_DEVICE_INTERFACE, "DeviceSize");
            if (capacity.isValid() && (capacity.value().toLongLong() >= 0)) {
                m_data->m_capacity = capacity.value().toULongLong();
            } else {
                m_data->m_capacity = 0;
            }
        }

        pollMedia();
    } else {
        m_data->m_status = DvdModel::dsNoDisc;
        m_data->m_capacity = 0;
    }

    update();
}

void DvdModel::pollMedia() {
    QDBusInterface dbusInterface( UDISKS_SERVICE,
                                  m_data->m_udisksDrive,
                                  "org.freedesktop.UDisks.Device",
                                  QDBusConnection::systemBus());

    QDBusReply<QVariant> reply = dbusInterface.call( "DrivePollMedia" );
}

/*
void DvdModel::checkAllDevices() {
    if (m_data) {
        QDBusInterface dbusInterface( UDISKS_SERVICE, UDISKS_PATH, UDISKS_INTERFACE,
                                      QDBusConnection::systemBus());

        QDBusReply<QList<QDBusObjectPath> > reply = dbusInterface.call( "EnumerateDevices" );
        if (reply.isValid()) {
            foreach (QDBusObjectPath device, reply.value()) {
                QDBusInterface dbusDeviceInterface( UDISKS_SERVICE,
                                                    device.path(),
                                                    "org.freedesktop.DBus.Properties",
                                                    QDBusConnection::systemBus() );

                checkDevice(device.path());
            }
        }
    }
}
*/

/*
void DvdModel::setDeviceFile(const QString &device) {
    if (m_data) {
        m_data->m_deviceFile = device;
        m_data->m_deviceType = DvdModel::dtUndefined;
        m_data->m_status = DvdModel::dsUndefined;
        m_data->m_deviceInfo = deviceInfo;
        checkAllDevices();

        update();
    }
}
*/

//!
QString DvdModel::deviceFile() const {
    if (m_data) {
        return m_data->m_deviceFile;
    }

    return QString::null;
}

//!
QString DvdModel::deviceInfo() const {
    if (m_data) {
        return m_data->m_deviceInfo;
    }

    return QString::null;
}


//!
void DvdModel::setSpeed(int speed) {
    if (m_data) {
        m_data->m_speed = speed;
    }
}

//!
int DvdModel::speed() const {
    if (m_data)
        return m_data->m_speed;

    return -1;
}

//!
quint64 DvdModel::capacity() const {
    if (m_data) {
        return m_data->m_capacity;
    }

    return -1;
}

//!
void DvdModel::setISOFileName(const QString &isoFileName) {
    if (m_data) {
        m_data->m_isoFileName = isoFileName;
    }
}

//!
QString DvdModel::isoFileName() const {
    if (m_data) {
        return m_data->m_isoFileName;
    }

    return QString::null;
}

//!
void DvdModel::setISOSize(quint64 size) {
    if (m_data)
        m_data->m_isoSize = size;
}


//!
quint64 DvdModel::isoSize() const {
    if (m_data)
        return m_data->m_isoSize;

    return quint64(0);
}

//!
DvdModel::DvdStatus DvdModel::dvdStatus() const {
    if (m_data)
        return m_data->m_status;

    return DvdModel::dsUndefined;
}

//!
DvdModel::ProcessMode DvdModel::processMode() const {
    if (m_data)
        return m_data->m_processMode;

    return DvdModel::pmNone;
}

//!
void DvdModel::update() {
    if (m_data) {
        emit(statusChanged(QString("%1 : %2").arg(m_data->m_deviceFile).arg(m_data->m_deviceInfo),
                           m_data->m_deviceType,  m_data->m_status, 
                           m_data->m_processMode, m_data->m_capacity, m_data->m_hash));
    } else {
        qDebug() << "mpData is NULL!";
    }
}


//////////////// SLOTS /////////////////////////////

//!
void DvdModel::burnISO(const QString fileName) {
    if (m_data->m_burnThread) return ;

    if (m_data->m_status == DvdModel::dsEmptyCd
       || m_data->m_status == DvdModel::dsEmptyDvd
       || m_data->m_status == DvdModel::dsEmptyBd) {
       m_data->m_burnThread = new BurnCDThread();
    } else {
      return ;
    }

    setISOFileName(fileName);
    m_data->m_burnThread->init(this);

    connect(m_data->m_burnThread, SIGNAL(finished()),
            this, SLOT(burnThreadFinished()));

    connect(m_data->m_burnThread, SIGNAL(started()),
            this, SLOT(burnThreadStarted()));

    connect(m_data->m_burnThread, SIGNAL(progress(int,const QString &)),
            this, SIGNAL(progress(int,const QString &)));

    m_data->m_burnThread->start();
}

//!
void DvdModel::cancel() {
    if (m_data->m_burnThread) {
        m_data->m_burnThread->stop();
    } else
    if (m_data->m_checkThread) {
        m_data->m_checkThread->stop();
    }
}


//!
void DvdModel::burnThreadFinished() {
    qDebug() << "burnThreadFinished!";
    if (m_data->m_burnThread) {
        if (m_data->m_burnThread->done()) {
            m_data->m_processMode = DvdModel::pmWriteDone;
        } else {
            m_data->m_processMode = DvdModel::pmWriteFailed;
        }
        update();

        delete m_data->m_burnThread;
        m_data->m_burnThread = 0;
    }
}

//!
void DvdModel::burnThreadStarted() {
    qDebug() << "burnThreadStarted!";

    m_data->m_processMode = DvdModel::pmWriting;
    update();
}

//!
void DvdModel::checkSum(quint64 aSize) {
    if (m_data->m_checkThread) return ;

    m_data->m_isoSize = aSize;
    m_data->m_checkThread = new CheckThread();
    m_data->m_checkThread->init(this);

    connect(m_data->m_checkThread, SIGNAL(finished()),
            this, SLOT(checkThreadFinished()));

    connect(m_data->m_checkThread, SIGNAL(started()),
            this, SLOT(checkThreadStarted()));

    connect(m_data->m_checkThread, SIGNAL(progress(int,const QString &)),
            this, SIGNAL(progress(int,const QString &)));

    m_data->m_checkThread->start();
}


void DvdModel::checkThreadFinished() {
    qDebug() << "checkThreadFinished!";
    m_data->m_hash = QLatin1String("");

    if (m_data->m_checkThread) {
        if (m_data->m_checkThread->done()) {
            m_data->m_hash = m_data->m_checkThread->hash();
            m_data->m_processMode = DvdModel::pmCheckDone;
        } else {
            m_data->m_processMode = DvdModel::pmCheckFailed;
        }
        update();
        delete m_data->m_checkThread;
        m_data->m_checkThread = 0;
    }
}


//!
void DvdModel::checkThreadStarted() {
    qDebug() << "checkThreadStarted!";

    m_data->m_processMode = DvdModel::pmChecking;
    update();
}


