void MovedFilmsWindow::ShowFounded( QStringList fileNames )
{
    DebugPrintFunc( "MovedFilmsWindow::ShowFounded", fileNames.size() );

      // Flip button
    bScan->setText( tr("Scan") );
    progressBar->hide();

      // Show
    for( FilmItem* film : unavailableFilms )
    {
        QString unavailFilePath = film->GetFileName();
        QString unavailFileName = QFileInfo(unavailFilePath).fileName();

        for( QString newFilePath : fileNames )
        {
            QString newFileName = QFileInfo( newFilePath ).fileName();

            if( newFileName == unavailFileName && newFilePath != unavailFilePath ) // Protection from multiple moving
            {
                gbFounded->AddItem( newFilePath, qVariantFromValue( (void*)film ) );
                fileNames.removeOne( newFilePath );
                break;
            }
        }
    }

    if( gbFounded->GetItemsCount() == 0 )
    {
        QMessageBox::information( this, tr("Moved films"), tr("Nothing was found.") );
    }

    DebugPrintFuncDone( "MovedFilmsWindow::ShowFounded" );
}
void FilmScannerWindow::ShowFound( QStringList fileNames )
{
    DebugPrintFunc( "FilmScannerWindow::ShowFound", fileNames.size() );

    bScan->setText( tr("Scan") );
    progressBar->hide();

    if( fileNames.isEmpty() )
    {
        QMessageBox::information( this, tr("Film scanner"), tr("Nothing was found.") );
        return;
    }

    for( const QString& fileName : fileNames )
    {
        #ifdef PORTABLE_VERSION
            bool setDisabled = existedFileNames.contains( QDir(qApp->applicationDirPath()).relativeFilePath(fileName) );
        #else
            bool setDisabled = existedFileNames.contains( fileName );
        #endif

        gbFound->AddItem( fileName, setDisabled );
    }

    DebugPrintFuncDone( "FilmScannerWindow::ShowFound" );
}
void FilmInfoView::ShowInformation( const QModelIndex& index )
{
    if( index.isValid() )
    {
        DebugPrintFunc( "FilmInfoView::ShowInformation", index.row() );
        const FilmsListProxyModel* model = static_cast<const FilmsListProxyModel*>( index.model() );
        QString pattern = "<b>%1:</b> %2";

        lFilmTitle->setText( model->index( index.row(), FilmItem::TitleColumn ).data().toString() );
        lFilmTitle->show();

        for( QPair<FilmItem::Column,QLabel*>& item : textItems )
        {
            QString title = model->headerData( item.first, Qt::Horizontal, Qt::DisplayRole ).toString();
            QString text = model->index( index.row(), item.first ).data().toString();
            item.second->setText( pattern.arg( title, text ) );
            item.second->setVisible( !text.isEmpty() );
        }

        QString title = model->headerData( FilmItem::RatingColumn, Qt::Horizontal, Qt::DisplayRole ).toString();
        QString text = model->index( index.row(), FilmItem::RatingColumn ).data( Qt::ToolTipRole ).toString();
        lRating->setText( pattern.arg( title, text ) );
        lRating->setVisible( !text.isEmpty() );

        QVariant pixmap = model->index( index.row(), FilmItem::RatingColumn ).data( Qt::DecorationRole );
        lRatingImg->setPixmap( pixmap.value<QPixmap>() );
        lRatingImg->setVisible( !text.isEmpty() );

        DebugPrintFuncDone( "FilmInfoView::ShowInformation" );
    }
}
MovedFilmsWindow::MovedFilmsWindow( QWidget* parent ) : QDialog( parent ),
    filmScannerWorker( new FilmScannerWorker() )
{
    DebugPrintFunc( "MovedFilmsWindow::MovedFilmsWindow" );

    setupUi( this );
    setAttribute( Qt::WA_DeleteOnClose );
    eDirectory->setText( QDir::homePath() );
    progressBar->hide();

      // Worker
    connect( filmScannerWorker, &FilmScannerWorker::Scanned, this, &MovedFilmsWindow::ShowFounded );

      // Buttons and view
    connect( bSelectDirectory, &QPushButton::clicked, this, &MovedFilmsWindow::SelectDirectory );
    connect( bScan, &QPushButton::clicked, this, &MovedFilmsWindow::Scan );
    connect( bMove, &QPushButton::clicked, this, &MovedFilmsWindow::MoveSelected );

    connect( gbFounded, &FoundedListWidget::ItemsCountChanged, this, [this] (int count)
    {
        lTotalFounded->setText( QString::number(count) );
    } );

    connect( gbFounded, &FoundedListWidget::SelectionChanged, this, [this] (int count)
    {
        lSelected->setText( QString::number(count) );
    } );

    DebugPrintFuncDone( "MovedFilmsWindow::MovedFilmsWindow" );
}
bool FilmsListLoader::Populate( FilmItem* rootItem, QString fileName )
{
    DebugPrintFunc( "FilmsListLoader::Populate", fileName );

    QFile file( fileName );

    if( file.open(QIODevice::ReadOnly) )
    {
        QDataStream stream( &file );
        stream.setVersion( QDataStream::Qt_5_3 );

        QString databaseHeader; quint8 databaseVersion;
        stream >> databaseHeader >> databaseVersion;

        QByteArray data;
        stream >> data;
        file.close();

        if( !data.isEmpty() )
        {
            QJsonDocument rootDocument = QJsonDocument::fromJson(data);
            QJsonObject rootObject = rootDocument.object();
            QJsonArray filmsArray = rootObject["films"].toArray();

            for( int i = 0; i < filmsArray.count(); ++i )
            {
                rootItem->AppendChild( FromJsonObjectToFilm( filmsArray.at(i).toObject() ) );
            }
        }

        DebugPrint( "Success!" );
        DebugPrintFuncDone( "FilmsListLoader::Populate" );
        return( true );
    }
void MovedFilmsWindow::Scan()
{
    DebugPrintFunc( "MovedFilmsWindow::Scan" );

      // If scans
    if( filmScannerWorker->isRunning() )
    {
        filmScannerWorker->Cancel();
        return;
    }

    gbFounded->Clear();

      // Messages
    if( eDirectory->text().isEmpty() )
    {
        QMessageBox::information( this, tr("Moved films"), tr("Select the directory to scan.") );
        return;
    }

      // Scan
    filmScannerWorker->SetIsRecursive( cSearchInSubdirs->isChecked() );
    filmScannerWorker->SetDir( eDirectory->text() );
    filmScannerWorker->start();

      // Flip button
    bScan->setText( tr("Cancel") );
    progressBar->show();
}
void FilmInfoWindow::LoadTechnicalInfo( const QString& fileName )
{
    DebugPrintFunc( "FilmInfoWindow::LoadTechnicalInfo", fileName );
    QMutexLocker locker( &loadInfoMutex );

    MediaInfo* mi = new MediaInfo( fileName );
    emit FullInfoLoaded( mi->GetCompleteData() );
    delete mi;

    DebugPrintFuncDone( "FilmInfoWindow::LoadTechnicalInfo" );
}
void FilmsViewList::RestoreColumnsOrder()
{
    DebugPrintFunc( "FilmsViewList::RestoreColumnsOrder" );
    QHeaderView* header = horizontalHeader();

    for( int i = 0; i < model()->columnCount(); ++i )
    {
        header->moveSection( header->visualIndex(i), i );
    }

    DebugPrintFuncDone( "FilmsViewList::RestoreColumnsOrder" );
}
MovedFilmsWindow::~MovedFilmsWindow()
{
    DebugPrintFunc( "MovedFilmsWindow::~MovedFilmsWindow" );

    if( filmScannerWorker->isRunning() )
    {
        filmScannerWorker->Terminate();
        filmScannerWorker->wait();
    }

    delete filmScannerWorker;
    DebugPrintFuncDone( "MovedFilmsWindow::~MovedFilmsWindow" );
}
Beispiel #10
0
void NetworkRequest::run( const QUrl& url )
{
    DebugPrintFunc( "NetworkRequest::run", url.toString() );

    data.clear();
    reply = MakeRequest( url );

    connect( reply.data(), &QNetworkReply::downloadProgress, this, [this] (quint64 received, quint64 total) { emit Progress( received, total ); } );
    connect( reply.data(), &QNetworkReply::readyRead, this, &NetworkRequest::ReadyRead );
    connect( reply.data(), &QNetworkReply::finished, this, &NetworkRequest::Finished );
    connect( reply.data(), &QNetworkReply::finished, reply.data(), &QObject::deleteLater );

    DebugPrintFuncDone( "NetworkRequest::run" );
}
Beispiel #11
0
FilmsListModel::FilmsListModel( QObject* parent ) : QAbstractItemModel( parent ),
      settings( AlexandraSettings::GetInstance() ), rootItem( nullptr )
{
    DebugPrintFunc( "FilmsListModel::FilmsListModel" );

    QList<QVariant> titles =
    {
        tr( "Title" ),
        tr( "Original title" ),
        tr( "Tagline" ),
        tr( "Year" ),
        tr( "Genre" ),
        tr( "Country" ),
        tr( "Director" ),
        tr( "Producer" ),
        tr( "Screenwriter" ),
        tr( "Composer" ),
        tr( "Budget" ),
        tr( "Rating" ),
        tr( "Viewed" ),
        tr( "Favourite" ),
        tr( "Views" ),
        tr( "Starring" ),
        tr( "Description" ),
        tr( "Tags" ),
        tr( "Filename" ),
        tr( "Poster" )
    };

    rootItem = new FilmItem( titles );

    connect( this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(DatabaseChanged()) );
    connect( this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(DatabaseChanged()) );
    connect( this, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SIGNAL(DatabaseChanged()) );
    connect( this, SIGNAL(layoutChanged()), this, SIGNAL(DatabaseChanged()) );
    connect( this, SIGNAL(modelReset()), this, SIGNAL(DatabaseChanged()) );

    connect( &savingTimer, &QTimer::timeout, this, [this]
    {
        SaveToFileAsync( savingFileName );
    } );

    DebugPrintFuncDone( "FilmsListModel::FilmsListModel" );
}
Beispiel #12
0
FilmScannerWindow::FilmScannerWindow( QWidget* parent ) : QDialog( parent ),
    settings( AlexandraSettings::GetInstance() ),
    filmScannerWorker( new FilmScannerWorker() ),
    filmAddWorker( new FilmScannerAddWorker() )
{
    DebugPrintFunc( "FilmScannerWindow::FilmScannerWindow" );

    setupUi( this );
    setAttribute( Qt::WA_DeleteOnClose );
    eDirectory->setText( settings->GetFilmsScannerLastDir() );
    progressBar->hide();

      // Scanner worker
    connect( filmScannerWorker, &FilmScannerWorker::Scanned,         this, &FilmScannerWindow::ShowFound );
    connect( filmScannerWorker, &FilmScannerWorker::IncFoundTotal, this, &FilmScannerWindow::IncFoundTotal );

      // Add worker
    connect( filmAddWorker, &FilmScannerAddWorker::FilmCreated, this, &FilmScannerWindow::AddFilm );
    connect( filmAddWorker, &FilmScannerAddWorker::FilmCreated, this, &FilmScannerWindow::DisableFilm );

      // Parsers
    cbSource->addItems( ParserManager().GetAvailableParsers() );
    cbSource->setCurrentIndex( settings->GetDefaultParserIndex() );
    cDownloadBigPoster->setChecked( settings->GetParsersLoadBigPoster() );
    cDownloadMoreInformation->setChecked( settings->GetParsersLoadAdvancedInfo() );

      // Buttons and view
    connect( bSelectDirectory, &QPushButton::clicked, this, &FilmScannerWindow::SelectDirectory );
    connect( bScan,            &QPushButton::clicked, this, &FilmScannerWindow::Scan );
    connect( bAdd,             &QPushButton::clicked, this, &FilmScannerWindow::AddSelected );

    connect( this->gbFound, &FoundListWidget::ItemsCountChanged, this, [this] (int count)
    {
        this->lTotalFound->setText( QString::number(count) );
    } );

    connect( this->gbFound, &FoundListWidget::SelectionChanged, this, [this] (int count)
    {
        lSelected->setText( QString::number(count) );
    } );

    DebugPrintFuncDone( "FilmScannerWindow::FilmScannerWindow()" );
}
void FilmsViewList::SetDefaultColumnsView()
{
    DebugPrintFunc( "FilmsViewList::SetDefaultColumnsView" );

      // Move to start
    QHeaderView* header = horizontalHeader();
    header->moveSection( FilmItem::IsFavouriteColumn, 0 );
    header->moveSection( FilmItem::IsViewedColumn + 1, 0 );

      // Hide
    QList<int> hiddenColumns =
    {
        FilmItem::OriginalTitleColumn, FilmItem::CountryColumn,  FilmItem::ProducerColumn,
        FilmItem::ScreenwriterColumn,  FilmItem::ComposerColumn, FilmItem::BudgetColumn,
        FilmItem::ViewsCountColumn,    FilmItem::TaglineColumn,  FilmItem::StarringColumn,
        FilmItem::DescriptionColumn,   FilmItem::TagsColumn,     FilmItem::FileNameColumn,
        FilmItem::PosterColumn
    };

    for( int column : hiddenColumns )
    {
        header->hideSection( column );
    }

      // Show and resize
    QList< QPair<int,int> > shownColumns =
    {
        { FilmItem::TitleColumn, 150 }, { FilmItem::YearColumn, 50 },
        { FilmItem::GenreColumn, 110 }, { FilmItem::DirectorColumn, 110 },
        { FilmItem::RatingColumn, 50 }, { FilmItem::IsViewedColumn, 20 },
        { FilmItem::IsFavouriteColumn, 20 }
    };

    for( QPair<int,int>& column : shownColumns )
    {
        header->showSection( column.first );
        header->resizeSection( column.first, column.second );
    }

    header->setSortIndicator( FilmItem::TitleColumn, Qt::AscendingOrder );
    DebugPrintFuncDone( "FilmsViewList::SetDefaultColumnsView" );
}
Beispiel #14
0
QByteArray NetworkRequest::runSync( const QUrl& url )
{
    DebugPrintFunc( "NetworkRequest::runSync", url.toString() );

    data.clear();
    reply = MakeRequest( url );

    QEventLoop loop;
    connect( reply.data(), &QNetworkReply::downloadProgress, this, [this] (quint64 received, quint64 total) { emit Progress( received, total ); } );
    connect( reply.data(), &QNetworkReply::readyRead, this, &NetworkRequest::ReadyRead );
    connect( reply.data(), &QNetworkReply::finished, this, &NetworkRequest::CheckForRedirect );
    connect( reply.data(), &QNetworkReply::finished, &loop, &QEventLoop::quit );
    loop.exec();

    DebugPrint( QString( "Loaded: %1 bytes" ).arg( data.size() ) );
    DebugPrintFuncDone( "NetworkRequest::runSync" );

    reply->deleteLater();
    return( data );
}
Beispiel #15
0
FilmScannerWindow::~FilmScannerWindow()
{
    DebugPrintFunc( "FilmScannerWindow::~FilmScannerWindow" );

    if( filmScannerWorker->isRunning() )
    {
        filmScannerWorker->Terminate();
        filmScannerWorker->wait();
    }
    else if( filmAddWorker->isRunning() )
    {
        filmAddWorker->Cancel();
        filmAddWorker->wait();
    }

    delete filmScannerWorker;
    delete filmAddWorker;

    DebugPrintFuncDone( "FilmScannerWindow::~FilmScannerWindow" );
}
Beispiel #16
0
QUrl ImdbParser::Parse( const QByteArray& data )
{
    DebugPrintFunc( "ImdbParser::Parse", data.size() );

    QString foundedPage( data );
    RegExpTools::SimplifyText( foundedPage );

    QRegExp reRedirect( "class=\"number\">1.</td><td class=\"title\"><a href=\"(.*)\">");
    QString redirectUrl( RegExpTools::ParseItem( foundedPage, reRedirect ) );

    QUrl posterUrl;

    if( !redirectUrl.isEmpty() )
    {
        redirectUrl = "http://www.imdb.com" + redirectUrl;

        QString str( request.runSync( QUrl( redirectUrl ) ) );
        RegExpTools::SimplifyText( str );

        DebugPrint( QString( "Simpified to: %1 bytes" ).arg( str.size() ) );

          // Title
        QRegExp reTitle( "h1 itemprop=\"name\".*>(.*)<span" );
        film.SetColumnData( FilmItem::TitleColumn, RegExpTools::ParseItem( str, reTitle ) );

          // Original title
        QRegExp reOriginalTitle( "div class=\"originalTitle\">(.*)<span" );
        film.SetColumnData( FilmItem::OriginalTitleColumn, RegExpTools::ParseItem( str, reOriginalTitle ) );

          // Tagline
        QRegExp reTagline( "Taglines:</h4>(.*)<" );
        film.SetColumnData( FilmItem::TaglineColumn, RegExpTools::ParseItem( str, reTagline ) );

          // Year
        QRegExp reYear( "Release Date:</h4>.*([0-9]{4})" );
        film.SetColumnData( FilmItem::YearColumn, RegExpTools::ParseItem( str, reYear ).toInt() );

          // Budget
        QRegExp reBudget( "Budget:</h4> \\$(.*)<span" );
        film.SetColumnData( FilmItem::BudgetColumn, RegExpTools::ParseItem( str, reBudget ).replace( " ", "" ).toDouble() );

          // Rating
        QRegExp reRating( "itemprop=\"ratingValue\">(.*)</span>" );
        film.SetColumnData( FilmItem::RatingColumn, RegExpTools::ParseItem( str, reRating ).replace( ",", "." ).toDouble() );

          // Country
        QRegExp reCountryList( "Countr.*</h4>(.*)</div>" );
        QRegExp reCountry( "href=\"/country/.*>(.*)</a>" );
        film.SetColumnData( FilmItem::CountryColumn, RegExpTools::ParseList( str, reCountryList, reCountry ) );

          // Genre
        QRegExp reGenreList( "Genres:</h4>(.*)</div>" );
        QRegExp reGenre( "href=\"/genre/.*>(.*)</a>" );
        film.SetColumnData( FilmItem::GenreColumn, RegExpTools::ParseList( str, reGenreList, reGenre ) );

          // Description
        QRegExp reDescription( "Storyline</h2><.*><p>(.*)<em class=\"nobr\">" );
        film.SetColumnData( FilmItem::DescriptionColumn, RegExpTools::ParseItem( str, reDescription ).replace( "<br><br>", "<br>\n" ) );

          // Advanced information

        QRegExp reName( "itemprop=\"name\">(.*)</span>" );

        if( AlexandraSettings::GetInstance()->GetParsersLoadAdvancedInfo() )
        {
            QString str( request.runSync( QUrl( redirectUrl + "fullcredits" ) ) );
            RegExpTools::SimplifyText( str );
            DebugPrint( QString( "Simpified to: %1 bytes" ).arg( str.size() ) );

              // Starring
            QRegExp reStarringList( "Cast <span>(.*)Produced by" );
            film.SetColumnData( FilmItem::StarringColumn, RegExpTools::ParseList( str, reStarringList, reName, 20 ) );  // 20 first actors

              // Director
            QRegExp reDirectorList( "Directed by(.*)Writing Credits" );
            reName = QRegExp( "href=\"/name/.*>(.*)</a>" );
            film.SetColumnData( FilmItem::DirectorColumn, RegExpTools::ParseList( str, reDirectorList, reName, 10 ) );  // 10 first directors

              // Screenwriter
            QRegExp reScreenwriterList( "Writing Credits(.*)Cast" );
            film.SetColumnData( FilmItem::ScreenwriterColumn, RegExpTools::ParseList( str, reScreenwriterList, reName, 10 ) ); // 10 first writers

              // Producer
            QRegExp reProducerList( "Produced by(.*)Music by" );
            film.SetColumnData( FilmItem::ProducerColumn, RegExpTools::ParseList( str, reProducerList, reName, 10 ) );  // 10 first producers

              // Composer
            QRegExp reComposerList( "Music by(.*)Film Editing by" );
            film.SetColumnData( FilmItem::ComposerColumn, RegExpTools::ParseList( str, reComposerList, reName ) );
        }
        else
        {
              // Starring
            QRegExp reStarringList( "Cast</h2>(.*)</table>" );
            film.SetColumnData( FilmItem::StarringColumn, RegExpTools::ParseList( str, reStarringList, reName ) );

              // Director
            QRegExp reDirectorList( "Director.*</h4>(.*)</div>" );
            QRegExp reName( "itemprop=\"name\">(.*)</span>" );
            film.SetColumnData( FilmItem::DirectorColumn, RegExpTools::ParseList( str, reDirectorList, reName ) );

              // Screenwriter
            QRegExp reScreenwriterList( "Writer.*</h4>(.*)</div>" );
            film.SetColumnData( FilmItem::ScreenwriterColumn, RegExpTools::ParseList( str, reScreenwriterList, reName ) );
        }

          // Poster

        if( AlexandraSettings::GetInstance()->GetParsersLoadBigPoster() )
        {
            QRegExp rePoster( "div class=\"poster\"><a href=\"(.*)\"" );
            QString s = QString( request.runSync( QUrl( "http://www.imdb.com" + RegExpTools::ParseItem( str, rePoster ) ) ) );

            RegExpTools::SimplifyText( s );
            DebugPrint( QString( "Simpified to: %1 bytes" ).arg( s.size() ) );

            rePoster = QRegExp( "id=\"primary-img\".*src=\"(.*)\"" );
            posterUrl = RegExpTools::ParseItem( s, rePoster );
        }

        if( posterUrl.isEmpty() ) // Small poster
        {
            QRegExp rePoster( "div class=\"poster\"><.*><img.*src=\"(.*)\"" );
            posterUrl = RegExpTools::ParseItem( str, rePoster );
        }

        DebugPrint( "Text parsed!" );
        emit Loaded( film, posterUrl );
    }
    else
    {
        emit Error( "Movie not found!" );
    }

    return( posterUrl );
}
Beispiel #17
0
ImdbParser::ImdbParser() : AbstractParser()
{
    DebugPrintFunc( "ImdbParser::ImdbParser" );
    searchUrlWithYear = QString( "http://www.imdb.com/search/title?title=%1&release_date=%2&view=simple" );
    searchUrl = QString( "http://www.imdb.com/search/title?title=%1&view=simple" );
}
bool FilmsListOldLoader::Populate( FilmItem* rootItem, const QString& fileName )
{
    DebugPrintFunc( "FilmsListOldLoader::Populate", fileName );

    QFile file( fileName );

    if( file.open(QIODevice::ReadOnly) )
    {
        AlexandraSettings* settings = AlexandraSettings::GetInstance();

        QDataStream stream( &file );
        QString header;
        quint8 version;
        stream >> header >> version;

        if( version == OldVersion10 )
        {
            QList<Film010> films;
            stream >> films;

            for( Film010& film : films )
            {
                // Views counter
                int viewsCount = film.GetViewsCounter();

                if( film.GetIsViewed() && viewsCount == 0 )
                {
                    viewsCount = 1;
                }

                bool isViewed = (viewsCount > 0) ? true : false;

                // Poster files renaming (for very old databases)
                QString posterFilename = film.GetPosterName();

                if( !posterFilename.isEmpty() )
                {
                    QString posterFilepath = settings->GetPostersDirPath() + "/" + posterFilename;
                    QFile posterFile( posterFilepath );

                    if( !posterFile.exists() )
                    {
                        QString maybeOldPoster = FilesExtensions::SearchForEponymousImage(posterFilepath);

                        if ( !maybeOldPoster.isEmpty() )
                        {
                            QFileInfo fileinfo( maybeOldPoster );
                            QDir postersDir( fileinfo.absolutePath() );
                            postersDir.rename( fileinfo.fileName(), posterFilename );
                        }
                    }
                }

                // Filling data
                QList<QVariant> data;

                data << film.GetTitle()
                     << film.GetOriginalTitle()
                     << film.GetTagline()
                     << film.GetYear()
                     << film.GetGenre()
                     << film.GetCountry()
                     << film.GetDirector()
                     << film.GetProducer()
                     << film.GetScreenwriter()
                     << film.GetComposer()
                     << film.GetBudget()
                     << film.GetRating()
                     << isViewed
                     << film.GetIsFavourite()
                     << viewsCount
                     << film.GetStarring()
                     << film.GetDescription()
                     << film.GetTags()
                     << film.GetFileName()
                     << film.GetId(); // PosterName

                FilmItem* item = new FilmItem( data, rootItem );
                rootItem->AppendChild( item );
            }

            DebugPrint( "Success!" );
            DebugPrintFuncDone( "FilmsListOldLoader::Populate" );
            return( true );
        }
Beispiel #19
0
void FilmsListModel::LoadFromFile( QString fileName )
{
    DebugPrintFunc( "FilmsList::LoadFromFile", fileName );

    beginResetModel();
    rootItem->RemoveChildren();
    QFile file( fileName );

    if( !file.exists() )
    {
        isDatabaseChanged = true; // Will be created
        emit DatabaseIsEmpty();
    }
    else if( file.open( QIODevice::ReadOnly ) )
    {
        QDataStream stream( &file );
        QString databaseHeader;
        stream >> databaseHeader;

        if( databaseHeader == Alexandra::databaseHeader )
        {
            bool isLoaded;
            quint8 databaseVersion;
            stream >> databaseVersion;
            file.close();

            if( databaseVersion == Alexandra::databaseVersion )
            {
                isLoaded = FilmsListLoader::Populate( rootItem, fileName );
            }
            else
            {
                emit DatabaseConvertOld();

                isLoaded = FilmsListOldLoader::Populate( rootItem, fileName );

                if( isLoaded )
                {
                    FilmsListLoader::Save( rootItem, fileName );
                }
            }

            if( isLoaded )
            {
                DebugPrint( "Reading done!" );
                emit DatabaseLoaded();
                isReadonly = false;

                if( rootItem->GetChildrenCount() == 0 )
                {
                    emit DatabaseIsEmpty();
                }

                if( !QFileInfo(fileName).isWritable() )
                {
                    emit DatabaseIsReadonly();
                    isReadonly = true;
                }
            }
            else
            {
                emit DatabaseReadError( tr("Can't load database!") );
            }
        }