code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : UIMain.cpp
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#include "UIMain.h"
#include "UIAbout.h"
#include "models/DiscModel.h"
#include "models/DiscDelegate.h"
#include "wiitdb/Covers.h"
#include "ProgressDialog.h"
#include "PropertiesDialog.h"
#include "Properties.h"
#include "main.h"

#include <FreshCore/pNetworkAccessManager>
#include <FreshCore/pTranslationManager>
#include <FreshGui/pTranslationDialog>
#include <FreshGui/pUpdateChecker>
#include <FreshGui/pPaypalButton>
#include "models/pPartitionModel.h" // will be part of fresh library in a next version

#include <QMenuBar>
#include <QMenu>
#include <QFileSystemModel>
#include <QFileDialog>
#include <QProcess>
#include <QMessageBox>
#include <QInputDialog>
#include <QPainter>
#include <QNetworkReply>
#include <QDesktopServices>
#include <QDebug>

#define COVER_DISC_SIZE QSize( 160, 160 )
#define COVER_SIZE QSize( 160, 224 )

UIMain::UIMain( QWidget* parent )
    : QMainWindow( parent )
{
#if defined( Q_OS_MAC )
    mMenuBar = new QMenuBar;
#endif
    mCache = pNetworkAccessManager::instance();
    mUpdateChecker = new pUpdateChecker( this );
    mUpdateChecker->setDownloadsFeedUrl( QUrl( APPLICATION_DOWNLOADS_FEED ) );
    mUpdateChecker->setVersion( APPLICATION_VERSION );
    mUpdateChecker->setVersionString( APPLICATION_VERSION_STR );
    mUpdateChecker->setVersionDiscoveryPattern( ".*qwbfsmanager-([0-9\\.]+).*" );

    setWindowTitle( QString( "%1 v%2" ).arg( APPLICATION_NAME ).arg( APPLICATION_VERSION_STR ) );
    setUnifiedTitleAndToolBarOnMac( true );
    setupUi( this );

#if defined( Q_OS_MAC )
    mMenuBar->addMenu( "Fake" )->addAction( aProperties );
#endif

    centralVerticalLayout->setMenuBar( qmtbInfos );
    qmtbInfos->layout()->setMargin( 5 );
    qmtbInfos->queuedMessageWidget()->setContentsMargins( 5, 0, 5, 0 );
    qmtbInfos->setVisible( false );

    dwTools->toggleViewAction()->setIcon( QIcon( ":/icons/256/tools.png" ) );
    dwCovers->toggleViewAction()->setIcon( QIcon( ":/icons/256/covers.png" ) );

    mDonationWidget = new pPaypalButton( this );
    mDonationWidget->setBusinessId( "5R924WYXJ6BAW" );
    mDonationWidget->setItemName( "QWBFS Manager" );
    mDonationWidget->setItemId( "QWBFS-DONATION" );
    mDonationWidget->setCurrencyCode( "EUR" );

    mActions = new QMenu( this );
    mActions->setIcon( aConvertToWBFSFiles->icon() );
    mActions->addAction( aConvertToWBFSFiles );
    mActions->addAction( aConvertToISOFiles );
    mActions->addAction( aRenameDiscsInFolder );

    toolBar->insertAction( aAbout, mUpdateChecker->menuAction() );
    toolBar->addAction( mActions->menuAction() );
    toolBar->addSeparator();
    toolBar->addAction( dwTools->toggleViewAction() );
    toolBar->addAction( dwCovers->toggleViewAction() );
    QWidget* spacerWidget = new QWidget( toolBar );
    spacerWidget->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum ) );
    toolBar->addWidget( spacerWidget );
    toolBar->addWidget( mDonationWidget );

    mFoldersModel = new QFileSystemModel( this );
    mFoldersModel->setFilter( QDir::Dirs | QDir::NoDotAndDotDot );

    mFilesModel = new QFileSystemModel( this );
    mFilesModel->setFilter( QDir::Files );

    tvFolders->setModel( mFoldersModel );
    tvFolders->setColumnHidden( 1, true );
    tvFolders->setColumnHidden( 2, true );
    tvFolders->setColumnHidden( 3, true );

    lvFiles->setModel( mFilesModel );

    lvExport->initialize( 0, mCache );

    mLastDiscId = -1;

    pwMainView->setMainView( true );
    pwMainView->showHideImportViewButton()->setChecked( false );
    connectView( pwMainView );

    qmtbInfos->installEventFilter( this );
    lWiiTDB->installEventFilter( this );

    localeChanged();

    connect( mCache, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( networkAccessManager_finished( QNetworkReply* ) ) );
    connect( mCache, SIGNAL( cached( const QUrl& ) ), this, SLOT( networkAccessManager_cached( const QUrl& ) ) );
    connect( mCache, SIGNAL( error( const QUrl&, const QString& ) ), this, SLOT( networkAccessManager_error( const QUrl&, const QString& ) ) );
    connect( mCache, SIGNAL( cacheCleared() ), this, SLOT( networkAccessManager_cacheCleared() ) );
}

UIMain::~UIMain()
{
#if defined( Q_OS_MAC )
    delete mMenuBar;
#endif
    //qWarning() << Q_FUNC_INFO;
}

pNetworkAccessManager* UIMain::cache() const
{
    return mCache;
}

pQueuedMessageToolBar* UIMain::messageToolBar() const
{
    return qmtbInfos;
}

bool UIMain::event( QEvent* event )
{
    switch ( event->type() ) {
        case QEvent::LocaleChange:
            localeChanged();
            break;
        default:
            break;
    }

    return QMainWindow::event( event );
}

void UIMain::showEvent( QShowEvent* event )
{
    QMainWindow::showEvent( event );

    static bool shown = false;

    if ( !shown ) {
        shown = true;
        loadProperties();
        mUpdateChecker->silentCheck();
        qmtbInfos->appendMessage( tr(
                "Welcome to %1, the cross-platform WBFS Manager. Report bugs here, discuss here."
            ).arg( APPLICATION_NAME ).arg( APPLICATION_REPORT_BUG_URL ).arg( APPLICATION_DISCUSS_URL ) );
    }
}

void UIMain::closeEvent( QCloseEvent* event )
{
    saveProperties();

    QMainWindow::closeEvent( event );
}

bool UIMain::eventFilter( QObject* object, QEvent* event )
{
    if ( object == qmtbInfos ) {
        if ( event->type() == QEvent::Paint ) {
            if ( qmtbInfos->queuedMessageWidget()->pendingMessageCount() > 0 ) {
                QPainter painter( qmtbInfos );
                QBrush brush;

                qmtbInfos->queuedMessageWidget()->currentMessageInformations( 0, &brush, 0 );

                painter.setRenderHint( QPainter::Antialiasing );
                painter.setPen( QPen( brush.color().darker( 150 ), 0.5 ) );
                painter.setBrush( brush );
                painter.drawRoundedRect( qmtbInfos->rect().adjusted( 10 -4, -9, -10 +4, -1 ), 9, 9 );

                return true;
            }
        }
    }
    else if ( object == lWiiTDB ) {
        if ( event->type() == QEvent::MouseButtonPress ) {
            QDesktopServices::openUrl( lWiiTDB->toolTip() );
        }
    }

    return QMainWindow::eventFilter( object, event );
}

void UIMain::connectView( PartitionWidget* widget )
{
    connect( widget, SIGNAL( openViewRequested() ), this, SLOT( openViewRequested() ) );
    connect( widget, SIGNAL( closeViewRequested() ), this, SLOT( closeViewRequested() ) );
    connect( widget, SIGNAL( coverRequested( const QString& ) ), this, SLOT( coverRequested( const QString& ) ) );
}

void UIMain::localeChanged()
{
    retranslateUi( this );
    mActions->setTitle( tr( "Actions" ) );
}

void UIMain::loadProperties( bool firstInit )
{
    Properties properties( this );

    PartitionComboBox::partitionModel()->addPartitions( properties.customPartitions() );

    tbReloadDrives->click();
    aReloadPartitions->trigger();

    mCache->setMaximumCacheSize( properties.cacheDiskSize() );
    mCache->setCacheDirectory( properties.cacheUseTemporaryPath() ? properties.temporaryPath() : properties.cacheWorkingPath() );

    QNetworkProxy proxy( properties.proxyType() );
    proxy.setHostName( properties.proxyServer() );
    proxy.setPort( properties.proxyPort() );
    proxy.setUser( properties.proxyLogin() );
    proxy.setPassword( properties.proxyPassword() );

    QNetworkProxy::setApplicationProxy( proxy );

    if ( firstInit ) {
        mUpdateChecker->setLastUpdated( properties.updateLastUpdated() );
        mUpdateChecker->setLastChecked( properties.updateLastChecked() );

        const QModelIndex index = mFoldersModel->index( properties.selectedPath() );

        properties.restoreState( this );
        tvFolders->setCurrentIndex( index );
        tvFolders->scrollTo( index );
        on_tvFolders_activated( index );
        pwMainView->setCurrentPartition( properties.selectedPartition() );
    }

    pTranslationManager* translationManager = pTranslationManager::instance();
    translationManager->setTranslationsPaths( properties.translationsPaths() );
    translationManager->setCurrentLocale( properties.locale().name() );

    if ( !properties.localeAccepted() ) {
        changeLocaleRequested();
    }

    translationManager->reloadTranslations();

    foreach ( QWidget* widget, QApplication::topLevelWidgets() ) {
        widget->setLocale( translationManager->currentLocale() );
    }

    foreach ( ListView* view, findChildren<ListView*>() ) {
        view->setViewMode( properties.viewMode() );
        view->setViewIconType( properties.viewIconType() );
    }
}

