Commit f824e2b5 authored by Bart Cerneels's avatar Bart Cerneels
Browse files

Don't block the organizer dialog.

Process in batches instead.

BUG:233196
parent 202c49eb
......@@ -45,9 +45,11 @@ OrganizeCollectionDialog::OrganizeCollectionDialog( const Meta::TrackList &track
QFlags<KDialog::ButtonCode> buttonMask )
: KDialog( parent )
, ui( new Ui::OrganizeCollectionDialogBase )
, m_trackOrganizerDone( false )
, m_detailed( true )
, m_schemeModified( false )
, m_formatListModified( false )
, m_conflict( false )
{
Q_UNUSED( name )
......@@ -57,7 +59,7 @@ OrganizeCollectionDialog::OrganizeCollectionDialog( const Meta::TrackList &track
showButtonSeparator( true );
m_targetFileExtension = targetExtension;
if ( tracks.size() > 0 )
if( tracks.size() > 0 )
{
m_allTracks = tracks;
}
......@@ -69,10 +71,11 @@ OrganizeCollectionDialog::OrganizeCollectionDialog( const Meta::TrackList &track
ui->setupUi( mainContainer );
m_trackOrganizer = new TrackOrganizer( m_allTracks, this );
m_filenameLayoutDialog = new FilenameLayoutDialog( mainContainer, 1 ); //", 1" means isOrganizeCollection ==> doesn't show Options frame
// m_filenameLayoutDialog->hide();
connect( this, SIGNAL( accepted() ),
m_filenameLayoutDialog, SLOT( onAccept() ) );
connect( m_trackOrganizer, SIGNAL(finished()), SLOT(slotOrganizerFinished()) );
//TODO: s/1/enum/g
//", 1" means isOrganizeCollection ==> doesn't show Options frame
m_filenameLayoutDialog = new FilenameLayoutDialog( mainContainer, 1 );
connect( this, SIGNAL( accepted() ), m_filenameLayoutDialog, SLOT( onAccept() ) );
ui->verticalLayout->insertWidget( 1, m_filenameLayoutDialog );
ui->ignoreTheCheck->show();
......@@ -96,33 +99,25 @@ OrganizeCollectionDialog::OrganizeCollectionDialog( const Meta::TrackList &track
KColorScheme::adjustForeground( p, KColorScheme::NegativeText ); // TODO this isn't working, the color is still normal
ui->conflictLabel->setPalette( p );
QTimer *updatePreviewTimer = new QTimer( this );
updatePreviewTimer->setSingleShot( true );
updatePreviewTimer->setInterval( 2000 );
connect( updatePreviewTimer, SIGNAL(timeout()), SLOT(slotUpdatePreview()) );
//schedule first run next iteration of eventloop (will not block UI)
updatePreviewTimer->start();
// to show the conflict error
connect( ui->overwriteCheck, SIGNAL( stateChanged( int ) ), SLOT( slotUpdatePreview() ) );
connect( ui->overwriteCheck, SIGNAL(stateChanged( int )), SLOT(slotUpdatePreview()) );
connect( ui->ignoreTheCheck, SIGNAL(toggled(bool)), SLOT(slotUpdatePreview()) );
connect( ui->spaceCheck , SIGNAL(toggled(bool)), SLOT(slotUpdatePreview()) );
connect( ui->asciiCheck , SIGNAL(toggled(bool)), SLOT(slotUpdatePreview()) );
connect( ui->regexpEdit , SIGNAL(textChanged(QString)), SLOT(slotUpdatePreview()) );
connect( ui->replaceEdit , SIGNAL(textChanged(QString)), SLOT(slotUpdatePreview()) );
//only start calculating preview after timeout.
connect( m_filenameLayoutDialog, SIGNAL( schemeChanged() ), updatePreviewTimer,
SLOT( start() ) );
connect( this, SIGNAL( finished(int) ), SLOT( slotSaveFormatList() ) );
connect( this , SIGNAL( accepted() ), SLOT( slotDialogAccepted() ) );
connect( ui->folderCombo, SIGNAL( currentIndexChanged( const QString & ) ),
this, SLOT( slotUpdatePreview() ) );
connect( ui->folderCombo, SIGNAL( currentIndexChanged( const QString & ) ),
this, SLOT( slotEnableOk( const QString & ) ) );
connect( ui->addPresetButton, SIGNAL( clicked( bool ) ), this, SLOT( slotAddFormat() ) );
connect( ui->removePresetButton, SIGNAL( clicked( bool ) ), this, SLOT( slotRemoveFormat() ) );
connect( ui->updatePresetButton, SIGNAL( clicked( bool ) ), this, SLOT( slotUpdateFormat() ) );
connect( ui->spaceCheck, SIGNAL(toggled(bool)), SLOT(slotUpdatePreview()) );
connect( ui->asciiCheck, SIGNAL(toggled(bool)), SLOT(slotUpdatePreview()) );
connect( ui->vfatCheck, SIGNAL(toggled(bool)), SLOT(slotUpdatePreview()) );
connect( ui->regexpEdit, SIGNAL(textChanged(QString)), SLOT(slotUpdatePreview()) );
connect( ui->replaceEdit, SIGNAL(textChanged(QString)), SLOT(slotUpdatePreview()) );
connect( ui->folderCombo, SIGNAL(currentIndexChanged( const QString & )),
SLOT(slotUpdatePreview()) );
connect( m_filenameLayoutDialog, SIGNAL(schemeChanged()), SLOT(slotUpdatePreview()) );
connect( this, SIGNAL(finished(int)), SLOT(slotSaveFormatList()) );
connect( this, SIGNAL(accepted()), SLOT(slotDialogAccepted()) );
connect( ui->folderCombo, SIGNAL(currentIndexChanged( const QString & )),
SLOT(slotEnableOk( const QString & )) );
connect( ui->addPresetButton, SIGNAL(clicked( bool )), SLOT(slotAddFormat()) );
connect( ui->removePresetButton, SIGNAL(clicked( bool )), SLOT(slotRemoveFormat()) );
connect( ui->updatePresetButton, SIGNAL(clicked( bool )), SLOT(slotUpdateFormat()) );
slotEnableOk( ui->folderCombo->currentText() );
......@@ -131,7 +126,7 @@ OrganizeCollectionDialog::OrganizeCollectionDialog( const Meta::TrackList &track
OrganizeCollectionDialog::~OrganizeCollectionDialog()
{
DEBUG_BLOCK
QApplication::restoreOverrideCursor();
AmarokConfig::setOrganizeDirectory( ui->folderCombo->currentText() );
delete ui;
......@@ -210,57 +205,6 @@ OrganizeCollectionDialog::commonPrefix( const QStringList &list ) const
}
void
OrganizeCollectionDialog::preview( const QString &format )
{
ui->previewTableWidget->clearContents();
bool conflict = false;
QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
m_trackOrganizer->setFormatString( format );
m_trackOrganizer->setTargetFileExtension( m_targetFileExtension );
QMap<Meta::TrackPtr, QString> dests = m_trackOrganizer->getDestinations();
ui->previewTableWidget->setRowCount( dests.count() );
QMapIterator<Meta::TrackPtr, QString> it( dests );
int i = 0;
while( it.hasNext() )
{
it.next();
Meta::TrackPtr track = it.key();
QString originalPath = track->prettyUrl();
QString newPath = it.value();
QFileInfo info( newPath );
if( !conflict && info.exists() )
conflict = true;
//new path preview in the 1st column
QPalette p = ui->previewTableWidget->palette();
QTableWidgetItem *item = new QTableWidgetItem( newPath );
KColorScheme::adjustBackground(p, KColorScheme::NegativeBackground);
if( info.exists() )
item->setBackgroundColor( p.color( QPalette::Base ) );
ui->previewTableWidget->setItem( i, 0, item );
//original in the second column
item = new QTableWidgetItem( originalPath );
ui->previewTableWidget->setItem( i, 1, item );
++i;
}
QApplication::restoreOverrideCursor();
if( conflict )
{
if( ui->overwriteCheck->isChecked() )
ui->conflictLabel->setText( i18n( "There is a filename conflict, existing files will be overwritten." ) );
else
ui->conflictLabel->setText( i18n( "There is a filename conflict, existing files will not be changed." ) );
}
else
ui->conflictLabel->setText(""); // we clear the text instead of hiding it to retain the layout spacing
}
void
OrganizeCollectionDialog::update( int dummy ) //why the dummy?
{
......@@ -340,19 +284,77 @@ OrganizeCollectionDialog::slotUpdatePreview()
m_trackOrganizer->setAsciiOnly( ui->asciiCheck->isChecked() );
m_trackOrganizer->setFolderPrefix( ui->folderCombo->currentText() );
m_trackOrganizer->setFormatString( formatString );
m_trackOrganizer->setTargetFileExtension( m_targetFileExtension );
m_trackOrganizer->setIgnoreThe( ui->ignoreTheCheck->isChecked() );
m_trackOrganizer->setReplaceSpaces( ui->spaceCheck->isChecked() );
m_trackOrganizer->setReplace( ui->regexpEdit->text(), ui->replaceEdit->text() );
m_trackOrganizer->setVfatSafe( ui->vfatCheck->isChecked() );
preview( formatString );
//empty the table, not only it's contents
ui->previewTableWidget->setRowCount( 0 );
m_conflict = false;
m_trackOrganizerDone = false;
QApplication::setOverrideCursor( QCursor( Qt::BusyCursor ) );
int index = ui->presetCombo->currentIndex();
if( index != -1 )
previewNextBatch();
}
void
OrganizeCollectionDialog::previewNextBatch() //private slot
{
QMap<Meta::TrackPtr, QString> dests = m_trackOrganizer->getDestinations( 10 );
QMapIterator<Meta::TrackPtr, QString> it( dests );
while( it.hasNext() )
{
m_schemeModified = ( m_filenameLayoutDialog->getParsableScheme() !=
ui->presetCombo->itemData( index ).toString() );
it.next();
Meta::TrackPtr track = it.key();
QString originalPath = track->prettyUrl();
QString newPath = it.value();
int newRow = ui->previewTableWidget->rowCount();
ui->previewTableWidget->insertRow( newRow );
//new path preview in the 1st column
QPalette p = ui->previewTableWidget->palette();
QTableWidgetItem *item = new QTableWidgetItem( newPath );
KColorScheme::adjustBackground( p, KColorScheme::NegativeBackground );
if( QFileInfo( newPath ).exists() )
{
item->setBackgroundColor( p.color( QPalette::Base ) );
m_conflict = true;
}
ui->previewTableWidget->setItem( newRow, 0, item );
//original in the second column
item = new QTableWidgetItem( originalPath );
ui->previewTableWidget->setItem( newRow, 1, item );
}
if( m_conflict )
{
if( ui->overwriteCheck->isChecked() )
ui->conflictLabel->setText( i18n( "There is a filename conflict, existing files will be overwritten." ) );
else
ui->conflictLabel->setText( i18n( "There is a filename conflict, existing files will not be changed." ) );
}
else
ui->conflictLabel->setText(""); // we clear the text instead of hiding it to retain the layout spacing
//non-blocking way of updating the preview table.
if( !m_trackOrganizerDone )
QTimer::singleShot( 0, this, SLOT(previewNextBatch()) );
}
/** WARNING: this slot *has* to be connected with a Qt::DirectConnection to avoid overrun in
* previewNextBatch()
*/
void
OrganizeCollectionDialog::slotOrganizerFinished()
{
m_trackOrganizerDone = true;
QApplication::restoreOverrideCursor();
}
void
......@@ -408,7 +410,7 @@ OrganizeCollectionDialog::slotUpdateFormat()
int idx = ui->presetCombo->currentIndex();
QString formatString = m_filenameLayoutDialog->getParsableScheme();
ui->presetCombo->setItemData( idx, formatString );
ui->updatePresetButton->setEnabled( m_schemeModified = false );
ui->updatePresetButton->setEnabled( false );
m_formatListModified = true;
}
......
......@@ -58,6 +58,7 @@ class AMAROK_EXPORT OrganizeCollectionDialog : public KDialog
public slots:
void slotUpdatePreview();
void slotDialogAccepted();
private slots:
void slotFormatPresetSelected( int );
void slotAddFormat();
......@@ -65,12 +66,14 @@ class AMAROK_EXPORT OrganizeCollectionDialog : public KDialog
void slotUpdateFormat();
void slotSaveFormatList();
void previewNextBatch();
void slotOrganizerFinished();
private:
QString buildFormatTip() const;
QString buildFormatString() const;
QString commonPrefix( const QStringList &list ) const;
void toggleDetails();
void preview( const QString &format );
void update( int dummy );
void update( const QString &dummy );
void init();
......@@ -79,12 +82,15 @@ class AMAROK_EXPORT OrganizeCollectionDialog : public KDialog
Ui::OrganizeCollectionDialogBase *ui;
FilenameLayoutDialog *m_filenameLayoutDialog;
TrackOrganizer *m_trackOrganizer;
bool m_trackOrganizerDone;
bool m_detailed;
Meta::TrackList m_allTracks;
QString m_targetFileExtension;
bool m_schemeModified;
bool m_formatListModified;
bool m_conflict;
private slots:
void slotEnableOk( const QString & currentCollectionRoot );
};
......
......@@ -28,6 +28,7 @@
TrackOrganizer::TrackOrganizer( const Meta::TrackList &tracks, QObject* parent )
: QObject( parent )
, m_allTracks( tracks )
, m_trackOffset( 0 )
, m_IgnoreThe( false )
, m_AsciiOnly( false )
, m_UnderscoresNotSpaces( false )
......@@ -133,54 +134,98 @@ QString TrackOrganizer::cleanPath( const QString& component ) const
return result;
}
QMap< Meta::TrackPtr, QString > TrackOrganizer::getDestinations()
QMap< Meta::TrackPtr, QString > TrackOrganizer::getDestinations( unsigned int batchSize )
{
QMap<Meta::TrackPtr, QString> destinations;
foreach( const Meta::TrackPtr &track, m_allTracks )
int newOffset = m_trackOffset + batchSize;
//don't go out of bounds in the for loop
if( newOffset >= m_allTracks.count() )
newOffset = m_allTracks.count() - 1;
if( batchSize == 0 )
{
m_trackOffset = 0;
newOffset = m_allTracks.count();
}
for( ; m_trackOffset < newOffset ; m_trackOffset++ )
{
Meta::TrackPtr track = m_allTracks.value( m_trackOffset );
if( track )
destinations.insert( track, buildDestination( m_format, track ) );
}
if( m_trackOffset == m_allTracks.count() - 1 )
{
emit finished();
m_trackOffset = 0;
}
return destinations;
}
void TrackOrganizer::setFormatString( const QString& format )
{
if( m_format != format )
m_trackOffset = 0;
m_format = format;
}
void TrackOrganizer::setFolderPrefix(const QString& prefix)
{
if( m_folderPrefix != prefix )
m_trackOffset = 0;
m_folderPrefix = prefix;
}
void TrackOrganizer::setAsciiOnly(bool flag)
{
if( m_AsciiOnly != flag )
m_trackOffset = 0;
m_AsciiOnly = flag;
}
void TrackOrganizer::setIgnoreThe(bool flag)
{
if( m_IgnoreThe != flag )
m_trackOffset = 0;
m_IgnoreThe = flag;
}
void TrackOrganizer::setReplaceSpaces(bool flag)
{
if( m_UnderscoresNotSpaces != flag )
m_trackOffset = 0;
m_UnderscoresNotSpaces = flag;
}
void TrackOrganizer::setVfatSafe(bool flag)
{
if( m_vfatSafe != flag )
m_trackOffset = 0;
m_vfatSafe = flag;
}
void TrackOrganizer::setReplace(const QString& regex, const QString& string)
{
if( m_regexPattern != regex || m_replaceString != string )
m_trackOffset = 0;
m_regexPattern = regex;
m_replaceString = string;
}
void TrackOrganizer::setTargetFileExtension( const QString &fileExtension )
{
if( m_targetFileExtension != fileExtension )
m_trackOffset = 0;
m_targetFileExtension = fileExtension;
}
......@@ -81,24 +81,30 @@ public:
*/
void setTargetFileExtension( const QString &fileExtension );
/**
* Get the list of processed destinations
* Only call after setting all the appropriate options
* @see setFormatString
* @arg batchSize How many to return this run of the function. If 0 (default) will calculate the
* complete list. This function can return a shorter list at the end of the results list.
* Over consecutive runs of this function the same number of results as the length of the
* tracklist passed in the constructor will be returned.
*/
QMap<Meta::TrackPtr, QString> getDestinations();
QMap<Meta::TrackPtr, QString> getDestinations( unsigned int batchSize = 0 );
signals:
void finished();
private:
QString buildDestination( const QString &format, const Meta::TrackPtr &track ) const;
QString cleanPath( const QString &component ) const;
Meta::TrackList m_allTracks;
QString m_format;
QString m_folderPrefix;
int m_trackOffset;
//options
QString m_format;
QString m_folderPrefix;
bool m_IgnoreThe;
bool m_AsciiOnly;
bool m_UnderscoresNotSpaces;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment