/[svn]/qsampler/trunk/src/qsamplerInstrumentForm.cpp
ViewVC logotype

Contents of /qsampler/trunk/src/qsamplerInstrumentForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1506 - (show annotations) (download)
Wed Nov 21 19:57:18 2007 UTC (12 years, 7 months ago) by schoenebeck
File size: 10967 byte(s)
* Disable OK button in sampler channel form and MIDI instrument
  form if no valid engine is selected (to avoid bothering newbie
  users with confusing LSCP syntax errors when using the UI the
  first time).
* Replaced Debian packaging dependency from libqt3-mt-dev to
  libqr4-dev.

1 // qsamplerInstrumentForm.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2003-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2007, Christian Schoenebeck
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 *****************************************************************************/
22
23 #include "qsamplerInstrumentForm.h"
24
25 #include "qsamplerAbout.h"
26 #include "qsamplerMainForm.h"
27
28 #include <QFileDialog>
29 #include <QMessageBox>
30
31 // Needed for lroundf()
32 #include <math.h>
33
34
35 namespace QSampler {
36
37 #ifndef CONFIG_ROUND
38 static inline long lroundf ( float x )
39 {
40 if (x >= 0.0f)
41 return long(x + 0.5f);
42 else
43 return long(x - 0.5f);
44 }
45 #endif
46
47 InstrumentForm::InstrumentForm ( QWidget* pParent )
48 : QDialog(pParent)
49 {
50 ui.setupUi(this);
51
52 // Initialize locals.
53 m_pInstrument = NULL;
54
55 m_iDirtySetup = 0;
56 m_iDirtyCount = 0;
57 m_iDirtyName = 0;
58
59 // Try to restore normal window positioning.
60 adjustSize();
61
62
63 QObject::connect(ui.MapComboBox,
64 SIGNAL(activated(int)),
65 SLOT(changed()));
66 QObject::connect(ui.BankSpinBox,
67 SIGNAL(valueChanged(int)),
68 SLOT(changed()));
69 QObject::connect(ui.ProgSpinBox,
70 SIGNAL(valueChanged(int)),
71 SLOT(changed()));
72 QObject::connect(ui.NameLineEdit,
73 SIGNAL(textChanged(const QString&)),
74 SLOT(nameChanged(const QString&)));
75 QObject::connect(ui.EngineNameComboBox,
76 SIGNAL(activated(int)),
77 SLOT(changed()));
78 QObject::connect(ui.InstrumentFileComboBox,
79 SIGNAL(activated(const QString&)),
80 SLOT(updateInstrumentName()));
81 QObject::connect(ui.InstrumentFileToolButton,
82 SIGNAL(clicked()),
83 SLOT(openInstrumentFile()));
84 QObject::connect(ui.InstrumentNrComboBox,
85 SIGNAL(activated(int)),
86 SLOT(instrumentNrChanged()));
87 QObject::connect(ui.VolumeSpinBox,
88 SIGNAL(valueChanged(int)),
89 SLOT(changed()));
90 QObject::connect(ui.LoadModeComboBox,
91 SIGNAL(activated(int)),
92 SLOT(changed()));
93 QObject::connect(ui.OkPushButton,
94 SIGNAL(clicked()),
95 SLOT(accept()));
96 QObject::connect(ui.CancelPushButton,
97 SIGNAL(clicked()),
98 SLOT(reject()));
99 }
100
101
102 InstrumentForm::~InstrumentForm (void)
103 {
104 }
105
106
107 // Channel dialog setup formal initializer.
108 void InstrumentForm::setup ( qsamplerInstrument *pInstrument )
109 {
110 m_pInstrument = pInstrument;
111
112 m_iDirtySetup = 0;
113 m_iDirtyCount = 0;
114 m_iDirtyName = 0;
115
116 if (m_pInstrument == NULL)
117 return;
118
119 // Check if we're up and connected.
120 MainForm* pMainForm = MainForm::getInstance();
121 if (pMainForm == NULL)
122 return;
123 if (pMainForm->client() == NULL)
124 return;
125
126 qsamplerOptions *pOptions = pMainForm->options();
127 if (pOptions == NULL)
128 return;
129
130 // It can be a brand new channel, remember?
131 bool bNew = (m_pInstrument->bank() < 0 || m_pInstrument->prog() < 0);
132 if (!bNew) {
133 m_pInstrument->getInstrument();
134 m_iDirtyName++;
135 }
136
137 // Avoid nested changes.
138 m_iDirtySetup++;
139
140 // Load combo box history...
141 pOptions->loadComboBoxHistory(ui.InstrumentFileComboBox);
142
143 // Populate maps list.
144 ui.MapComboBox->clear();
145 ui.MapComboBox->insertItems(0, qsamplerInstrument::getMapNames());
146
147 // Populate Engines list.
148 const char **ppszEngines = ::lscp_list_available_engines(pMainForm->client());
149 if (ppszEngines) {
150 ui.EngineNameComboBox->clear();
151 for (int iEngine = 0; ppszEngines[iEngine]; iEngine++)
152 ui.EngineNameComboBox->addItem(ppszEngines[iEngine]);
153 }
154 else pMainForm->appendMessagesClient("lscp_list_available_engines");
155
156 // Read proper instrument information,
157 // and populate the instrument form fields.
158
159 // Instrument map name...
160 int iMap = (bNew ? pOptions->iMidiMap : m_pInstrument->map());
161 if (iMap < 0)
162 iMap = 0;
163 const QString& sMapName = qsamplerInstrument::getMapName(iMap);
164 if (!sMapName.isEmpty()) {
165 ui.MapComboBox->setItemText(
166 ui.MapComboBox->currentIndex(),
167 sMapName);
168 }
169 // It might be no maps around...
170 bool bMapEnabled = (ui.MapComboBox->count() > 0);
171 ui.MapTextLabel->setEnabled(bMapEnabled);
172 ui.MapComboBox->setEnabled(bMapEnabled);
173
174 // Instrument bank/program...
175 int iBank = (bNew ? pOptions->iMidiBank : m_pInstrument->bank());
176 int iProg = (bNew ? pOptions->iMidiProg : m_pInstrument->prog()) + 1;
177 if (bNew && iProg > 128) {
178 iProg = 1;
179 iBank++;
180 }
181 ui.BankSpinBox->setValue(iBank);
182 ui.ProgSpinBox->setValue(iProg);
183
184 // Instrument name...
185 ui.NameLineEdit->setText(m_pInstrument->name());
186
187 // Engine name...
188 QString sEngineName = m_pInstrument->engineName();
189 if (sEngineName.isEmpty() || bNew)
190 sEngineName = pOptions->sEngineName;
191 if (sEngineName.isEmpty())
192 sEngineName = qsamplerChannel::noEngineName();
193 if (ui.EngineNameComboBox->findText(sEngineName,
194 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
195 ui.EngineNameComboBox->addItem(sEngineName);
196 }
197 ui.EngineNameComboBox->setCurrentIndex(
198 ui.EngineNameComboBox->findText(sEngineName,
199 Qt::MatchExactly | Qt::MatchCaseSensitive));
200
201 // Instrument filename and index...
202 QString sInstrumentFile = m_pInstrument->instrumentFile();
203 if (sInstrumentFile.isEmpty())
204 sInstrumentFile = qsamplerChannel::noInstrumentName();
205 ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
206 ui.InstrumentNrComboBox->clear();
207 ui.InstrumentNrComboBox->insertItems(0,
208 qsamplerChannel::getInstrumentList(sInstrumentFile,
209 pOptions->bInstrumentNames));
210 ui.InstrumentNrComboBox->setCurrentIndex(m_pInstrument->instrumentNr());
211
212 // Instrument volume....
213 int iVolume = (bNew ? pOptions->iVolume :
214 ::lroundf(100.0f * m_pInstrument->volume()));
215 ui.VolumeSpinBox->setValue(iVolume);
216
217 // Instrument load mode...
218 int iLoadMode = (bNew ? pOptions->iLoadMode :
219 m_pInstrument->loadMode());
220 ui.LoadModeComboBox->setCurrentIndex(iLoadMode);
221
222 // Done.
223 m_iDirtySetup--;
224 stabilizeForm();
225
226 // Done.
227 m_iDirtySetup--;
228 stabilizeForm();
229 }
230
231
232 // Special case for name change,
233 void InstrumentForm::nameChanged ( const QString& /* sName */ )
234 {
235 if (m_iDirtySetup > 0)
236 return;
237
238 m_iDirtyName++;
239 changed();
240 }
241
242
243 // Browse and open an instrument file.
244 void InstrumentForm::openInstrumentFile (void)
245 {
246 MainForm* pMainForm = MainForm::getInstance();
247 if (pMainForm == NULL)
248 return;
249
250 qsamplerOptions *pOptions = pMainForm->options();
251 if (pOptions == NULL)
252 return;
253
254 // FIXME: the instrument file filters should be restricted,
255 // depending on the current engine.
256 QString sInstrumentFile = QFileDialog::getOpenFileName(this,
257 QSAMPLER_TITLE ": " + tr("Instrument files"), // Caption.
258 pOptions->sInstrumentDir, // Start here.
259 tr("Instrument files") + " (*.gig *.dls)" // Filter (GIG and DLS files)
260 );
261
262 if (sInstrumentFile.isEmpty())
263 return;
264
265 ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
266 updateInstrumentName();
267 }
268
269
270 // Refresh the actual instrument name.
271 void InstrumentForm::updateInstrumentName (void)
272 {
273 MainForm* pMainForm = MainForm::getInstance();
274 if (pMainForm == NULL)
275 return;
276
277 qsamplerOptions *pOptions = pMainForm->options();
278 if (pOptions == NULL)
279 return;
280
281 // TODO: this better idea would be to use libgig
282 // to retrieve the REAL instrument names.
283 ui.InstrumentNrComboBox->clear();
284 ui.InstrumentNrComboBox->insertItems(0,
285 qsamplerChannel::getInstrumentList(
286 ui.InstrumentFileComboBox->currentText(),
287 pOptions->bInstrumentNames)
288 );
289
290 instrumentNrChanged();
291 }
292
293
294 // Special case for instrumnet index change,
295 void InstrumentForm::instrumentNrChanged (void)
296 {
297 if (m_iDirtySetup > 0)
298 return;
299
300 if (ui.NameLineEdit->text().isEmpty() || m_iDirtyName == 0) {
301 ui.NameLineEdit->setText(ui.InstrumentNrComboBox->currentText());
302 m_iDirtyName = 0;
303 }
304
305 changed();
306 }
307
308
309 // Accept settings (OK button slot).
310 void InstrumentForm::accept (void)
311 {
312 if (m_pInstrument == NULL)
313 return;
314
315 MainForm* pMainForm = MainForm::getInstance();
316 if (pMainForm == NULL)
317 return;
318 if (pMainForm->client() == NULL)
319 return;
320
321 qsamplerOptions *pOptions = pMainForm->options();
322 if (pOptions == NULL)
323 return;
324
325 if (m_iDirtyCount > 0) {
326 m_pInstrument->setMap(ui.MapComboBox->currentIndex());
327 m_pInstrument->setBank(ui.BankSpinBox->value());
328 m_pInstrument->setProg(ui.ProgSpinBox->value() - 1);
329 m_pInstrument->setName(ui.NameLineEdit->text());
330 m_pInstrument->setEngineName(ui.EngineNameComboBox->currentText());
331 m_pInstrument->setInstrumentFile(ui.InstrumentFileComboBox->currentText());
332 m_pInstrument->setInstrumentNr(ui.InstrumentNrComboBox->currentIndex());
333 m_pInstrument->setVolume(0.01f * float(ui.VolumeSpinBox->value()));
334 m_pInstrument->setLoadMode(ui.LoadModeComboBox->currentIndex());
335 }
336
337 // Save default engine name, instrument directory and history...
338 pOptions->sInstrumentDir = QFileInfo(
339 ui.InstrumentFileComboBox->currentText()).dir().absolutePath();
340 pOptions->sEngineName = ui.EngineNameComboBox->currentText();
341 pOptions->iMidiMap = ui.MapComboBox->currentIndex();
342 pOptions->iMidiBank = ui.BankSpinBox->value();
343 pOptions->iMidiProg = ui.ProgSpinBox->value();
344 pOptions->iVolume = ui.VolumeSpinBox->value();
345 pOptions->iLoadMode = ui.LoadModeComboBox->currentIndex();
346 pOptions->saveComboBoxHistory(ui.InstrumentFileComboBox);
347
348 // Just go with dialog acceptance.
349 QDialog::accept();
350 }
351
352
353 // Reject settings (Cancel button slot).
354 void InstrumentForm::reject (void)
355 {
356 bool bReject = true;
357
358 // Check if there's any pending changes...
359 if (m_iDirtyCount > 0 && ui.OkPushButton->isEnabled()) {
360 switch (QMessageBox::warning(this,
361 QSAMPLER_TITLE ": " + tr("Warning"),
362 tr("Some channel settings have been changed.\n\n"
363 "Do you want to apply the changes?"),
364 tr("Apply"), tr("Discard"), tr("Cancel"))) {
365 case 0: // Apply...
366 accept();
367 return;
368 case 1: // Discard
369 break;
370 default: // Cancel.
371 bReject = false;
372 break;
373 }
374 }
375
376 if (bReject)
377 QDialog::reject();
378 }
379
380
381 // Dirty up settings.
382 void InstrumentForm::changed (void)
383 {
384 if (m_iDirtySetup > 0)
385 return;
386
387 m_iDirtyCount++;
388 stabilizeForm();
389 }
390
391
392 // Stabilize current form state.
393 void InstrumentForm::stabilizeForm (void)
394 {
395 bool bValid =
396 !ui.NameLineEdit->text().isEmpty() &&
397 ui.EngineNameComboBox->currentIndex() >= 0 &&
398 ui.EngineNameComboBox->currentText() !=
399 qsamplerChannel::noEngineName();
400
401 const QString& sPath = ui.InstrumentFileComboBox->currentText();
402 bValid = bValid && !sPath.isEmpty() && QFileInfo(sPath).exists();
403
404 ui.OkPushButton->setEnabled(m_iDirtyCount > 0 && bValid);
405 }
406
407 } // namespace QSampler
408
409
410 // end of qsamplerInstrumentForm.cpp

  ViewVC Help
Powered by ViewVC