void UIMain::saveProperties()
{
    const QModelIndex index = tvFolders->selectionModel()->selectedIndexes().value( 0 );
    const QString selectedPath = mFoldersModel->filePath( index );
    Properties properties;

    properties.setUpdateLastUpdated( mUpdateChecker->lastUpdated() );
    properties.setUpdateLastChecked( mUpdateChecker->lastChecked() );
    properties.setSelectedPath( selectedPath );
    properties.setSelectedPartition( pwMainView->currentPartition() );
    properties.setCustomPartitions( PartitionComboBox::partitionModel()->customPartitions() );
    properties.saveState( this );
}

void UIMain::changeLocaleRequested()
{
    pTranslationManager* translationManager = pTranslationManager::instance();
    const QString locale = pTranslationDialog::getLocale( translationManager, this );

    if ( !locale.isEmpty() ) {
        Properties properties;
        properties.setTranslationsPaths( translationManager->translationsPaths() );
        properties.setLocaleAccepted( true );
        properties.setLocale( QLocale( locale ) );

        translationManager->setCurrentLocale( locale );
    }
}

void UIMain::propertiesChanged()
{
    loadProperties( false );
}

void UIMain::openViewRequested()
{
    PartitionWidget* pw = new PartitionWidget( this );
    pw->setMainView( false );
    pw->showHideImportViewButton()->setChecked( false );
    connectView( pw );
    sViews->addWidget( pw );
}

void UIMain::closeViewRequested()
{
    sender()->deleteLater();
}

void UIMain::coverRequested( const QString& id )
{
    mLastDiscId = id;

    networkAccessManager_cached( QUrl( WIITDB_DOMAIN ) );
    QWBFS::WiiTDB::coverDiscPixmap( id, mCache, COVER_DISC_SIZE );
    QWBFS::WiiTDB::coverBoxPixmap( id, mCache, COVER_SIZE );
}

void UIMain::progress_jobFinished( const QWBFS::Model::Disc& disc )
{
    lvExport->model()->updateDisc( disc );
}

void UIMain::networkAccessManager_finished( QNetworkReply* reply )
{
    reply->deleteLater();
}

void UIMain::networkAccessManager_cached( const QUrl& url )
{
    if ( !url.toString().startsWith( WIITDB_DOMAIN, Qt::CaseInsensitive ) && url != QUrl() ) {
        return;
    }

    // update all models
    const QString id = QFileInfo( url.path() ).baseName();
    const QList<QWBFS::Model::DiscModel*> models = findChildren<QWBFS::Model::DiscModel*>();

    foreach ( QWBFS::Model::DiscModel* model, models ) {
        const QModelIndex index = model->index( id );

        model->setData( index, QVariant(), Qt::DecorationRole );
    }

    lCDCover->setPixmap( QWBFS::WiiTDB::coverDiscPixmap( mLastDiscId, mCache, COVER_DISC_SIZE ) );
    lCover->setPixmap( QWBFS::WiiTDB::coverBoxPixmap( mLastDiscId, mCache, COVER_SIZE ) );
}

void UIMain::networkAccessManager_error( const QUrl& url, const QString& message )
{
    if ( !url.toString().startsWith( WIITDB_DOMAIN, Qt::CaseInsensitive ) ) {
        return;
    }

    const QString id = QFileInfo( url.path() ).baseName();

    switch ( QWBFS::WiiTDB::urlCover( url ) )
    {
        case QWBFS::WiiTDB::CoverDisc: {
            const QUrl enUrl = QWBFS::WiiTDB::coverUrl( QWBFS::WiiTDB::CoverDisc, id, "EN" );

            // request english
            if ( url != enUrl ) {
                mCache->get( QNetworkRequest( enUrl ) );
            }
            // or custom disk
            else {
                mCache->get( QNetworkRequest( QWBFS::WiiTDB::coverUrl( QWBFS::WiiTDB::CoverDiscCustom, id ) ) );
            }

            return;
        }
        case QWBFS::WiiTDB::CoverDiscCustom: {
            const QUrl enUrl = QWBFS::WiiTDB::coverUrl( QWBFS::WiiTDB::CoverDiscCustom, id, "EN" );

            // request english
            if ( url != enUrl ) {
                mCache->get( QNetworkRequest( enUrl ) );
                return;
            }

            break;
        }
        case QWBFS::WiiTDB::Cover: {
            const QUrl enUrl = QWBFS::WiiTDB::coverUrl( QWBFS::WiiTDB::Cover, id, "EN" );

            // request english
            if ( url != enUrl ) {
                mCache->get( QNetworkRequest( enUrl ) );
                return;
            }

            break;
        }
        case QWBFS::WiiTDB::CoverHQ:
        case QWBFS::WiiTDB::Cover3D:
        case QWBFS::WiiTDB::CoverFull:
        case QWBFS::WiiTDB::CoverInvalid:
            break;
    }

    qmtbInfos->appendMessage( message );
}

void UIMain::networkAccessManager_cacheCleared()
{
    networkAccessManager_cached( QUrl() );
}

void UIMain::on_aReloadPartitions_triggered()
{
    PartitionComboBox::partitionModel()->update();

    if ( PartitionComboBox::partitionModel()->rowCount() == 0 ) {
        qmtbInfos->appendMessage( tr(
                "I don't know how to list partition for this platform.\n"
                "You will have to set the correct partition path yourself for mounting partitions." ) );
    }
}

void UIMain::on_aQuit_triggered()
{
    close();
}

void UIMain::on_aAbout_triggered()
{
    UIAbout* about = new UIAbout( this );
    about->open();
}

void UIMain::on_aProperties_triggered()
{
    saveProperties();

    PropertiesDialog* dlg = new PropertiesDialog( this );
    connect( dlg, SIGNAL( propertiesChanged() ), this, SLOT( propertiesChanged() ) );

    dlg->open();
}

void UIMain::on_aConvertToWBFSFiles_triggered()
{
    const QStringList filePaths = QFileDialog::getOpenFileNames( this, tr( "Choose ISO files to convert" ), QString::null, tr( "ISO Files (*.iso)" ) );

    if ( filePaths.isEmpty() ) {
        return;
    }

    ProgressDialog* dlg = new ProgressDialog( this );

    WorkerThread::Work work;
    work.task = WorkerThread::ConvertWBFS;

    foreach ( const QString& filePath, filePaths ) {
        work.discs << QWBFS::Model::Disc( filePath );
    }

    work.target = QFileInfo( filePaths.first() ).absolutePath();
    work.window = dlg;

    dlg->setWork( work );
}

void UIMain::on_aConvertToISOFiles_triggered()
{
    const QStringList filePaths = QFileDialog::getOpenFileNames( this, tr( "Choose WBFS files to convert" ), QString::null, tr( "WBFS Files (*.wbfs)" ) );

    if ( filePaths.isEmpty() ) {
        return;
    }

    ProgressDialog* dlg = new ProgressDialog( this );

    WorkerThread::Work work;
    work.task = WorkerThread::ConvertISO;

    foreach ( const QString& filePath, filePaths ) {
        work.discs << QWBFS::Model::Disc( filePath );
    }

    work.target = QFileInfo( filePaths.first() ).absolutePath();
    work.window = dlg;

    dlg->setWork( work );
}

void UIMain::on_aRenameDiscsInFolder_triggered()
{
    const QString path = QFileDialog::getExistingDirectory( this, tr( "Choose the folder to scan for ISOs/WBFSs files" ) );

    if ( path.isEmpty() ) {
        return;
    }

    /*
        %title = Game Title
        %id = Game ID
        %suffix = File Suffix
    */
    const QStringList patterns = QStringList()
        << "%id.%suffix" // GAMEID.wbfs
        << "%title [%id].%suffix" // Game Title [GAMEID].wbfs
        << "%id_%title/%id.%suffix" // GAMEID_Game Title/GAMEID.wbfs
        << "%title/%id.%suffix" // Game Title/GAMEID.wbfs
        << "%title[%id]/%id.%suffix" // Game Title[GAMEID]/GAMEID.wbfs
        ;
    const QString text = tr( "Choose the pattern to apply:\n%1\n%2\n%3\n" )
        .arg( tr( "%1 = Game Title" ).arg( "%title" ) )
        .arg( tr( "%1 = Game Id" ).arg( "%id" ) )
        .arg( tr( "%1 = File Suffix" ).arg( "%suffix" ) )
        ;
    bool ok;
    const QString pattern = QInputDialog::getItem( this, QString::null, text, patterns, 0, true, &ok );

    if ( !ok || pattern.isEmpty() ) {
        return;
    }

    ProgressDialog* dlg = new ProgressDialog( this );

    WorkerThread::Work work;
    work.task = WorkerThread::RenameAll;
    work.pattern = pattern;
    work.target = path;
    work.window = dlg;

    dlg->setWork( work );
}

void UIMain::on_tvFolders_activated( const QModelIndex& index )
{
    const QString filePath = mFoldersModel->filePath( index );
    mFilesModel->setRootPath( filePath );
    lvFiles->setRootIndex( mFilesModel->index( filePath ) );
}

void UIMain::on_tbReloadDrives_clicked()
{
    const QString drive = cbDrives->currentText();
    QFileInfoList drives = QDir::drives();
    QStringList pathsToScan;

    cbDrives->clear();
#if defined( Q_OS_WIN )
#elif defined( Q_OS_MAC )
    pathsToScan << "/Volumes";
#else
    pathsToScan  << "/media" << "/mnt";
#endif

    foreach ( const QString& path, pathsToScan ) {
        foreach ( const QFileInfo& fi, QDir( path ).entryInfoList( QDir::Dirs | QDir::NoDotAndDotDot ) ) {
            if ( !drives.contains( fi ) ) {
                drives << fi;
            }
        }
    }

    foreach ( const QFileInfo& fi, drives ) {
        cbDrives->addItem( fi.absoluteFilePath() );
    }

    if ( !drive.isEmpty() ) {
        cbDrives->setCurrentIndex( cbDrives->findText( drive ) );
    }
}

