/* * soundpicker.cpp - widget to select a sound file or a beep * Program: kalarm * Copyright © 2002,2004-2007 by David Jarvie * * 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. * * This program 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, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kalarm.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifndef WITHOUT_ARTS #include #endif #include #include "combobox.h" #include "functions.h" #include "kalarmapp.h" #include "pushbutton.h" #include "sounddlg.h" #include "soundpicker.moc" // Collect these widget labels together to ensure consistent wording and // translations across different modules. TQString SoundPicker::i18n_Sound() { return i18n("An audio sound", "Sound"); } TQString SoundPicker::i18n_None() { return i18n("None"); } TQString SoundPicker::i18n_Beep() { return i18n("Beep"); } TQString SoundPicker::i18n_Speak() { return i18n("Speak"); } TQString SoundPicker::i18n_File() { return i18n("Sound file"); } SoundPicker::SoundPicker(TQWidget* parent, const char* name) : TQFrame(parent, name) { setFrameStyle(TQFrame::NoFrame); TQHBoxLayout* soundLayout = new TQHBoxLayout(this, 0, KDialog::spacingHint()); mTypeBox = new TQHBox(this); // this is to control the TQWhatsThis text display area mTypeBox->setSpacing(KDialog::spacingHint()); TQLabel* label = new TQLabel(i18n("An audio sound", "&Sound:"), mTypeBox); label->setFixedSize(label->sizeHint()); // Sound type combo box // The order of combo box entries must correspond with the 'Type' enum. mTypeCombo = new ComboBox(false, mTypeBox); mTypeCombo->insertItem(i18n_None()); // index NONE mTypeCombo->insertItem(i18n_Beep()); // index BEEP mTypeCombo->insertItem(i18n_File()); // index PLAY_FILE mSpeakShowing = !theApp()->speechEnabled(); showSpeak(!mSpeakShowing); // index SPEAK (only displayed if appropriate) connect(mTypeCombo, TQT_SIGNAL(activated(int)), TQT_SLOT(slotTypeSelected(int))); label->setBuddy(mTypeCombo); soundLayout->addWidget(mTypeBox); // Sound file picker button mFilePicker = new PushButton(this); mFilePicker->setPixmap(SmallIcon("playsound")); mFilePicker->setFixedSize(mFilePicker->sizeHint()); connect(mFilePicker, TQT_SIGNAL(clicked()), TQT_SLOT(slotPickFile())); TQToolTip::add(mFilePicker, i18n("Configure sound file")); TQWhatsThis::add(mFilePicker, i18n("Configure a sound file to play when the alarm is displayed.")); soundLayout->addWidget(mFilePicker); // Initialise the file picker button state and tooltip mTypeCombo->setCurrentItem(NONE); mFilePicker->setEnabled(false); } /****************************************************************************** * Set the read-only status of the widget. */ void SoundPicker::setReadOnly(bool readOnly) { mTypeCombo->setReadOnly(readOnly); #ifdef WITHOUT_ARTS mFilePicker->setReadOnly(readOnly); #endif mReadOnly = readOnly; } /****************************************************************************** * Show or hide the Speak option. */ void SoundPicker::showSpeak(bool show) { if (!theApp()->speechEnabled()) show = false; // speech capability is not installed if (show == mSpeakShowing) return; // no change TQString whatsThis = "

" + i18n("Choose a sound to play when the message is displayed.") + "
" + i18n("%1: the message is displayed silently.").arg("" + i18n_None() + "") + "
" + i18n("%1: a simple beep is sounded.").arg("" + i18n_Beep() + "") + "
" + i18n("%1: an audio file is played. You will be prompted to choose the file and set play options.").arg("" + i18n_File() + ""); if (!show && mTypeCombo->currentItem() == SPEAK) mTypeCombo->setCurrentItem(NONE); if (mTypeCombo->count() == SPEAK+1) mTypeCombo->removeItem(SPEAK); // precaution in case of mix-ups if (show) { mTypeCombo->insertItem(i18n_Speak()); whatsThis += "
" + i18n("%1: the message text is spoken.").arg("" + i18n_Speak() + "") + "

"; } TQWhatsThis::add(mTypeBox, whatsThis + "

"); mSpeakShowing = show; } /****************************************************************************** * Return the currently selected option. */ SoundPicker::Type SoundPicker::sound() const { return static_cast(mTypeCombo->currentItem()); } /****************************************************************************** * Return the selected sound file, if the File option is selected. * Returns null string if File is not currently selected. */ TQString SoundPicker::file() const { return (mTypeCombo->currentItem() == PLAY_FILE) ? mFile : TQString(); } /****************************************************************************** * Return the specified volumes (range 0 - 1). * Returns < 0 if beep is currently selected, or if 'set volume' is not selected. */ float SoundPicker::volume(float& fadeVolume, int& fadeSeconds) const { if (mTypeCombo->currentItem() == PLAY_FILE && !mFile.isEmpty()) { fadeVolume = mFadeVolume; fadeSeconds = mFadeSeconds; return mVolume; } else { fadeVolume = -1; fadeSeconds = 0; return -1; } } /****************************************************************************** * Return whether sound file repetition is selected, if the main checkbox is checked. * Returns false if beep is currently selected. */ bool SoundPicker::repeat() const { return mTypeCombo->currentItem() == PLAY_FILE && !mFile.isEmpty() && mRepeat; } /****************************************************************************** * Initialise the widget's state. */ void SoundPicker::set(SoundPicker::Type type, const TQString& f, float volume, float fadeVolume, int fadeSeconds, bool repeat) { if (type == PLAY_FILE && f.isEmpty()) type = BEEP; mFile = f; mVolume = volume; mFadeVolume = fadeVolume; mFadeSeconds = fadeSeconds; mRepeat = repeat; mTypeCombo->setCurrentItem(type); // this doesn't trigger slotTypeSelected() mFilePicker->setEnabled(type == PLAY_FILE); if (type == PLAY_FILE) TQToolTip::add(mTypeCombo, mFile); else TQToolTip::remove(mTypeCombo); mLastType = type; } /****************************************************************************** * Called when the sound option is changed. */ void SoundPicker::slotTypeSelected(int id) { Type newType = static_cast(id); if (newType == mLastType) return; TQString tooltip; if (mLastType == PLAY_FILE) { mFilePicker->setEnabled(false); TQToolTip::remove(mTypeCombo); } else if (newType == PLAY_FILE) { if (mFile.isEmpty()) { slotPickFile(); if (mFile.isEmpty()) return; // revert to previously selected type } mFilePicker->setEnabled(true); TQToolTip::add(mTypeCombo, mFile); } mLastType = newType; } /****************************************************************************** * Called when the file picker button is clicked. */ void SoundPicker::slotPickFile() { #ifdef WITHOUT_ARTS TQString url = browseFile(mDefaultDir, mFile); if (!url.isEmpty()) mFile = url; #else TQString file = mFile; SoundDlg dlg(mFile, mVolume, mFadeVolume, mFadeSeconds, mRepeat, i18n("Sound File"), this, "soundDlg"); dlg.setReadOnly(mReadOnly); bool accepted = (dlg.exec() == TQDialog::Accepted); if (mReadOnly) return; if (accepted) { float volume, fadeVolume; int fadeTime; file = dlg.getFile(); mRepeat = dlg.getSettings(volume, fadeVolume, fadeTime); mVolume = volume; mFadeVolume = fadeVolume; mFadeSeconds = fadeTime; } if (!file.isEmpty()) { mFile = file; mDefaultDir = dlg.defaultDir(); } #endif if (mFile.isEmpty()) { // No audio file is selected, so revert to previously selected option mTypeCombo->setCurrentItem(mLastType); TQToolTip::remove(mTypeCombo); } else TQToolTip::add(mTypeCombo, mFile); } /****************************************************************************** * Display a dialogue to choose a sound file, initially highlighting any * specified file. 'initialFile' must be a full path name or URL. * 'defaultDir' is updated to the directory containing the chosen file. * Reply = URL selected. If none is selected, URL.isEmpty() is true. */ TQString SoundPicker::browseFile(TQString& defaultDir, const TQString& initialFile) { static TQString kdeSoundDir; // directory containing KDE sound files if (defaultDir.isEmpty()) { if (kdeSoundDir.isNull()) kdeSoundDir = TDEGlobal::dirs()->findResourceDir("sound", "KDE_Notify.wav"); defaultDir = kdeSoundDir; } #ifdef WITHOUT_ARTS TQString filter = TQString::fromLatin1("*.wav *.mp3 *.ogg|%1\n*|%2").arg(i18n("Sound Files")).arg(i18n("All Files")); #else TQStringList filters = KDE::PlayObjectFactory::mimeTypes(); TQString filter = filters.join(" "); #endif return KAlarm::browseFile(i18n("Choose Sound File"), defaultDir, initialFile, filter, KFile::ExistingOnly, 0, "pickSoundFile"); }