kalarm

soundpicker.cpp
1/*
2 * soundpicker.cpp - widget to select a sound file or a beep
3 * Program: kalarm
4 * Copyright © 2002,2004-2007 by David Jarvie <software@astrojar.org.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include "kalarm.h"
22
23#include <tqlayout.h>
24#include <tqregexp.h>
25#include <tqtooltip.h>
26#include <tqtimer.h>
27#include <tqlabel.h>
28#include <tqhbox.h>
29#include <tqwhatsthis.h>
30
31#include <tdeglobal.h>
32#include <tdelocale.h>
33#include <tdefiledialog.h>
34#include <tdestandarddirs.h>
35#include <kiconloader.h>
36#ifndef WITHOUT_ARTS
37#include <arts/kplayobjectfactory.h>
38#endif
39#include <kdebug.h>
40
41#include "combobox.h"
42#include "functions.h"
43#include "kalarmapp.h"
44#include "pushbutton.h"
45#include "sounddlg.h"
46#include "soundpicker.moc"
47
48
49// Collect these widget labels together to ensure consistent wording and
50// translations across different modules.
51TQString SoundPicker::i18n_Sound() { return i18n("An audio sound", "Sound"); }
52TQString SoundPicker::i18n_None() { return i18n("None"); }
53TQString SoundPicker::i18n_Beep() { return i18n("Beep"); }
54TQString SoundPicker::i18n_Speak() { return i18n("Speak"); }
55TQString SoundPicker::i18n_File() { return i18n("Sound file"); }
56
57
58SoundPicker::SoundPicker(TQWidget* parent, const char* name)
59 : TQFrame(parent, name)
60{
61 setFrameStyle(TQFrame::NoFrame);
62 TQHBoxLayout* soundLayout = new TQHBoxLayout(this, 0, KDialog::spacingHint());
63 mTypeBox = new TQHBox(this); // this is to control the TQWhatsThis text display area
64 mTypeBox->setSpacing(KDialog::spacingHint());
65
66 TQLabel* label = new TQLabel(i18n("An audio sound", "&Sound:"), mTypeBox);
67 label->setFixedSize(label->sizeHint());
68
69 // Sound type combo box
70 // The order of combo box entries must correspond with the 'Type' enum.
71 mTypeCombo = new ComboBox(false, mTypeBox);
72 mTypeCombo->insertItem(i18n_None()); // index NONE
73 mTypeCombo->insertItem(i18n_Beep()); // index BEEP
74 mTypeCombo->insertItem(i18n_File()); // index PLAY_FILE
75 mSpeakShowing = !theApp()->speechEnabled();
76 showSpeak(!mSpeakShowing); // index SPEAK (only displayed if appropriate)
77 connect(mTypeCombo, TQ_SIGNAL(activated(int)), TQ_SLOT(slotTypeSelected(int)));
78 label->setBuddy(mTypeCombo);
79 soundLayout->addWidget(mTypeBox);
80
81 // Sound file picker button
82 mFilePicker = new PushButton(this);
83 mFilePicker->setPixmap(SmallIcon("playsound"));
84 mFilePicker->setFixedSize(mFilePicker->sizeHint());
85 connect(mFilePicker, TQ_SIGNAL(clicked()), TQ_SLOT(slotPickFile()));
86 TQToolTip::add(mFilePicker, i18n("Configure sound file"));
87 TQWhatsThis::add(mFilePicker, i18n("Configure a sound file to play when the alarm is displayed."));
88 soundLayout->addWidget(mFilePicker);
89
90 // Initialise the file picker button state and tooltip
91 mTypeCombo->setCurrentItem(NONE);
92 mFilePicker->setEnabled(false);
93}
94
95/******************************************************************************
96* Set the read-only status of the widget.
97*/
98void SoundPicker::setReadOnly(bool readOnly)
99{
100 mTypeCombo->setReadOnly(readOnly);
101#ifdef WITHOUT_ARTS
102 mFilePicker->setReadOnly(readOnly);
103#endif
104 mReadOnly = readOnly;
105}
106
107/******************************************************************************
108* Show or hide the Speak option.
109*/
110void SoundPicker::showSpeak(bool show)
111{
112 if (!theApp()->speechEnabled())
113 show = false; // speech capability is not installed
114 if (show == mSpeakShowing)
115 return; // no change
116 TQString whatsThis = "<p>" + i18n("Choose a sound to play when the message is displayed.")
117 + "<br>" + i18n("%1: the message is displayed silently.").arg("<b>" + i18n_None() + "</b>")
118 + "<br>" + i18n("%1: a simple beep is sounded.").arg("<b>" + i18n_Beep() + "</b>")
119 + "<br>" + i18n("%1: an audio file is played. You will be prompted to choose the file and set play options.").arg("<b>" + i18n_File() + "</b>");
120 if (!show && mTypeCombo->currentItem() == SPEAK)
121 mTypeCombo->setCurrentItem(NONE);
122 if (mTypeCombo->count() == SPEAK+1)
123 mTypeCombo->removeItem(SPEAK); // precaution in case of mix-ups
124 if (show)
125 {
126 mTypeCombo->insertItem(i18n_Speak());
127 whatsThis += "<br>" + i18n("%1: the message text is spoken.").arg("<b>" + i18n_Speak() + "</b>") + "</p>";
128 }
129 TQWhatsThis::add(mTypeBox, whatsThis + "</p>");
130 mSpeakShowing = show;
131}
132
133/******************************************************************************
134* Return the currently selected option.
135*/
136SoundPicker::Type SoundPicker::sound() const
137{
138 return static_cast<SoundPicker::Type>(mTypeCombo->currentItem());
139}
140
141/******************************************************************************
142* Return the selected sound file, if the File option is selected.
143* Returns null string if File is not currently selected.
144*/
145TQString SoundPicker::file() const
146{
147 return (mTypeCombo->currentItem() == PLAY_FILE) ? mFile : TQString();
148}
149
150/******************************************************************************
151* Return the specified volumes (range 0 - 1).
152* Returns < 0 if beep is currently selected, or if 'set volume' is not selected.
153*/
154float SoundPicker::volume(float& fadeVolume, int& fadeSeconds) const
155{
156 if (mTypeCombo->currentItem() == PLAY_FILE && !mFile.isEmpty())
157 {
158 fadeVolume = mFadeVolume;
159 fadeSeconds = mFadeSeconds;
160 return mVolume;
161 }
162 else
163 {
164 fadeVolume = -1;
165 fadeSeconds = 0;
166 return -1;
167 }
168}
169
170/******************************************************************************
171* Return whether sound file repetition is selected, if the main checkbox is checked.
172* Returns false if beep is currently selected.
173*/
174bool SoundPicker::repeat() const
175{
176 return mTypeCombo->currentItem() == PLAY_FILE && !mFile.isEmpty() && mRepeat;
177}
178
179/******************************************************************************
180* Initialise the widget's state.
181*/
182void SoundPicker::set(SoundPicker::Type type, const TQString& f, float volume, float fadeVolume, int fadeSeconds, bool repeat)
183{
184 if (type == PLAY_FILE && f.isEmpty())
185 type = BEEP;
186 mFile = f;
187 mVolume = volume;
188 mFadeVolume = fadeVolume;
189 mFadeSeconds = fadeSeconds;
190 mRepeat = repeat;
191 mTypeCombo->setCurrentItem(type); // this doesn't trigger slotTypeSelected()
192 mFilePicker->setEnabled(type == PLAY_FILE);
193 if (type == PLAY_FILE)
194 TQToolTip::add(mTypeCombo, mFile);
195 else
196 TQToolTip::remove(mTypeCombo);
197 mLastType = type;
198}
199
200/******************************************************************************
201* Called when the sound option is changed.
202*/
203void SoundPicker::slotTypeSelected(int id)
204{
205 Type newType = static_cast<Type>(id);
206 if (newType == mLastType)
207 return;
208 TQString tooltip;
209 if (mLastType == PLAY_FILE)
210 {
211 mFilePicker->setEnabled(false);
212 TQToolTip::remove(mTypeCombo);
213 }
214 else if (newType == PLAY_FILE)
215 {
216 if (mFile.isEmpty())
217 {
218 slotPickFile();
219 if (mFile.isEmpty())
220 return; // revert to previously selected type
221 }
222 mFilePicker->setEnabled(true);
223 TQToolTip::add(mTypeCombo, mFile);
224 }
225 mLastType = newType;
226}
227
228/******************************************************************************
229* Called when the file picker button is clicked.
230*/
231void SoundPicker::slotPickFile()
232{
233#ifdef WITHOUT_ARTS
234 TQString url = browseFile(mDefaultDir, mFile);
235 if (!url.isEmpty())
236 mFile = url;
237#else
238 TQString file = mFile;
239 SoundDlg dlg(mFile, mVolume, mFadeVolume, mFadeSeconds, mRepeat, i18n("Sound File"), this, "soundDlg");
240 dlg.setReadOnly(mReadOnly);
241 bool accepted = (dlg.exec() == TQDialog::Accepted);
242 if (mReadOnly)
243 return;
244 if (accepted)
245 {
246 float volume, fadeVolume;
247 int fadeTime;
248 file = dlg.getFile();
249 mRepeat = dlg.getSettings(volume, fadeVolume, fadeTime);
250 mVolume = volume;
251 mFadeVolume = fadeVolume;
252 mFadeSeconds = fadeTime;
253 }
254 if (!file.isEmpty())
255 {
256 mFile = file;
257 mDefaultDir = dlg.defaultDir();
258 }
259#endif
260 if (mFile.isEmpty())
261 {
262 // No audio file is selected, so revert to previously selected option
263 mTypeCombo->setCurrentItem(mLastType);
264 TQToolTip::remove(mTypeCombo);
265 }
266 else
267 TQToolTip::add(mTypeCombo, mFile);
268}
269
270/******************************************************************************
271* Display a dialogue to choose a sound file, initially highlighting any
272* specified file. 'initialFile' must be a full path name or URL.
273* 'defaultDir' is updated to the directory containing the chosen file.
274* Reply = URL selected. If none is selected, URL.isEmpty() is true.
275*/
276TQString SoundPicker::browseFile(TQString& defaultDir, const TQString& initialFile)
277{
278 static TQString kdeSoundDir; // directory containing KDE sound files
279 if (defaultDir.isEmpty())
280 {
281 if (kdeSoundDir.isNull())
282 kdeSoundDir = TDEGlobal::dirs()->findResourceDir("sound", "KDE_Notify.wav");
283 defaultDir = kdeSoundDir;
284 }
285#ifdef WITHOUT_ARTS
286 TQString filter = TQString::fromLatin1("*.wav *.mp3 *.ogg|%1\n*|%2").arg(i18n("Sound Files")).arg(i18n("All Files"));
287#else
288 TQStringList filters = KDE::PlayObjectFactory::mimeTypes();
289 TQString filter = filters.join(" ");
290#endif
291 return KAlarm::browseFile(i18n("Choose Sound File"), defaultDir, initialFile, filter, KFile::ExistingOnly, 0, "pickSoundFile");
292}
miscellaneous functions
the KAlarm application object