void UIMain::on_cbDrives_currentIndexChanged( const QString& text )
{
    mFoldersModel->setRootPath( text );
    tvFolders->setRootIndex( mFoldersModel->index( text ) );
    on_tvFolders_activated( tvFolders->rootIndex() );
}

void UIMain::on_tbClearExport_clicked()
{
    lvExport->model()->clear();
}

void UIMain::on_tbRemoveExport_clicked()
{
    lvExport->model()->removeSelection( lvExport->selectionModel()->selection() );
}

void UIMain::on_tbExport_clicked()
{
    if ( lvExport->model()->rowCount() == 0 ) {
        return;
    }

    const QString path = QFileDialog::getExistingDirectory( this, tr( "Choose a folder to export the discs" ), QString::null );

    if ( path.isEmpty() ) {
        return;
    }

    WorkerThread::Work work;
    work.discs = lvExport->model()->discs();
    work.target = path;

    const QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::Ok;
    const QMessageBox::StandardButton defaultButton = QMessageBox::Ok;

    QMessageBox msgBox( this );
    msgBox.setIcon( QMessageBox::Question );
    msgBox.setText( tr( "Which format do you want to use to export the discs ?" ) );
    msgBox.setStandardButtons( buttons );
    msgBox.button( QMessageBox::Yes )->setText( "ISO" );
    msgBox.button( QMessageBox::Ok )->setText( "WBFS" );
    msgBox.setEscapeButton( 0 );
    msgBox.setDefaultButton( defaultButton );

    switch ( msgBox.exec() ) {
        case QMessageBox::Yes:
            work.task = WorkerThread::ExportISO;
            break;
        case QMessageBox::Ok:
            work.task = WorkerThread::ExportWBFS;
            break;
        default:
            Q_ASSERT( 0 );
            return;
    }

    ProgressDialog* dlg = new ProgressDialog( this );

    connect( dlg, SIGNAL( jobFinished( const QWBFS::Model::Disc& ) ), this, SLOT( progress_jobFinished( const QWBFS::Model::Disc& ) ) );

    work.window = dlg;

    dlg->setWork( work );
}


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : UIMain.h
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#ifndef UIMAIN_H
#define UIMAIN_H

#include "ui_UIMain.h"

class QMenuBar;
class QFileSystemModel;
class QNetworkReply;
class pNetworkAccessManager;
class pPaypalButton;
class pUpdateChecker;

namespace QWBFS {
namespace Model {
    class DiscModel;
}; // Model
}; // QWBFS

class UIMain : public QMainWindow, public Ui::UIMain
{
    Q_OBJECT

public:
    UIMain( QWidget* parent = 0 );
    virtual ~UIMain();

    virtual bool event( QEvent* event );

    pNetworkAccessManager* cache() const;
    pQueuedMessageToolBar* messageToolBar() const;

protected:
#if defined( Q_OS_MAC )
    QMenuBar* mMenuBar;
#endif
    QMenu* mActions;
    pPaypalButton* mDonationWidget;
    QFileSystemModel* mFoldersModel;
    QFileSystemModel* mFilesModel;
    pNetworkAccessManager* mCache;
    QString mLastDiscId;
    pUpdateChecker* mUpdateChecker;

    virtual void showEvent( QShowEvent* event );
    virtual void closeEvent( QCloseEvent* event );
    virtual bool eventFilter( QObject* object, QEvent* event );

    void connectView( PartitionWidget* widget );

protected slots:
    void localeChanged();
    void loadProperties( bool firstInit = true );
    void saveProperties();
    void changeLocaleRequested();
    void propertiesChanged();
    void openViewRequested();
    void closeViewRequested();
    void coverRequested( const QString& id );
    void progress_jobFinished( const QWBFS::Model::Disc& disc );
    void networkAccessManager_finished( QNetworkReply* reply );
    void networkAccessManager_cached( const QUrl& url );
    void networkAccessManager_error( const QUrl& url, const QString& message );
    void networkAccessManager_cacheCleared();
    void on_aReloadPartitions_triggered();
    void on_aQuit_triggered();
    void on_aAbout_triggered();
    void on_aProperties_triggered();
    void on_aConvertToWBFSFiles_triggered();
    void on_aConvertToISOFiles_triggered();
    void on_aRenameDiscsInFolder_triggered();
    void on_tvFolders_activated( const QModelIndex& index );
    void on_tbReloadDrives_clicked();
    void on_cbDrives_currentIndexChanged( const QString& text );
    void on_tbClearExport_clicked();
    void on_tbRemoveExport_clicked();
    void on_tbExport_clicked();
};

#endif // UIMAIN_H

repo_name: CYBERDEViL/qwbfsmanager

license: unknown


code:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>UIMain</class>
 <widget class="QMainWindow" name="UIMain">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>900</width>
    <height>400</height>
   </rect>
  </property>
  <property name="iconSize">
   <size>
    <width>36</width>
    <height>36</height>
   </size>
  </property>
  <property name="toolButtonStyle">
   <enum>Qt::ToolButtonTextUnderIcon</enum>
  </property>
  <property name="dockNestingEnabled">
   <bool>true</bool>
  </property>
  <property name="unifiedTitleAndToolBarOnMac">
   <bool>true</bool>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="centralVerticalLayout">
    <item>
     <widget class="pQueuedMessageToolBar" name="qmtbInfos"/>
    </item>
    <item>
     <widget class="QSplitter" name="sViews">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
      <widget class="PartitionWidget" name="pwMainView" native="true"/>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="pDockWidget" name="dwTools">
   <property name="features">
    <set>QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetMovable</set>
   </property>
   <property name="allowedAreas">
    <set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
   </property>
   <property name="windowTitle">
    <string>Tools</string>
   </property>
   <attribute name="dockWidgetArea">
    <number>1</number>
   </attribute>
   <widget class="QWidget" name="dockWidgetContents">
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QTabWidget" name="twPages">
       <property name="currentIndex">
        <number>0</number>
       </property>
       <widget class="QWidget" name="wFS">
        <attribute name="icon">
         <iconset resource="../resources/resources.qrc">
          <normaloff>:/icons/256/tree.png</normaloff>:/icons/256/tree.png</iconset>
        </attribute>
        <attribute name="title">
         <string>File System</string>
        </attribute>
        <layout class="QGridLayout" name="gridLayout">
         <item row="0" column="0">
          <widget class="QComboBox" name="cbDrives"/>
         </item>
         <item row="0" column="1">
          <widget class="QToolButton" name="tbReloadDrives">
           <property name="toolTip">
            <string>Reload the mount points</string>
           </property>
           <property name="icon">
            <iconset resource="../resources/resources.qrc">
             <normaloff>:/icons/256/reload.png</normaloff>:/icons/256/reload.png</iconset>
           </property>
           <property name="iconSize">
            <size>
             <width>20</width>
             <height>20</height>
            </size>
           </property>
           <property name="autoRaise">
            <bool>true</bool>
           </property>
          </widget>
         </item>
         <item row="1" column="0" colspan="2">
          <widget class="QSplitter" name="splitter">
           <property name="orientation">
            <enum>Qt::Vertical</enum>
           </property>
           <widget class="QTreeView" name="tvFolders">
            <property name="editTriggers">
             <set>QAbstractItemView::NoEditTriggers</set>
            </property>
            <property name="uniformRowHeights">
             <bool>true</bool>
            </property>
            <property name="headerHidden">
             <bool>true</bool>
            </property>
           </widget>
           <widget class="QListView" name="lvFiles">
            <property name="editTriggers">
             <set>QAbstractItemView::NoEditTriggers</set>
            </property>
            <property name="dragEnabled">
             <bool>true</bool>
            </property>
            <property name="dragDropMode">
             <enum>QAbstractItemView::DragOnly</enum>
            </property>
            <property name="selectionMode">
             <enum>QAbstractItemView::ExtendedSelection</enum>
            </property>
            <property name="uniformItemSizes">
             <bool>true</bool>
            </property>
           </widget>
          </widget>
         </item>
        </layout>
       </widget>
       <widget class="QWidget" name="wExport">
        <attribute name="icon">
         <iconset resource="../resources/resources.qrc">
          <normaloff>:/icons/256/export.png</normaloff>:/icons/256/export.png</iconset>
        </attribute>
        <attribute name="title">
         <string>Export</string>
        </attribute>
        <layout class="QVBoxLayout" name="verticalLayout_3">
         <item>
          <layout class="QHBoxLayout" name="horizontalLayout_2">
           <item>
            <spacer name="horizontalSpacer">
             <property name="orientation">
              <enum>Qt::Horizontal</enum>
             </property>
             <property name="sizeHint" stdset="0">
              <size>
               <width>40</width>
               <height>20</height>
              </size>
             </property>
            </spacer>
           </item>
           <item>
            <widget class="QToolButton" name="tbClearExport">
             <property name="toolTip">
              <string>Clear the list</string>
             </property>
             <property name="icon">
              <iconset resource="../resources/resources.qrc">
               <normaloff>:/icons/256/clear.png</normaloff>:/icons/256/clear.png</iconset>
             </property>
             <property name="iconSize">
              <size>
               <width>20</width>
               <height>20</height>
              </size>
             </property>
             <property name="autoRaise">
              <bool>true</bool>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QToolButton" name="tbRemoveExport">
             <property name="toolTip">
              <string>Remove the selected items from the list</string>
             </property>
             <property name="icon">
              <iconset resource="../resources/resources.qrc">
               <normaloff>:/icons/256/remove.png</normaloff>:/icons/256/remove.png</iconset>
             </property>
             <property name="iconSize">
              <size>
               <width>20</width>
               <height>20</height>
              </size>
             </property>
             <property name="autoRaise">
              <bool>true</bool>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QToolButton" name="tbExport">
             <property name="toolTip">
              <string>Process the export list</string>
             </property>
             <property name="icon">
              <iconset resource="../resources/resources.qrc">
               <normaloff>:/icons/256/export.png</normaloff>:/icons/256/export.png</iconset>
             </property>
             <property name="iconSize">
              <size>
               <width>20</width>
               <height>20</height>
              </size>
             </property>
             <property name="autoRaise">
              <bool>true</bool>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item>
          <widget class="ListView" name="lvExport">
           <property name="editTriggers">
            <set>QAbstractItemView::NoEditTriggers</set>
           </property>
           <property name="showDropIndicator" stdset="0">
            <bool>false</bool>
           </property>
           <property name="dragDropMode">
            <enum>QAbstractItemView::DropOnly</enum>
           </property>
           <property name="defaultDropAction">
            <enum>Qt::CopyAction</enum>
           </property>
           <property name="selectionMode">
            <enum>QAbstractItemView::ExtendedSelection</enum>
           </property>
           <property name="verticalScrollMode">
            <enum>QAbstractItemView::ScrollPerPixel</enum>
           </property>
           <property name="horizontalScrollMode">
            <enum>QAbstractItemView::ScrollPerPixel</enum>
           </property>
           <property name="uniformItemSizes">
            <bool>true</bool>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <widget class="QToolBar" name="toolBar">
   <property name="windowTitle">
    <string>Main ToolBar</string>
   </property>
   <property name="movable">
    <bool>false</bool>
   </property>
   <property name="floatable">
    <bool>false</bool>
   </property>
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="aProperties"/>
   <addaction name="aReloadPartitions"/>
   <addaction name="aAbout"/>
   <addaction name="aQuit"/>
   <addaction name="separator"/>
  </widget>
  <widget class="pDockWidget" name="dwCovers">
   <property name="minimumSize">
    <size>
     <width>184</width>
     <height>192</height>
    </size>
   </property>
   <property name="maximumSize">
    <size>
     <width>184</width>
     <height>524287</height>
    </size>
   </property>
   <property name="features">
    <set>QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetMovable</set>
   </property>
   <property name="allowedAreas">
    <set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
   </property>
   <property name="windowTitle">
    <string>Covers</string>
   </property>
   <attribute name="dockWidgetArea">
    <number>2</number>
   </attribute>
   <widget class="QWidget" name="dockWidgetContents_2">
    <layout class="QVBoxLayout" name="verticalLayout_4">
     <item>
      <widget class="QLabel" name="lCDCover">
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
       <property name="openExternalLinks">
        <bool>true</bool>
       </property>
      </widget>
     </item>
     <item>
      <widget class="Line" name="line_2">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="lWiiTDB">
       <property name="minimumSize">
        <size>
         <width>0</width>
         <height>60</height>
        </size>
       </property>
       <property name="maximumSize">
        <size>
         <width>16777215</width>
         <height>60</height>
        </size>
       </property>
       <property name="cursor">
        <cursorShape>PointingHandCursor</cursorShape>
       </property>
       <property name="toolTip">
        <string notr="true">http://wiitdb.com</string>
       </property>
       <property name="styleSheet">
        <string notr="true">QLabel {
	background-image: url(:/wii/wiitdb.png);
	background-repeat: no-repeat;
	background-position:center bottom;
	font: bold 13px "Arial";
}</string>
       </property>
       <property name="text">
        <string>Covers By</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignHCenter|Qt::AlignTop</set>
       </property>
       <property name="wordWrap">
        <bool>true</bool>
       </property>
      </widget>
     </item>
     <item>
      <widget class="Line" name="line">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QLabel" name="lCover">
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
       <property name="openExternalLinks">
        <bool>true</bool>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <action name="aReloadPartitions">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/256/reload.png</normaloff>:/icons/256/reload.png</iconset>
   </property>
   <property name="text">
    <string>Reload</string>
   </property>
   <property name="toolTip">
    <string>Reload the partitions</string>
   </property>
  </action>
  <action name="aAbout">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/256/about.png</normaloff>:/icons/256/about.png</iconset>
   </property>
   <property name="text">
    <string>About...</string>
   </property>
   <property name="menuRole">
    <enum>QAction::AboutRole</enum>
   </property>
  </action>
  <action name="aQuit">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/256/quit.png</normaloff>:/icons/256/quit.png</iconset>
   </property>
   <property name="text">
    <string>Quit...</string>
   </property>
   <property name="menuRole">
    <enum>QAction::QuitRole</enum>
   </property>
  </action>
  <action name="aProperties">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/256/properties.png</normaloff>:/icons/256/properties.png</iconset>
   </property>
   <property name="text">
    <string>Properties</string>
   </property>
   <property name="menuRole">
    <enum>QAction::PreferencesRole</enum>
   </property>
  </action>
  <action name="aConvertToWBFSFiles">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/128/iso-to-wbfs.png</normaloff>:/icons/128/iso-to-wbfs.png</iconset>
   </property>
   <property name="text">
    <string>Convert ISO Files</string>
   </property>
  </action>
  <action name="aConvertToISOFiles">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/128/wbfs-to-iso.png</normaloff>:/icons/128/wbfs-to-iso.png</iconset>
   </property>
   <property name="text">
    <string>Convert WBFS Files</string>
   </property>
  </action>
  <action name="aRenameDiscsInFolder">
   <property name="icon">
    <iconset resource="../resources/resources.qrc">
     <normaloff>:/icons/256/read-partition.png</normaloff>:/icons/256/read-partition.png</iconset>
   </property>
   <property name="text">
    <string>Rename Discs in folder</string>
   </property>
  </action>
 </widget>
 <customwidgets>
  <customwidget>
   <class>ListView</class>
   <extends>QListView</extends>
   ListView.h
  </customwidget>
  <customwidget>
   <class>PartitionWidget</class>
   <extends>QWidget</extends>
   PartitionWidget.h
   <container>1</container>
  </customwidget>
  <customwidget>
   <class>pQueuedMessageToolBar</class>
   <extends>QToolBar</extends>
   FreshGui/pQueuedMessageToolBar
  </customwidget>
  <customwidget>
   <class>pDockWidget</class>
   <extends>QDockWidget</extends>
   FreshGui/pDockWidget
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources>
  <include location="../resources/resources.qrc"/>
 </resources>
 <connections/>
</ui>


code:
#include "Utils.h"

#include <QApplication>
#include <QStyleFactory>

QStyle* Utils::neutralStyle()
{
    const QStringList keys = QStyleFactory::keys();

    if ( keys.contains( QLatin1String( "plastique" ), Qt::CaseInsensitive ) ) {
        return QStyleFactory::create( QLatin1String( "plastique" ) );
    }
    else if ( keys.contains( QLatin1String( "fusion" ), Qt::CaseInsensitive ) ) {
        return QStyleFactory::create( QLatin1String( "fusion" ) );
    }

    // Just use native style as fallback
    return QApplication::style();
}


code:
#ifndef UTILS_H
#define UTILS_H

class QStyle;

namespace Utils
{
    QStyle* neutralStyle();
};

#endif // UTILS_H


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : WorkerThread.cpp
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#include "WorkerThread.h"

#include <FreshCore/pCoreUtils>

#include <QTime>
#include <QWidget>
#include <QDir>
#include <QMetaType>
#include <QDebug>

WorkerThread::WorkerThread( QObject* parent )
    : QThread( parent )
{
    qRegisterMetaType<QWBFS::Model::Disc>( "QWBFS::Model::Disc" );
}

WorkerThread::~WorkerThread()
{
    if ( isRunning() ) {
        qWarning() << "Waiting thread to finish...";
        stop();
        wait();
    }

    //qWarning() << Q_FUNC_INFO;
}

WorkerThread::Task WorkerThread::task() const
{
    QMutexLocker locker( &const_cast<WorkerThread*>( this )->mMutex );
    return mWork.task;
}

bool WorkerThread::setWork( const WorkerThread::Work& work )
{
    if ( isRunning() ) {
        Q_ASSERT( 0 );
        return false;
    }

    mWork = work;
    mWork.window->setWindowTitle( taskToWindowTitle( mWork.task ) );

    start();

    return true;
}

QString WorkerThread::taskToWindowTitle( WorkerThread::Task task, bool indirect )
{
    return taskToLabel( task, indirect ).append( "..." );
}

QString WorkerThread::taskToLabel( WorkerThread::Task task, bool indirect )
{
    switch ( task ) {
        case WorkerThread::ExportISO:
            return indirect ? tr( "Indirect Export to ISO" ) : tr( "Export to ISO" );
        case WorkerThread::ExportWBFS:
            return indirect ? tr( "Indirect Export to WBFS" ) : tr( "Export to WBFS" );
        case WorkerThread::ImportISO:
            return indirect ? tr( "Indirect Import to ISO" ) : tr( "Import to ISO" );
        case WorkerThread::ImportWBFS:
            return indirect ? tr( "Indirect Import to WBFS" ) : tr( "Import to WBFS" );
        case WorkerThread::ConvertISO:
            return indirect ? tr( "Indirect Convert to ISO" ) : tr( "Convert to ISO" );
        case WorkerThread::ConvertWBFS:
            return indirect ? tr( "Indirect Convert to WBFS" ) : tr( "Convert to WBFS" );
        case WorkerThread::RenameAll:
            return tr( "Rename Disc" );
    }

    return QString::null;
}

void WorkerThread::stop()
{
    QMutexLocker locker( &mMutex );
    mStop = true;
    emit canceled();
}

