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 <kstandarddirs.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.
51 TQString SoundPicker::i18n_Sound() { return i18n("An audio sound", "Sound"); }
52 TQString SoundPicker::i18n_None() { return i18n("None"); }
53 TQString SoundPicker::i18n_Beep() { return i18n("Beep"); }
54 TQString SoundPicker::i18n_Speak() { return i18n("Speak"); }
55 TQString SoundPicker::i18n_File() { return i18n("Sound file"); }
56 
57 
58 SoundPicker::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 */
98 void 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 */
110 void 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 */
136 SoundPicker::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 */
145 TQString 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 */
154 float 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 */
174 bool SoundPicker::repeat() const
175 {
176  return mTypeCombo->currentItem() == PLAY_FILE && !mFile.isEmpty() && mRepeat;
177 }
178 
179 /******************************************************************************
180 * Initialise the widget's state.
181 */
182 void 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 */
203 void 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 */
231 void 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 */
276 TQString 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