kalarm

sounddlg.cpp

00001 /*
00002  *  sounddlg.cpp  -  sound file selection and configuration dialog
00003  *  Program:  kalarm
00004  *  Copyright © 2005,2007 by David Jarvie <software@astrojar.org.uk>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #ifndef WITHOUT_ARTS
00022 
00023 #include "kalarm.h"
00024 
00025 #include <qlabel.h>
00026 #include <qhbox.h>
00027 #include <qgroupbox.h>
00028 #include <qlayout.h>
00029 #include <qfile.h>
00030 #include <qdir.h>
00031 #include <qwhatsthis.h>
00032 #include <qtooltip.h>
00033 
00034 #include <klocale.h>
00035 #include <kstandarddirs.h>
00036 #include <kiconloader.h>
00037 #include <kaudioplayer.h>
00038 #include <kmessagebox.h>
00039 #include <kio/netaccess.h>
00040 #include <kdebug.h>
00041 
00042 #include "checkbox.h"
00043 #include "functions.h"
00044 #include "lineedit.h"
00045 #include "pushbutton.h"
00046 #include "slider.h"
00047 #include "soundpicker.h"
00048 #include "spinbox.h"
00049 #include "sounddlg.moc"
00050 
00051 
00052 // Collect these widget labels together to ensure consistent wording and
00053 // translations across different modules.
00054 QString SoundDlg::i18n_SetVolume()   { return i18n("Set volume"); }
00055 QString SoundDlg::i18n_v_SetVolume() { return i18n("Set &volume"); }
00056 QString SoundDlg::i18n_Repeat()      { return i18n("Repeat"); }
00057 QString SoundDlg::i18n_p_Repeat()    { return i18n("Re&peat"); }
00058 
00059 static const char SOUND_DIALOG_NAME[] = "SoundDialog";
00060 
00061 
00062 SoundDlg::SoundDlg(const QString& file, float volume, float fadeVolume, int fadeSeconds, bool repeat,
00063                    const QString& caption, QWidget* parent, const char* name)
00064     : KDialogBase(parent, name, true, caption, Ok|Cancel, Ok, false),
00065       mReadOnly(false)
00066 {
00067     QWidget* page = new QWidget(this);
00068     setMainWidget(page);
00069     QVBoxLayout* layout = new QVBoxLayout(page, 0, spacingHint());
00070 
00071     // File play button
00072     QHBox* box = new QHBox(page);
00073     layout->addWidget(box);
00074     mFilePlay = new QPushButton(box);
00075     mFilePlay->setPixmap(SmallIcon("player_play"));
00076     mFilePlay->setFixedSize(mFilePlay->sizeHint());
00077     connect(mFilePlay, SIGNAL(clicked()), SLOT(playSound()));
00078     QToolTip::add(mFilePlay, i18n("Test the sound"));
00079     QWhatsThis::add(mFilePlay, i18n("Play the selected sound file."));
00080 
00081     // File name edit box
00082     mFileEdit = new LineEdit(LineEdit::Url, box);
00083     mFileEdit->setAcceptDrops(true);
00084     QWhatsThis::add(mFileEdit, i18n("Enter the name or URL of a sound file to play."));
00085 
00086     // File browse button
00087     mFileBrowseButton = new PushButton(box);
00088     mFileBrowseButton->setPixmap(SmallIcon("fileopen"));
00089     mFileBrowseButton->setFixedSize(mFileBrowseButton->sizeHint());
00090     connect(mFileBrowseButton, SIGNAL(clicked()), SLOT(slotPickFile()));
00091     QToolTip::add(mFileBrowseButton, i18n("Choose a file"));
00092     QWhatsThis::add(mFileBrowseButton, i18n("Select a sound file to play."));
00093 
00094     // Sound repetition checkbox
00095     mRepeatCheckbox = new CheckBox(i18n_p_Repeat(), page);
00096     mRepeatCheckbox->setFixedSize(mRepeatCheckbox->sizeHint());
00097     QWhatsThis::add(mRepeatCheckbox,
00098           i18n("If checked, the sound file will be played repeatedly for as long as the message is displayed."));
00099     layout->addWidget(mRepeatCheckbox);
00100 
00101     // Volume
00102     QGroupBox* group = new QGroupBox(i18n("Volume"), page);
00103     layout->addWidget(group);
00104     QGridLayout* grid = new QGridLayout(group, 4, 3, marginHint(), spacingHint());
00105     grid->addRowSpacing(0, fontMetrics().lineSpacing()/2);
00106     grid->setColStretch(2, 1);
00107     int indentWidth = 3 * KDialog::spacingHint();
00108     grid->addColSpacing(0, indentWidth);
00109     grid->addColSpacing(1, indentWidth);
00110     // Get alignment to use in QGridLayout (AlignAuto doesn't work correctly there)
00111     int alignment = QApplication::reverseLayout() ? Qt::AlignRight : Qt::AlignLeft;
00112 
00113     // 'Set volume' checkbox
00114     box = new QHBox(group);
00115     box->setSpacing(spacingHint());
00116     grid->addMultiCellWidget(box, 1, 1, 0, 2);
00117     mVolumeCheckbox = new CheckBox(i18n_v_SetVolume(), box);
00118     mVolumeCheckbox->setFixedSize(mVolumeCheckbox->sizeHint());
00119     connect(mVolumeCheckbox, SIGNAL(toggled(bool)), SLOT(slotVolumeToggled(bool)));
00120     QWhatsThis::add(mVolumeCheckbox,
00121           i18n("Select to choose the volume for playing the sound file."));
00122 
00123     // Volume slider
00124     mVolumeSlider = new Slider(0, 100, 10, 0, Qt::Horizontal, box);
00125     mVolumeSlider->setTickmarks(QSlider::Below);
00126     mVolumeSlider->setTickInterval(10);
00127     mVolumeSlider->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
00128     QWhatsThis::add(mVolumeSlider, i18n("Choose the volume for playing the sound file."));
00129     mVolumeCheckbox->setFocusWidget(mVolumeSlider);
00130 
00131     // Fade checkbox
00132     mFadeCheckbox = new CheckBox(i18n("Fade"), group);
00133     mFadeCheckbox->setFixedSize(mFadeCheckbox->sizeHint());
00134     connect(mFadeCheckbox, SIGNAL(toggled(bool)), SLOT(slotFadeToggled(bool)));
00135     QWhatsThis::add(mFadeCheckbox,
00136           i18n("Select to fade the volume when the sound file first starts to play."));
00137     grid->addMultiCellWidget(mFadeCheckbox, 2, 2, 1, 2, alignment);
00138 
00139     // Fade time
00140     mFadeBox = new QHBox(group);
00141     mFadeBox->setSpacing(spacingHint());
00142     grid->addWidget(mFadeBox, 3, 2, alignment);
00143     QLabel* label = new QLabel(i18n("Time period over which to fade the sound", "Fade time:"), mFadeBox);
00144     label->setFixedSize(label->sizeHint());
00145     mFadeTime = new SpinBox(1, 999, 1, mFadeBox);
00146     mFadeTime->setLineShiftStep(10);
00147     mFadeTime->setFixedSize(mFadeTime->sizeHint());
00148     label->setBuddy(mFadeTime);
00149     label = new QLabel(i18n("seconds"), mFadeBox);
00150     label->setFixedSize(label->sizeHint());
00151     QWhatsThis::add(mFadeBox, i18n("Enter how many seconds to fade the sound before reaching the set volume."));
00152 
00153     // Fade slider
00154     mFadeVolumeBox = new QHBox(group);
00155     mFadeVolumeBox->setSpacing(spacingHint());
00156     grid->addWidget(mFadeVolumeBox, 4, 2);
00157     label = new QLabel(i18n("Initial volume:"), mFadeVolumeBox);
00158     label->setFixedSize(label->sizeHint());
00159     mFadeSlider = new Slider(0, 100, 10, 0, Qt::Horizontal, mFadeVolumeBox);
00160     mFadeSlider->setTickmarks(QSlider::Below);
00161     mFadeSlider->setTickInterval(10);
00162     mFadeSlider->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
00163     label->setBuddy(mFadeSlider);
00164     QWhatsThis::add(mFadeVolumeBox, i18n("Choose the initial volume for playing the sound file."));
00165 
00166     // Restore the dialogue size from last time
00167     QSize s;
00168     if (KAlarm::readConfigWindowSize(SOUND_DIALOG_NAME, s))
00169         resize(s);
00170 
00171     // Initialise the control values
00172     mFileEdit->setText(file);
00173     mRepeatCheckbox->setChecked(repeat);
00174     mVolumeCheckbox->setChecked(volume >= 0);
00175     mVolumeSlider->setValue(volume >= 0 ? static_cast<int>(volume*100) : 100);
00176     mFadeCheckbox->setChecked(fadeVolume >= 0);
00177     mFadeSlider->setValue(fadeVolume >= 0 ? static_cast<int>(fadeVolume*100) : 100);
00178     mFadeTime->setValue(fadeSeconds);
00179     slotVolumeToggled(volume >= 0);
00180 }
00181 
00182 /******************************************************************************
00183 * Set the read-only status of the dialogue.
00184 */
00185 void SoundDlg::setReadOnly(bool readOnly)
00186 {
00187     if (readOnly != mReadOnly)
00188     {
00189         mFileEdit->setReadOnly(readOnly);
00190         mFileBrowseButton->setReadOnly(readOnly);
00191         mRepeatCheckbox->setReadOnly(readOnly);
00192         mVolumeCheckbox->setReadOnly(readOnly);
00193         mVolumeSlider->setReadOnly(readOnly);
00194         mFadeCheckbox->setReadOnly(readOnly);
00195         mFadeTime->setReadOnly(readOnly);
00196         mFadeSlider->setReadOnly(readOnly);
00197         mReadOnly = readOnly;
00198     }
00199 }
00200 
00201 /******************************************************************************
00202 * Return the entered repetition and volume settings:
00203 * 'volume' is in range 0 - 1, or < 0 if volume is not to be set.
00204 * 'fadeVolume is similar, with 'fadeTime' set to the fade interval in seconds.
00205 * Reply = whether to repeat or not.
00206 */
00207 bool SoundDlg::getSettings(float& volume, float& fadeVolume, int& fadeSeconds) const
00208 {
00209     volume = mVolumeCheckbox->isChecked() ? (float)mVolumeSlider->value() / 100 : -1;
00210     if (mFadeCheckbox->isChecked())
00211     {
00212         fadeVolume  = (float)mFadeSlider->value() / 100;
00213         fadeSeconds = mFadeTime->value();
00214     }
00215     else
00216     {
00217         fadeVolume  = -1;
00218         fadeSeconds = 0;
00219     }
00220     return mRepeatCheckbox->isChecked();
00221 }
00222 
00223 /******************************************************************************
00224 *  Called when the dialog's size has changed.
00225 *  Records the new size in the config file.
00226 */
00227 void SoundDlg::resizeEvent(QResizeEvent* re)
00228 {
00229     if (isVisible())
00230         KAlarm::writeConfigWindowSize(SOUND_DIALOG_NAME, re->size());
00231     mVolumeSlider->resize(mFadeSlider->size());
00232     KDialog::resizeEvent(re);
00233 }
00234 
00235 void SoundDlg::showEvent(QShowEvent* se)
00236 {
00237     mVolumeSlider->resize(mFadeSlider->size());
00238     KDialog::showEvent(se);
00239 }
00240 
00241 /******************************************************************************
00242 *  Called when the OK button is clicked.
00243 */
00244 void SoundDlg::slotOk()
00245 {
00246     if (mReadOnly)
00247         reject();
00248     if (!checkFile())
00249         return;
00250     accept();
00251 }
00252 
00253 /******************************************************************************
00254 * Called when the file browser button is clicked.
00255 */
00256 void SoundDlg::slotPickFile()
00257 {
00258     QString url = SoundPicker::browseFile(mDefaultDir, mFileEdit->text());
00259     if (!url.isEmpty())
00260         mFileEdit->setText(url);
00261 }
00262 
00263 /******************************************************************************
00264 * Called when the file play button is clicked.
00265 */
00266 void SoundDlg::playSound()
00267 {
00268     if (checkFile())
00269         KAudioPlayer::play(QFile::encodeName(mFileName));
00270 }
00271 
00272 /******************************************************************************
00273 * Check whether the specified sound file exists.
00274 * Note that KAudioPlayer::play() can only cope with local files.
00275 */
00276 bool SoundDlg::checkFile()
00277 {
00278     QString file = mFileEdit->text();
00279     KURL url;
00280     if (KURL::isRelativeURL(file))
00281     {
00282         // It's not an absolute URL, so check for an absolute path
00283         QFileInfo f(file);
00284         if (!f.isRelative())
00285             url.setPath(file);
00286     }
00287     else
00288         url = KURL::fromPathOrURL(file);   // it's an absolute URL
00289     if (!url.isEmpty())
00290     {
00291         // It's an absolute path or URL.
00292         // Only allow local files for KAudioPlayer.
00293         if (url.isLocalFile()  &&  KIO::NetAccess::exists(url, true, this))
00294         {
00295             mFileName = url.path();
00296             return true;
00297         }
00298     }
00299     else
00300     {
00301         // It's a relative path.
00302         // Find the first sound resource that contains files.
00303         QStringList soundDirs = KGlobal::dirs()->resourceDirs("sound");
00304         if (!soundDirs.isEmpty())
00305         {
00306             QDir dir;
00307             dir.setFilter(QDir::Files | QDir::Readable);
00308             for (QStringList::ConstIterator it = soundDirs.begin();  it != soundDirs.end();  ++it)
00309             {
00310                 dir = *it;
00311                 if (dir.isReadable() && dir.count() > 2)
00312                 {
00313                     url.setPath(*it);
00314                     url.addPath(file);
00315                     if (KIO::NetAccess::exists(url, true, this))
00316                     {
00317                         mFileName = url.path();
00318                         return true;
00319                     }
00320                 }
00321             }
00322         }
00323         url.setPath(QDir::homeDirPath());
00324         url.addPath(file);
00325         if (KIO::NetAccess::exists(url, true, this))
00326         {
00327             mFileName = url.path();
00328             return true;
00329         }
00330     }
00331     KMessageBox::sorry(this, i18n("File not found"));
00332     mFileName = QString::null;
00333     return false;
00334 }
00335 
00336 /******************************************************************************
00337 * Called when the Set Volume checkbox is toggled.
00338 */
00339 void SoundDlg::slotVolumeToggled(bool on)
00340 {
00341     mVolumeSlider->setEnabled(on);
00342     mFadeCheckbox->setEnabled(on);
00343     slotFadeToggled(on  &&  mFadeCheckbox->isChecked());
00344 }
00345 
00346 /******************************************************************************
00347 * Called when the Fade checkbox is toggled.
00348 */
00349 void SoundDlg::slotFadeToggled(bool on)
00350 {
00351     mFadeBox->setEnabled(on);
00352     mFadeVolumeBox->setEnabled(on);
00353 }
00354 
00355 #endif // #ifndef WITHOUT_ARTS
KDE Home | KDE Accessibility Home | Description of Access Keys