void WorkerThread::run()
{
    WorkerThread::Work work;
    int count = 0;
    int id = 0;

    {
        QMutexLocker locker( &mMutex );
        mStop = false;
        work = mWork;
    }

    emit globalProgressChanged( id, count );

    if ( work.task == WorkerThread::RenameAll ) {
        QDir dir( work.target );
        QStringList filters;

        dir.setFilter( QDir::Files );

        if ( work.task & WorkerThread::WBFS ) {
            filters << "*.wbfs";
        }

        if ( work.task & WorkerThread::ISO ) {
            filters << "*.iso";
        }

        foreach ( const QString& filePath, pCoreUtils::findFiles( dir, filters, true ) ) {
            work.discs << QWBFS::Model::Disc( filePath );
        }
    }

    count = work.discs.count();

    emit globalProgressChanged( id, count );

    foreach ( QWBFS::Model::Disc disc, work.discs ) {
        switch ( work.task ) {
            case WorkerThread::RenameAll:
                renameDisc( work.task, disc, work.target, work.pattern, work.invalidChars );
                break;
            case WorkerThread::ExportISO:
            case WorkerThread::ExportWBFS:
            case WorkerThread::ImportISO:
            case WorkerThread::ImportWBFS:
            case WorkerThread::ConvertISO:
            case WorkerThread::ConvertWBFS: {
                switch ( QWBFS::Driver::fileType( disc.origin ) ) {
                    case QWBFS::Driver::WBFSFile:
                    case QWBFS::Driver::WBFSPartitionFile: {
                        switch ( QWBFS::Driver::fileType( work.target ) ) {
                            case QWBFS::Driver::WBFSPartitionFile: {
                                wbfsToWBFS( work.task, disc, work.target, false, work.invalidChars );
                                break;
                            }
                            case QWBFS::Driver::WBFSFile:
                            case QWBFS::Driver::ISOFile:
                            case QWBFS::Driver::UnknownFile: {
                                if ( work.task & WorkerThread::WBFS ) {
                                    wbfsToWBFS( work.task, disc, work.target, true, work.invalidChars );
                                }
                                else if ( work.task & WorkerThread::ISO ) {
                                    wbfsToISO( work.task, disc, work.target, work.invalidChars );
                                }
                                else {
                                    if ( work.task & WorkerThread::Import ) {
                                        disc.error = QWBFS::Driver::DiscAddFailed;
                                    }
                                    else if ( work.task & WorkerThread::Export ) {
                                        disc.error = QWBFS::Driver::DiscExtractFailed;
                                    }
                                    else if ( work.task & WorkerThread::Convert ) {
                                        disc.error = QWBFS::Driver::DiscConvertFailed;
                                    }
                                    else {
                                        disc.error = QWBFS::Driver::UnknownError;
                                    }
                                }

                                break;
                            }
                        }

                        break;
                    }
                    case QWBFS::Driver::ISOFile: {
                        switch ( QWBFS::Driver::fileType( work.target ) ) {
                            case QWBFS::Driver::WBFSPartitionFile: {
                                isoToWBFS( work.task, disc, work.target, false, work.invalidChars );
                                break;
                            }
                            case QWBFS::Driver::WBFSFile:
                            case QWBFS::Driver::ISOFile:
                            case QWBFS::Driver::UnknownFile: {
                                if ( work.task & WorkerThread::WBFS ) {
                                    isoToWBFS( work.task, disc, work.target, true, work.invalidChars );
                                }
                                else if ( work.task & WorkerThread::ISO ) {
                                    isoToISO( work.task, disc, work.target, work.invalidChars );
                                }
                                else {
                                    if ( work.task & WorkerThread::Import ) {
                                        disc.error = QWBFS::Driver::DiscAddFailed;
                                    }
                                    else if ( work.task & WorkerThread::Export ) {
                                        disc.error = QWBFS::Driver::DiscExtractFailed;
                                    }
                                    else if ( work.task & WorkerThread::Convert ) {
                                        disc.error = QWBFS::Driver::DiscConvertFailed;
                                    }
                                    else {
                                        disc.error = QWBFS::Driver::UnknownError;
                                    }
                                }

                                break;
                            }
                        }

                        break;
                    }
                    case QWBFS::Driver::UnknownFile:
                        disc.error = QWBFS::Driver::UnknownError;
                        break;
                }
            }
        }

        disc.state = disc.error == QWBFS::Driver::Ok ? QWBFS::Driver::Success : QWBFS::Driver::Failed;

        emit globalProgressChanged( ++id, count );
        emit jobFinished( disc );

        {
            QMutexLocker locker( &mMutex );

            if ( mStop ) {
                break;
            }
        }
    }

    emit globalProgressChanged( count, count );
}

void WorkerThread::connectDriver( QWBFS::Driver* driver )
{
    connect( driver, SIGNAL( currentProgressChanged( int, int, const QTime& ) ), this, SIGNAL( currentProgressChanged( int, int, const QTime& ) ) );
    connect( driver, SIGNAL( globalProgressChanged( int, int ) ), this, SIGNAL( globalProgressChanged( int, int ) ) );
}

void WorkerThread::renameDisc( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& target, const QString& pattern, const QString& invalidChars )
{
    if ( !source.isValid() ) {
        source.error = QWBFS::Driver::InvalidDisc;
        return;
    }

    /*
        %title = Game Title
        %id = Game ID
        %suffix = File Suffix
    */
    QString filePath = QString( "%1/%2" )
        .arg( target )
        .arg( pattern )
        .replace( "%title", QWBFS::Model::Disc::cleanupGameTitle( source.title, invalidChars ), Qt::CaseInsensitive )
        .replace( "%id", source.id.toUpper(), Qt::CaseInsensitive )
        .replace( "%suffix", QFileInfo( source.origin ).suffix(), Qt::CaseInsensitive )
        ;

    emit message( QString( "%1 '%2'..." ).arg( taskToLabel( task ) ).arg( source.baseName( invalidChars ) ) );
    emit currentProgressChanged( 0, 1, QTime( 0, 0, 0 ) );

    if ( source.origin != filePath ) {
        source.error = QDir( target ).mkpath( QFileInfo( filePath ).absolutePath() ) ? QWBFS::Driver::Ok : QWBFS::Driver::UnknownError;

        if ( !source.hasError() ) {
            const bool exists = QFile::exists( filePath );

            if ( exists ) {
                const QFileInfo file( filePath );
                const QString path = file.absolutePath();
                const QString fileName = file.fileName();
                filePath = QString( "%1/Existing/%2.%3" )
                    .arg( path )
                    .arg( fileName )
                    .arg( QDateTime::currentDateTime().toString( "yyyy-MM-dd hh'h'mm" ) );

                QDir( path ).mkpath( "Existing" );
            }

            source.error = QFile::rename( source.origin, filePath ) ? QWBFS::Driver::Ok : QWBFS::Driver::DiscRenameFailed;

            if ( exists ) {
                source.error = QWBFS::Driver::DiscFound;
            }

            if ( !source.hasError() ) {
                const QString sourcePath = QFileInfo( source.origin ).absolutePath();

                if ( pCoreUtils::isEmptyDirectory( sourcePath ) ) {
                    QDir( sourcePath ).rmdir( sourcePath );
                }
            }
        }
    }
    else {
        source.error = QWBFS::Driver::Ok;
    }

    emit currentProgressChanged( 1, 1, QTime( 0, 0, 0 ) );
}

void WorkerThread::isoToWBFS( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& _target, bool trimWBFS, const QString& invalidChars )
{
    if ( !source.isValid() ) {
        source.error = QWBFS::Driver::InvalidDisc;
        return;
    }

    const QFileInfo file( _target );
    QString target = _target;
    bool created = false;
    QWBFS::Partition::Handle handle;

    if ( trimWBFS && file.isDir() ) {
        target = QDir::cleanPath( target.append( QString( "/%1.wbfs" ).arg( source.baseName( invalidChars ) ) ) );
    }

    if ( trimWBFS ) {

        if ( QFile::exists( target ) ) {
            source.error = QWBFS::Driver::DiscFound;
            return;
        }

        emit message( tr( "Initializing WBFS disc '%1'..." ).arg( source.baseName( invalidChars ) ) );
        source.error = QWBFS::Driver::allocateFile( target );

        if ( source.hasError() ) {
            QFile::remove( target );
            return;
        }

        QWBFS::Partition::Properties properties( target );
        properties.reset = true;

        emit message( tr( "Formating WBFS disc '%1'..." ).arg( source.baseName( invalidChars ) ) );

        handle = QWBFS::Partition::Handle( properties );
    }
    else {
        handle = QWBFS::Driver::getHandle( target, &created );
    }

    if ( !handle.isValid() ) {
        if ( created ) {
            QWBFS::Driver::closeHandle( handle );
        }

        if ( trimWBFS ) {
            QFile::remove( target );
        }

        source.error = QWBFS::Driver::PartitionNotOpened;
        return;
    }

    QWBFS::Driver driver( 0, handle );
    connectDriver( &driver );

    emit message( QString( "%1 '%2'..." ).arg( taskToLabel( task ) ).arg( source.baseName( invalidChars ) ) );
    source.error = driver.addDiscImage( source.origin );

    if ( source.hasError() ) {
        if ( created ) {
            QWBFS::Driver::closeHandle( handle );
        }

        if ( trimWBFS ) {
            QFile::remove( target );
        }

        return;
    }

    if ( trimWBFS ) {
        source.error = driver.trim();
    }

    if ( created ) {
        QWBFS::Driver::closeHandle( handle );
    }
}

