/*************************************************************************** dlgpreflibrary.cpp - description ------------------- begin : Thu Apr 17 2003 copyright : (C) 2003 by Tue & Ken Haste Andersen email : haste@diku.dk ***************************************************************************/ /*************************************************************************** * * * 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 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "dlgpreflibrary.h" #include "soundsourceproxy.h" #define MIXXX_ADDONS_URL "http://www.mixxx.org/wiki/doku.php/add-ons" DlgPrefLibrary::DlgPrefLibrary(QWidget * parent, ConfigObject * config, Library *pLibrary) : DlgPreferencePage(parent), m_dirListModel(), m_pconfig(config), m_pLibrary(pLibrary), m_baddedDirectory(false), m_iOriginalTrackTableRowHeight(Library::kDefaultRowHeightPx) { setupUi(this); slotUpdate(); checkbox_ID3_sync->setVisible(false); connect(this, SIGNAL(requestAddDir(QString)), m_pLibrary, SLOT(slotRequestAddDir(QString))); connect(this, SIGNAL(requestRemoveDir(QString, Library::RemovalType)), m_pLibrary, SLOT(slotRequestRemoveDir(QString, Library::RemovalType))); connect(this, SIGNAL(requestRelocateDir(QString,QString)), m_pLibrary, SLOT(slotRequestRelocateDir(QString,QString))); connect(PushButtonAddDir, SIGNAL(clicked()), this, SLOT(slotAddDir())); connect(PushButtonRemoveDir, SIGNAL(clicked()), this, SLOT(slotRemoveDir())); connect(PushButtonRelocateDir, SIGNAL(clicked()), this, SLOT(slotRelocateDir())); //connect(pushButtonM4A, SIGNAL(clicked()), this, SLOT(slotM4ACheck())); connect(pushButtonExtraPlugins, SIGNAL(clicked()), this, SLOT(slotExtraPlugins())); // plugins are loaded in src/main.cpp way early in boot so this is safe // here, doesn't need done at every slotUpdate QStringList plugins(SoundSourceProxy::supportedFileExtensionsByPlugins()); if (plugins.length() > 0) { pluginsLabel->setText(plugins.join(", ")); } // Set default direction as stored in config file int rowHeight = m_pLibrary->getTrackTableRowHeight(); spinBoxRowHeight->setValue(rowHeight); connect(spinBoxRowHeight, SIGNAL(valueChanged(int)), this, SLOT(slotRowHeightValueChanged(int))); connect(libraryFontButton, SIGNAL(clicked()), this, SLOT(slotSelectFont())); connect(this, SIGNAL(setTrackTableFont(QFont)), m_pLibrary, SLOT(slotSetTrackTableFont(QFont))); connect(this, SIGNAL(setTrackTableRowHeight(int)), m_pLibrary, SLOT(slotSetTrackTableRowHeight(int))); // TODO(XXX) this string should be extracted from the soundsources QString builtInFormatsStr = "Ogg Vorbis, FLAC, WAVe, AIFF"; #if defined(__MAD__) || defined(__APPLE__) builtInFormatsStr += ", MP3"; #endif #ifdef __OPUS__ builtInFormatsStr += ", Opus"; #endif #ifdef _MODPLUG_ builtInFormatsStr += ", ModPlug"; #endif builtInFormats->setText(builtInFormatsStr); } DlgPrefLibrary::~DlgPrefLibrary() { } void DlgPrefLibrary::slotShow() { m_baddedDirectory = false; } void DlgPrefLibrary::slotHide() { if (!m_baddedDirectory) { return; } QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("Music Directory Added")); msgBox.setText(tr("You added one or more music directories. The tracks in " "these directories won't be available until you rescan " "your library. Would you like to rescan now?")); QPushButton* scanButton = msgBox.addButton( tr("Scan"), QMessageBox::AcceptRole); msgBox.addButton(QMessageBox::Cancel); msgBox.setDefaultButton(scanButton); msgBox.exec(); if (msgBox.clickedButton() == scanButton) { emit(scanLibrary()); return; } } void DlgPrefLibrary::initialiseDirList() { // save which index was selected const QString selected = dirList->currentIndex().data().toString(); // clear and fill model m_dirListModel.clear(); QStringList dirs = m_pLibrary->getDirs(); foreach (QString dir, dirs) { m_dirListModel.appendRow(new QStandardItem(dir)); } dirList->setModel(&m_dirListModel); dirList->setCurrentIndex(m_dirListModel.index(0, 0)); // reselect index if it still exists for (int i=0 ; isetCurrentIndex(index); break; } } } void DlgPrefLibrary::slotExtraPlugins() { QDesktopServices::openUrl(QUrl(MIXXX_ADDONS_URL)); } void DlgPrefLibrary::slotResetToDefaults() { checkBox_library_scan->setChecked(false); checkbox_ID3_sync->setChecked(false); checkBox_use_relative_path->setChecked(false); checkBox_show_rhythmbox->setChecked(true); checkBox_show_banshee->setChecked(true); checkBox_show_itunes->setChecked(true); checkBox_show_traktor->setChecked(true); radioButton_dbclick_bottom->setChecked(false); radioButton_dbclick_top->setChecked(false); radioButton_dbclick_deck->setChecked(true); spinBoxRowHeight->setValue(Library::kDefaultRowHeightPx); setLibraryFont(QApplication::font()); } void DlgPrefLibrary::slotUpdate() { initialiseDirList(); checkBox_library_scan->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","RescanOnStartup")).toInt()); checkbox_ID3_sync->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","WriteAudioTags")).toInt()); checkBox_use_relative_path->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","UseRelativePathOnExport")).toInt()); checkBox_show_rhythmbox->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","ShowRhythmboxLibrary"),"1").toInt()); checkBox_show_banshee->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","ShowBansheeLibrary"),"1").toInt()); checkBox_show_itunes->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","ShowITunesLibrary"),"1").toInt()); checkBox_show_traktor->setChecked((bool)m_pconfig->getValueString( ConfigKey("[Library]","ShowTraktorLibrary"),"1").toInt()); switch (m_pconfig->getValueString(ConfigKey("[Library]","TrackLoadAction"), QString::number(LOAD_TRACK_DECK)).toInt()) { case ADD_TRACK_BOTTOM: radioButton_dbclick_bottom->setChecked(true); break; case ADD_TRACK_TOP: radioButton_dbclick_top->setChecked(true); break; default: radioButton_dbclick_deck->setChecked(true); break; } m_originalTrackTableFont = m_pLibrary->getTrackTableFont(); m_iOriginalTrackTableRowHeight = m_pLibrary->getTrackTableRowHeight(); spinBoxRowHeight->setValue(m_iOriginalTrackTableRowHeight); setLibraryFont(m_originalTrackTableFont); } void DlgPrefLibrary::slotCancel() { // Undo any changes in the library font or row height. emit(setTrackTableRowHeight(m_iOriginalTrackTableRowHeight)); emit(setTrackTableFont(m_originalTrackTableFont)); } void DlgPrefLibrary::slotAddDir() { QString fd = QFileDialog::getExistingDirectory( this, tr("Choose a music directory"), QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); if (!fd.isEmpty()) { emit(requestAddDir(fd)); slotUpdate(); m_baddedDirectory = true; } } void DlgPrefLibrary::slotRemoveDir() { QModelIndex index = dirList->currentIndex(); QString fd = index.data().toString(); QMessageBox removeMsgBox; removeMsgBox.setIcon(QMessageBox::Warning); removeMsgBox.setWindowTitle(tr("Confirm Directory Removal")); removeMsgBox.setText(tr( "Mixxx will no longer watch this directory for new tracks. " "What would you like to do with the tracks from this directory and " "subdirectories?" "
    " "
  • Hide all tracks from this directory and subdirectories.
  • " "
  • Delete all metadata for these tracks from Mixxx permanently.
  • " "
  • Leave the tracks unchanged in your library.
  • " "
" "Hiding tracks saves their metadata in case you re-add them in the " "future.")); removeMsgBox.setInformativeText(tr( "Metadata means all track details (artist, title, playcount, etc.) as " "well as beatgrids, hotcues, and loops. This choice only affects the " "Mixxx library. No files on disk will be changed or deleted.")); QPushButton* cancelButton = removeMsgBox.addButton(QMessageBox::Cancel); QPushButton* hideAllButton = removeMsgBox.addButton( tr("Hide Tracks"), QMessageBox::AcceptRole); QPushButton* deleteAllButton = removeMsgBox.addButton( tr("Delete Track Metadata"), QMessageBox::AcceptRole); QPushButton* leaveUnchangedButton = removeMsgBox.addButton( tr("Leave Tracks Unchanged"), QMessageBox::AcceptRole); removeMsgBox.setDefaultButton(cancelButton); removeMsgBox.exec(); if (removeMsgBox.clickedButton() == cancelButton) { return; } bool deleteAll = removeMsgBox.clickedButton() == deleteAllButton; bool hideAll = removeMsgBox.clickedButton() == hideAllButton; bool leaveUnchanged = removeMsgBox.clickedButton() == leaveUnchangedButton; Library::RemovalType removalType = Library::LeaveTracksUnchanged; if (leaveUnchanged) { removalType = Library::LeaveTracksUnchanged; } else if (deleteAll) { removalType = Library::PurgeTracks; } else if (hideAll) { removalType = Library::HideTracks; } emit(requestRemoveDir(fd, removalType)); slotUpdate(); } void DlgPrefLibrary::slotRelocateDir() { QModelIndex index = dirList->currentIndex(); QString currentFd = index.data().toString(); // If the selected directory exists, use it. If not, go up one directory (if // that directory exists). If neither exist, use the default music // directory. QString startDir = currentFd; QDir dir(startDir); if (!dir.exists() && dir.cdUp()) { startDir = dir.absolutePath(); } else if (!dir.exists()) { startDir = QDesktopServices::storageLocation( QDesktopServices::MusicLocation); } QString fd = QFileDialog::getExistingDirectory( this, tr("Relink music directory to new location"), startDir); if (!fd.isEmpty()) { emit(requestRelocateDir(currentFd, fd)); slotUpdate(); } } void DlgPrefLibrary::slotApply() { m_pconfig->set(ConfigKey("[Library]","RescanOnStartup"), ConfigValue((int)checkBox_library_scan->isChecked())); m_pconfig->set(ConfigKey("[Library]","WriteAudioTags"), ConfigValue((int)checkbox_ID3_sync->isChecked())); m_pconfig->set(ConfigKey("[Library]","UseRelativePathOnExport"), ConfigValue((int)checkBox_use_relative_path->isChecked())); m_pconfig->set(ConfigKey("[Library]","ShowRhythmboxLibrary"), ConfigValue((int)checkBox_show_rhythmbox->isChecked())); m_pconfig->set(ConfigKey("[Library]","ShowBansheeLibrary"), ConfigValue((int)checkBox_show_banshee->isChecked())); m_pconfig->set(ConfigKey("[Library]","ShowITunesLibrary"), ConfigValue((int)checkBox_show_itunes->isChecked())); m_pconfig->set(ConfigKey("[Library]","ShowTraktorLibrary"), ConfigValue((int)checkBox_show_traktor->isChecked())); int dbclick_status; if (radioButton_dbclick_bottom->isChecked()) { dbclick_status = ADD_TRACK_BOTTOM; } else if (radioButton_dbclick_top->isChecked()) { dbclick_status = ADD_TRACK_TOP; } else { dbclick_status = LOAD_TRACK_DECK; } m_pconfig->set(ConfigKey("[Library]","TrackLoadAction"), ConfigValue(dbclick_status)); QFont font = m_pLibrary->getTrackTableFont(); if (m_originalTrackTableFont != font) { m_pconfig->set(ConfigKey("[Library]", "Font"), ConfigValue(font.toString())); } int rowHeight = spinBoxRowHeight->value(); if (m_iOriginalTrackTableRowHeight != rowHeight) { m_pconfig->set(ConfigKey("[Library]","RowHeight"), ConfigValue(rowHeight)); } // TODO(rryan): Don't save here. m_pconfig->Save(); } void DlgPrefLibrary::slotRowHeightValueChanged(int height) { emit(setTrackTableRowHeight(height)); } void DlgPrefLibrary::setLibraryFont(const QFont& font) { libraryFont->setText(QString("%1 %2 %3pt").arg( font.family(), font.styleName(), QString::number(font.pointSizeF()))); emit(setTrackTableFont(font)); // Don't let the row height exceed the library height. QFontMetrics metrics(font); int fontHeight = metrics.height(); if (fontHeight > spinBoxRowHeight->value()) { spinBoxRowHeight->setValue(fontHeight); } spinBoxRowHeight->setMinimum(fontHeight); } void DlgPrefLibrary::slotSelectFont() { // False if the user cancels font selection. bool ok = false; QFont font = QFontDialog::getFont(&ok, m_pLibrary->getTrackTableFont(), this, tr("Select Library Font")); if (ok) { setLibraryFont(font); } }