void WorkerThread::wbfsToISO( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& _target, const QString& invalidChars )
{
    if ( !source.isValid() ) {
        source.error = QWBFS::Driver::InvalidDisc;
        return;
    }

    QFileInfo file( _target );
    QString target = _target;

    if ( file.isDir() ) {
        target = QDir::cleanPath( target.append( QString( "/%1.iso" ).arg( source.baseName( invalidChars ) ) ) );
    }

    if ( QFile::exists( target ) ) {
        source.error = QWBFS::Driver::DiscFound;
        return;
    }

    file.setFile( target );

    bool created = false;
    QWBFS::Partition::Handle handle = QWBFS::Driver::getHandle( source.origin, &created );

    // check handle validity
    if ( !handle.isValid() ) {
        if ( created ) {
            QWBFS::Driver::closeHandle( handle );
        }

        source.error = QWBFS::Driver::PartitionNotOpened;
        return;
    }

    QWBFS::Driver driver( 0, handle );
    connectDriver( &driver );

    emit message( QString( "%1 '%2'..." ).arg( taskToLabel( task ) ).arg( source.baseName( invalidChars ) ) );
    source.error = driver.extractDisc( source.id, file.absolutePath(), file.fileName() );

    if ( source.hasError() ) {
        QFile::remove( target );
    }

    if ( created ) {
        QWBFS::Driver::closeHandle( handle );
    }
}

void WorkerThread::isoToISO( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& _target, const QString& invalidChars )
{
    if ( !source.isValid() ) {
        source.error = QWBFS::Driver::InvalidDisc;
        return;
    }

    const QFileInfo file( _target );
    QString target = _target;

    if ( file.isDir() ) {
        target = QDir::cleanPath( target.append( QString( "/%1.iso" ).arg( source.baseName( invalidChars ) ) ) );
    }

    if ( QFile::exists( target ) ) {
        source.error = QWBFS::Driver::DiscFound;
        return;
    }

    emit message( QString( "%1 '%2'..." ).arg( taskToLabel( task ) ).arg( source.baseName( invalidChars ) ) );

    // copying the file chunk by chunk instead of using QFile::copy() to be able to see progression
    QFile in( source.origin );
    QFile out( target );

    if ( !in.open( QIODevice::ReadOnly ) ) {
        source.error = QWBFS::Driver::DiscReadFailed;
        return;
    }

    if ( !out.open( QIODevice::WriteOnly ) ) {
        source.error = QWBFS::Driver::DiscWriteFailed;
        return;
    }

    const uint bufferSize = 1024 *1024 *5; // 5 MB buffer size
    char buffer[ bufferSize ];
    int totalRead = 0;

    QTime estimatedTime = QWBFS::Driver::estimatedTimeForTask( totalRead, in.size() );
    emit currentProgressChanged( totalRead, in.size(), estimatedTime );

    while ( !in.atEnd() ) {
        const qint64 read = in.read( buffer, bufferSize );

        if ( read == -1 ) {
            out.close();
            out.remove();

            QFile::remove( target );
            source.error = QWBFS::Driver::DiscReadFailed;
            return;
        }

        const qint64 write = out.write( buffer, read );

        if ( write == -1 ) {
            out.close();
            out.remove();

            QFile::remove( target );
            source.error = QWBFS::Driver::DiscWriteFailed;
            return;
        }

        totalRead += read;

        estimatedTime = QWBFS::Driver::estimatedTimeForTask( totalRead, in.size() );
        emit currentProgressChanged( totalRead, in.size(), estimatedTime );
    }

    in.close();
    out.close();
}

void WorkerThread::wbfsToWBFS( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& _target, bool trimWBFS, const QString& invalidChars )
{
    if ( !source.isValid() ) {
        source.error = QWBFS::Driver::InvalidDisc;
        return;
    }

    const QFileInfo file( _target );
    QString target = _target;
    bool sourceCreated = false;
    QWBFS::Partition::Handle sourceHandle = QWBFS::Driver::getHandle( source.origin, &sourceCreated );
    bool targetCreated = false;
    QWBFS::Partition::Handle targetHandle;

    if ( !sourceHandle.isValid() ) {
        if ( sourceCreated ) {
            QWBFS::Driver::closeHandle( sourceHandle );
        }

        source.error = QWBFS::Driver::PartitionNotOpened;
        return;
    }

    if ( trimWBFS && file.isDir() ) {
        target = QDir::cleanPath( target.append( QString( "/%1.wbfs" ).arg( source.baseName( invalidChars ) ) ) );
    }

    if ( trimWBFS ) {

        if ( QFile::exists( target ) ) {
            if ( sourceCreated ) {
                QWBFS::Driver::closeHandle( sourceHandle );
            }

            source.error = QWBFS::Driver::DiscFound;
            return;
        }

        emit message( tr( "Initializing WBFS disc '%1'..." ).arg( source.baseName( invalidChars ) ) );
        source.error = QWBFS::Driver::allocateFile( target );

        if ( source.hasError() ) {
            if ( sourceCreated ) {
                QWBFS::Driver::closeHandle( sourceHandle );
            }

            QFile::remove( target );
            return;
        }

        QWBFS::Partition::Properties properties( target );
        properties.reset = true;

        emit message( tr( "Formating WBFS disc '%1'..." ).arg( source.baseName( invalidChars ) ) );

        targetHandle = QWBFS::Partition::Handle( properties );
    }
    else {
        targetHandle = QWBFS::Driver::getHandle( target, &targetCreated );
    }

    if ( !targetHandle.isValid() ) {
        if ( sourceCreated ) {
            QWBFS::Driver::closeHandle( sourceHandle );
        }

        if ( targetCreated ) {
            QWBFS::Driver::closeHandle( targetHandle );
        }

        if ( trimWBFS ) {
            QFile::remove( target );
        }

        source.error = QWBFS::Driver::PartitionNotOpened;
        return;
    }

    QWBFS::Driver targetDriver( 0, targetHandle );
    connectDriver( &targetDriver );

    // direct drive2drive
    if ( targetDriver.canDrive2Drive( sourceHandle ) == QWBFS::Driver::Ok ) {
        emit message( QString( "%1 '%2'..." ).arg( taskToLabel( task ) ).arg( source.baseName( invalidChars ) ) );

        source.error = targetDriver.addDisc( source.id, sourceHandle );
    }
    // indirect drive2drive
    else {
        emit message( QString( "%1 '%2'..." ).arg( taskToLabel( task, true ) ).arg( source.baseName( invalidChars ) ) );

        const QFileInfo tmpFile( QString( "%1/%2.iso" ).arg( QDir::tempPath() ).arg( source.baseName( invalidChars ) ) );
        QWBFS::Driver sourceDriver( 0, sourceHandle );
        connectDriver( &sourceDriver );

        if ( targetDriver.hasDisc( source.id ) == QWBFS::Driver::DiscNotFound ) {
            source.error = sourceDriver.extractDisc( source.id, tmpFile.absolutePath(), tmpFile.fileName() );

            if ( !source.hasError() ) {
                source.error = targetDriver.addDiscImage( tmpFile.absoluteFilePath() );
            }

            QFile::remove( tmpFile.absoluteFilePath() );
        }
        else {
            source.error = QWBFS::Driver::DiscFound;
        }
    }

    if ( !source.hasError() && trimWBFS ) {
        source.error = targetDriver.trim();
    }

    if ( sourceCreated ) {
        QWBFS::Driver::closeHandle( sourceHandle );
    }

    if ( targetCreated ) {
        QWBFS::Driver::closeHandle( targetHandle );
    }

    if ( source.hasError() && trimWBFS ) {
        QFile::remove( target );
    }
}


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : WorkerThread.h
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#ifndef WORKERTHREAD_H
#define WORKERTHREAD_H

#include <QThread>
#include <QMutex>
#include <QTime>

#include "models/Disc.h"
#include "qwbfsdriver/PartitionHandle.h"
#include "qwbfsdriver/Driver.h"

class QWidget;

class WorkerThread : public QThread
{
    Q_OBJECT

    enum BasicTask {
        Export = 0x1,
        Import = 0x2,
        Convert = 0x4,
        Rename = 0x8,
        ISO = 0x1000,
        WBFS = 0x2000,
        Indirect = 0x4000
    };

public:
    enum Task {
        ExportISO = Export | ISO,
        ExportWBFS = Export | WBFS,
        ImportISO = Import | ISO,
        ImportWBFS = Import | WBFS,
        ConvertISO = Convert | ISO,
        ConvertWBFS = Convert | WBFS,
        RenameAll = Rename | WBFS | ISO
    };

    struct Work
    {
        Work()
        {
            invalidChars = "/\\:|<>?*\"'";
        }

        WorkerThread::Task task;
        QWBFS::Model::DiscList discs;
        QString target;
        QString pattern;
        QString invalidChars;
        QWidget* window;
    };

    WorkerThread( QObject* parent = 0 );
    virtual ~WorkerThread();

    WorkerThread::Task task() const;

    bool setWork( const WorkerThread::Work& work );

    static QString taskToWindowTitle( WorkerThread::Task task, bool indirect = false );
    static QString taskToLabel( WorkerThread::Task task, bool indirect = false );

public slots:
    void stop();

protected:
    QMutex mMutex;
    bool mStop;
    WorkerThread::Work mWork;

    virtual void run();

    void connectDriver( QWBFS::Driver* driver );
    void renameDisc( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& target, const QString& pattern, const QString& invalidChars );
    void isoToWBFS( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& target, bool trimWBFS, const QString& invalidChars );
    void wbfsToISO( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& target, const QString& invalidChars );
    void isoToISO( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& target, const QString& invalidChars );
    void wbfsToWBFS( WorkerThread::Task task, QWBFS::Model::Disc& source, const QString& target, bool trimWBFS, const QString& invalidChars );

signals:
    void currentProgressChanged( int value, int maximum, const QTime& remaining );
    void globalProgressChanged( int value, int maximum );
    void jobFinished( const QWBFS::Model::Disc& disc );
    void message( const QString& text );
    void log( const QString& text );
    void canceled();
};

#endif // WORKERTHREAD_H


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : main.cpp
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#include <QApplication>
#include <QProxyStyle>
#include <QSplashScreen>
#include <QPointer>
#include <QDateTime>
#include <QTimer>
#include <QPixmapCache>
#include <QDebug>

#include <FreshCore/pSettings>
#include <FreshCore/pNetworkAccessManager>
#include <FreshCore/pTranslationManager>
#include <FreshGui/pIconManager>

#include "main.h"
#include "UIMain.h"

#define SPLASHSCREEN_TIMEOUT 3000

class IconSizeProxyStyle : public QProxyStyle
{
    Q_OBJECT

public:
    // Fix boggued icon size on mac os x / Qt 4.8.5 Cocoa / MacPort
    virtual int pixelMetric( QStyle::PixelMetric metric, const QStyleOption* option = 0, const QWidget* widget = 0 ) const {
        switch ( metric ) {
            case QStyle::PM_ToolBarIconSize: // 64
                return 36;

            case QStyle::PM_SmallIconSize: // 32
                return 16;

            case QStyle::PM_LargeIconSize: // 64
                break;

            case QStyle::PM_IconViewIconSize: // 64
                return 32;

            case QStyle::PM_ListViewIconSize: // 32 - Use QStyle::PM_SmallIconSize
                break;

            case QStyle::PM_TabBarIconSize: // 32 - Use QStyle::PM_SmallIconSize
                break;

            case QStyle::PM_ButtonIconSize: // 32
                return pixelMetric( QStyle::PM_SmallIconSize, option, widget );

            default:
                break;
        }

        return QProxyStyle::pixelMetric( metric, option, widget );
    }
};

class SplashScreen : public QSplashScreen
{
    Q_OBJECT

public:
    SplashScreen( const QPixmap& pixmap )
        : QSplashScreen( pixmap )
    {
        QFont font = this->font();
        font.setPixelSize( 9 );
        setFont( font );
        showMessage( tr( "Version %1" ).arg( APPLICATION_VERSION_STR ), Qt::AlignRight | Qt::AlignBottom, QColor( 0, 0, 0 ) );

        show();
        raise();
    }

    void handle( QWidget* widget )
    {
        mWidget = widget;
        QTimer::singleShot( SPLASHSCREEN_TIMEOUT, this, SLOT( close() ) );
    }

protected:
    QPointer<QWidget> mWidget;

    virtual void hideEvent( QHideEvent* event )
    {
        QSplashScreen::hideEvent( event );

        if ( mWidget && !mWidget->isVisible() )
        {
            mWidget->show();
            mWidget->raise();
        }
    }
};

class Application : public QApplication
{
    Q_OBJECT

public:
    Application( int& argc, char** argv )
        : QApplication( argc, argv )
    {}

    virtual bool notify( QObject* receiver, QEvent* e ) {
        try {
            return QApplication::notify( receiver, e );
        }
        catch ( ... ) {
            qWarning( "%s: Try/Catch", Q_FUNC_INFO );
            qWarning() << receiver << e << e->type();
        }

        return false;
    }
};

int main( int argc, char** argv )
{
    Application app( argc, argv );
#if defined( Q_OS_MACX )
    app.setStyle( new IconSizeProxyStyle );
#endif
    app.setApplicationName( APPLICATION_NAME );
    app.setOrganizationName( APPLICATION_ORGANIZATION );
    app.setOrganizationDomain( APPLICATION_DOMAIN );
    app.setWindowIcon( QIcon( ":/icons/qwbfsmanager.png" ) );

    qsrand( QDateTime( QDate( 0, 0, 0 ) ).secsTo( QDateTime::currentDateTime() ) );
    QPixmapCache::setCacheLimit( QPixmapCache::cacheLimit() *4 );
    pNetworkAccessManager::instance()->setCacheDirectory( QDir::tempPath().append( QString( "/%1-%2-%3" ).arg( APPLICATION_NAME ).arg( APPLICATION_VERSION ).arg( QT_VERSION_STR ) ) );

    Q_INIT_RESOURCE( fresh );
    Q_UNUSED( QT_TRANSLATE_NOOP( "QObject", "The Free, Fast and Powerful cross platform Wii Backup File System manager" ) );

    pSettings::setDefaultProperties( pSettings::Properties( APPLICATION_NAME, APPLICATION_VERSION, pSettings::Auto ) );

    pTranslationManager* translationManager = pTranslationManager::instance();
    translationManager->setFakeCLocaleEnabled( true );
    translationManager->addTranslationsMask( "qt*.qm" );
    translationManager->addTranslationsMask( "fresh*.qm" );
    translationManager->addTranslationsMask( "qwbfsmanager*.qm" );
    translationManager->addForbiddenTranslationsMask( "qt_help*.qm" );

    QObject::connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );

    SplashScreen splash( pIconManager::pixmap( "splashscreen.png", ":/icons" ) );
    UIMain w;

    splash.handle( &w );
    return app.exec();
}

#include "main.moc"


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : main.h
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#ifndef MAIN_H
#define MAIN_H

#define APPLICATION_NAME _APPLICATION_NAME
#define APPLICATION_VERSION _APPLICATION_VERSION
#define APPLICATION_VERSION_STR _APPLICATION_VERSION_STR
#define APPLICATION_COPYRIGHTS _APPLICATION_COPYRIGHTS
#define APPLICATION_DESCRIPTION _APPLICATION_DESCRIPTION
#define APPLICATION_DOMAIN _APPLICATION_DOMAIN
#define APPLICATION_ORGANIZATION _APPLICATION_ORGANIZATION
#define APPLICATION_DOWNLOADS_FEED _APPLICATION_DOWNLOADS_FEED
#define APPLICATION_REPORT_BUG_URL _APPLICATION_REPORT_BUG_URL
#define APPLICATION_DISCUSS_URL _APPLICATION_DISCUSS_URL

#endif // MAIN_H


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : Disc.cpp
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#include "Disc.h"
#include "qwbfsdriver/Driver.h"

#include <FreshCore/pCoreUtils>

#include <QFileInfo>

#define WBFS_DISC_XML_NAME "WBFS-Discs"

using namespace QWBFS::Model;

Disc::Disc( const QDomElement& element )
{
    readFromElement( element );
}

Disc::Disc( const QString& filePath )
{
    readFromElement( QDomElement() );

    switch ( QWBFS::Driver::fileType( filePath ) ) {
        case QWBFS::Driver::WBFSFile:
            QWBFS::Driver::wbfsFileInfo( filePath, *this );
            break;
        case QWBFS::Driver::ISOFile:
            operator=( Driver::isoDiscInfo( filePath ) );
            break;
        case QWBFS::Driver::WBFSPartitionFile:
        case QWBFS::Driver::UnknownFile:
            Q_ASSERT( 0 );
            break;
    }
}

bool Disc::operator==( const Disc& other ) const
{
    return id == other.id &&
        title == other.title &&
        size == other.size &&
        origin == other.origin &&
        region == other.region /*&&
        state == other.state &&
        error == other.error*/;
}

bool Disc::isValid() const
{
    return !id.isEmpty() && !title.isEmpty();
}

bool Disc::hasError() const
{
    return error != QWBFS::Driver::Ok;
}

QString Disc::baseName( const QString& invalidChars ) const
{
    return isValid() ? QString( "%1 [%2]" ).arg( cleanupGameTitle( title, invalidChars ) ).arg( id ) : QString::null;
}

void Disc::addToDocument( QDomDocument& document ) const
{
    QDomElement element = document.createElement( "disc" );
    element.setAttribute( "id", id );
    element.setAttribute( "title", title );
    element.setAttribute( "size", size );
    element.setAttribute( "origin", origin );
    element.setAttribute( "region", region );
    element.setAttribute( "state", state );
    element.setAttribute( "error", error );
    document.documentElement().appendChild( element );
}

void Disc::readFromElement( const QDomElement& element )
{
    id = element.attribute( "id", QString::null );
    title = element.attribute( "title", QString::null );
    size = element.attribute( "size", QString::number( 0 ) ).toUInt();
    origin = element.attribute( "origin", QString::null );
    region = element.attribute( "region", 0 ).toInt();
    state = element.attribute( "state", QString::number( QWBFS::Driver::None ) ).toInt();
    error = element.attribute( "error", QString::number( QWBFS::Driver::Ok ) ).toInt();
}

QString Disc::cleanupGameTitle( const QString& _title, const QString& invalidChars )
{
    QString title = pCoreUtils::toTitleCase( _title );

    foreach ( const QChar& c, invalidChars ) {
        QString r;

        /*switch ( c.toAscii() ) {
            case '\'':
                r = " ";
                break;
            case ':':
                r = "-";
        }*/

        title.replace( c, r );
    }

    return title;
}

QDomDocument Disc::toDocument( const DiscList& discs )
{
    QDomDocument document( WBFS_DISC_XML_NAME );
    document.appendChild( document.createElement( "discs" ) );

    foreach ( const Disc& disc, discs ) {
        disc.addToDocument( document );
    }

    return document;
}

DiscList Disc::fromDocument( const QDomDocument& document )
{
    DiscList discs;

    const QDomNodeList nodes = document.documentElement().childNodes();

    for ( int i = 0; i < nodes.count(); i++ ) {
        discs << Disc( nodes.at( i ).toElement() );
    }

    return discs;
}

QByteArray Disc::toByteArray( const DiscList& discs )
{
    return toDocument( discs ).toString().toUtf8();
}

DiscList Disc::fromByteArray( const QByteArray& data )
{
    QDomDocument document( WBFS_DISC_XML_NAME );
    document.setContent( data );
    return fromDocument( document );
}


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : Disc.h
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#ifndef DISC_H
#define DISC_H

#include <QList>
#include <QDomDocument>
#include <QHash>

namespace QWBFS {
namespace Model {

typedef QList<struct Disc> DiscList;

struct Disc
{
    Disc( const QDomElement& element = QDomElement() );
    Disc( const QString& filePath );

    bool operator==( const Disc& other ) const;

    bool isValid() const;
    bool hasError() const;
    QString baseName( const QString& invalidChars = QString::null ) const;

    void addToDocument( QDomDocument& document ) const;
    void readFromElement( const QDomElement& element );

    static QString cleanupGameTitle( const QString& title, const QString& invalidChars );

    static QDomDocument toDocument( const DiscList& discs );
    static DiscList fromDocument( const QDomDocument& document );

    static QByteArray toByteArray( const DiscList& discs );
    static DiscList fromByteArray( const QByteArray& data );

    QString id;
    QString title;
    quint32 size;
    QString origin;
    int region;
    int state;
    int error;
};

inline uint qHash( const Disc& disc )
{
    return qHash( QString( "%1 - %2" ).arg( disc.id ).arg( disc.origin ) );
}

}; // Model
}; // QWBFS

#endif // DISC_H


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : DiscDelegate.cpp
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#include "DiscDelegate.h"
#include "DiscModel.h"
#include "Gauge.h"
#include "qwbfsdriver/Driver.h"
#include "wiitdb/Covers.h"
#include "ListView.h"

#include <FreshCore/pNetworkAccessManager>
#include <FreshGui/pIconManager>
#include <FreshCore/pCoreUtils>

#include <QPainter>
#include <QDebug>

using namespace QWBFS::Model;

DiscDelegate::DiscDelegate( QWBFS::Model::DiscModel* parent, pNetworkAccessManager* cache )
    : QStyledItemDelegate( parent )
{
    Q_ASSERT( parent );
    Q_ASSERT( cache );
    mModel = parent;
    mCache = cache;
}

DiscDelegate::~DiscDelegate()
{
}

void DiscDelegate::paint( QPainter* painter, const QStyleOptionViewItem& _option, const QModelIndex& index ) const
{
    // remove ugly focus rect
    QStyleOptionViewItem option = _option;
    option.state &= ~QStyle::State_HasFocus;

    if ( mModel ) {
        switch ( mModel->view()->viewMode() ) {
            case QListView::ListMode: {
                paintList( painter, option, index );
                break;
            }
            case QListView::IconMode: {
                paintIcon( painter, option, index );
                break;
            }
        }
    }
}

QSize DiscDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    if ( mModel ) {
        switch ( mModel->view()->viewMode() ) {
            case QListView::ListMode: {
                return mModel->data( index, DiscModel::ListModeSizeHintRole ).toSize();
            }
            case QListView::IconMode: {
                return mModel->data( index, DiscModel::IconModeSizeHintRole ).toSize();
            }
        }
    }

    return QStyledItemDelegate::sizeHint( option, index );
}

void DiscDelegate::paintFrame( QPainter* painter, const QStyleOptionViewItemV4& option, bool pair ) const
{
    const int corner = 5;
    const QRect r = option.rect.adjusted( 0, 0, -1, -1 );
    const QPalette::ColorRole role = pair ? QPalette::Highlight : QPalette::Button;
    QColor strokeColor = option.palette.color( role ).darker();
    QColor fillColor1 = option.palette.color( role ).lighter();
    QColor fillColor2 = option.palette.color( role );

    if ( option.state & QStyle::State_MouseOver ) {
        const int factor = 110;
        strokeColor = strokeColor.darker( factor );
        fillColor1 = fillColor1.darker( factor );
        fillColor2 = fillColor2.darker( factor );
    }

    QLinearGradient gradient( option.rect.topLeft(), option.rect.bottomLeft() );
    gradient.setColorAt( 0, fillColor1 );
    gradient.setColorAt( 1, fillColor2 );

    painter->setPen( strokeColor );
    painter->setBrush( gradient );
    painter->drawRoundedRect( r, corner, corner );
}

void DiscDelegate::paintList( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const
{
    painter->setRenderHint( QPainter::Antialiasing );

    const bool selected = option.state & QStyle::State_Selected;
    const QWBFS::Model::Disc disc = mModel->disc( index );
    QRect rect;

    // background / selection
    {
        QStyleOptionViewItemV4 o = option;
        o.rect = option.rect.adjusted( 1, 1, 0, 0 );

        paintFrame( painter, o, selected );
    }

    // icon
    {
        rect = option.rect;
        rect = option.rect.adjusted( 8, 5, -rect.width() +40 -5, -5 );
        QPixmap pixmap = disc.state == QWBFS::Driver::None ? mModel->coverPixmap( disc.id, rect.size() ) : mModel->statePixmap( disc.state, rect.size() );

        if ( !pixmap.isNull() ) {
            painter->drawPixmap( rect.topLeft(), pixmap );
        }
    }

    // title/region
    {
        QFont font = painter->font();
        font.setPixelSize( 13 );
        font.setBold( true );

        QFontMetrics metrics( font );
        rect = option.rect.adjusted( 40, 2, -10, -( metrics.height() -2 ) );

        QString text = QString( "%1 - %2 (%3 - %4)" ).arg( disc.id ).arg( pCoreUtils::toTitleCase( disc.title ) ).arg( QWBFS::Driver::regionToString( disc.region ) ).arg( QWBFS::Driver::regionToLanguageString( disc.region ) );
        text = metrics.elidedText( text, Qt::ElideRight, rect.width() );

        painter->setFont( font );
        painter->setPen( QColor( 0, 0, 0 ) );
        painter->setBrush( Qt::NoBrush );
        painter->drawText( rect, Qt::AlignLeft | Qt::AlignVCenter, text );
    }

    // size/origin
    {
        QFont font = painter->font();
        font.setBold( false );
        font.setPixelSize( 9 );

        QFontMetricsF metrics( font );
        rect = option.rect.adjusted( 40, rect.height(), -10, -2 );

        QString text = tr( "Estimated size: %1 - Origin: %2" ).arg( pCoreUtils::fileSizeToString( disc.size ) ).arg( disc.origin );
        text = metrics.elidedText( text, Qt::ElideRight, rect.width() );

        painter->setFont( font );
        painter->setPen( QColor( 0, 0, 0 ) );
        painter->setBrush( Qt::NoBrush );
        painter->drawText( rect, Qt::AlignLeft | Qt::AlignVCenter, text );
    }
}

void DiscDelegate::paintIcon( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const
{
    painter->setRenderHint( QPainter::Antialiasing );

    const bool selected = option.state & QStyle::State_Selected;
    const QWBFS::Model::Disc disc = mModel->disc( index );
    const int margin = 9;
    const int spacing = 5;
    const QString text = disc.title;
    QRect rect = option.rect.adjusted( margin, margin, -margin, -margin );
    QPixmap cover = mModel->coverPixmap( disc.id, rect.size() -QSize( 0, painter->font().pointSize() +spacing ) );
    QPixmap state = mModel->statePixmap( disc.state, QSize( 24, 24 ) );

    // selection
    if ( selected ) {
        QStyleOptionViewItemV4 o = option;
        o.rect = option.rect.adjusted( 1, 1, 0, 0 );

        paintFrame( painter, o );
    }

    // icon
    if ( !cover.isNull() ) {
        QRect r = QRect( QPoint(), cover.size() );
        r.moveCenter( rect.center() );
        r.moveTop( rect.top() );

        painter->drawPixmap( r.topLeft(), cover );
    }

    // state
    if ( !state.isNull() && disc.state != QWBFS::Driver::None ) {
        painter->drawPixmap( option.rect.topLeft() +QPoint( 2, 2 ), state );
    }

    // title
    {
        QStyleOptionViewItemV4 o = option;
        o.displayAlignment = Qt::AlignCenter;
        o.rect = option.rect.adjusted( 1, option.rect.height() -( margin *2 ), 0, 0 );
        o.icon = QIcon();
        o.text = painter->fontMetrics().elidedText( pCoreUtils::toTitleCase( text ), Qt::ElideRight, o.rect.width() -margin );

        if ( !selected ) {
            paintFrame( painter, o );
        }

        painter->setPen( selected ? o.palette.color( QPalette::HighlightedText ) : o.palette.color( QPalette::WindowText ) );
        painter->drawText( o.rect, o.displayAlignment, o.text );
    }
}


code:
/****************************************************************************
**
**      Created using Monkey Studio IDE v1.8.4.0 (1.8.4.0)
** Authors   : Filipe Azevedo aka Nox P@sNox <pasnox@gmail.com>
** Project   : QWBFS Manager
** FileName  : DiscDelegate.h
** Date      : 2010-06-16T14:19:29
** License   : GPL2
** Home Page : https://github.com/pasnox/qwbfsmanager
** Comment   : QWBFS Manager is a cross platform WBFS manager developed using C++/Qt4.
** It's currently working fine under Windows (XP to Seven, 32 & 64Bits), Mac OS X (10.4.x to 10.6.x), Linux & unix like.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This package is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
**
** In addition, as a special exception, the copyright holders give permission
** to link this program with the OpenSSL project's "OpenSSL" library (or with
** modified versions of it that use the same license as the "OpenSSL"
** library), and distribute the linked executables. You must obey the GNU
** General Public License in all respects for all of the code used other than
** "OpenSSL".  If you modify file(s), you may extend this exception to your
** version of the file(s), but you are not obligated to do so. If you do not
** wish to do so, delete this exception statement from your version.
**
****************************************************************************/
#ifndef DISCDELEGATE_H
#define DISCDELEGATE_H

#include <QStyledItemDelegate>

class pNetworkAccessManager;

namespace QWBFS {
namespace Model {

class DiscModel;

class DiscDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    DiscDelegate( QWBFS::Model::DiscModel* parent, pNetworkAccessManager* cache );
    virtual ~DiscDelegate();

    virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
    virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;

protected:
    QWBFS::Model::DiscModel* mModel;
    pNetworkAccessManager* mCache;

    void paintFrame( QPainter* painter, const QStyleOptionViewItemV4& option, bool pair = true ) const;
    void paintList( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const;
    void paintIcon( QPainter* painter, const QStyleOptionViewItemV4& option, const QModelIndex& index ) const;
};

}; // Model
}; // QWBFS

#endif // DISCDELEGATE_H