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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1509 - (show annotations) (download)
Thu Nov 22 11:10:44 2007 UTC (16 years, 4 months ago) by capela
File size: 11098 byte(s)
* Audio routing table is initially hidden in the dialog, when
  creating a new sampler channel.

* README requirements and configuration notes update.

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 m_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(m_ui.MapComboBox,
64 SIGNAL(activated(int)),
65 SLOT(changed()));
66 QObject::connect(m_ui.BankSpinBox,
67 SIGNAL(valueChanged(int)),
68 SLOT(changed()));
69 QObject::connect(m_ui.ProgSpinBox,
70 SIGNAL(valueChanged(int)),
71 SLOT(changed()));
72 QObject::connect(m_ui.NameLineEdit,
73 SIGNAL(textChanged(const QString&)),
74 SLOT(nameChanged(const QString&)));
75 QObject::connect(m_ui.EngineNameComboBox,
76 SIGNAL(activated(int)),
77 SLOT(changed()));
78 QObject::connect(m_ui.InstrumentFileComboBox,
79 SIGNAL(activated(const QString&)),
80 SLOT(updateInstrumentName()));
81 QObject::connect(m_ui.InstrumentFileToolButton,
82 SIGNAL(clicked()),
83 SLOT(openInstrumentFile()));
84 QObject::connect(m_ui.InstrumentNrComboBox,
85 SIGNAL(activated(int)),
86 SLOT(instrumentNrChanged()));
87 QObject::connect(m_ui.VolumeSpinBox,
88 SIGNAL(valueChanged(int)),
89 SLOT(changed()));
90 QObject::connect(m_ui.LoadModeComboBox,
91 SIGNAL(activated(int)),
92 SLOT(changed()));
93 QObject::connect(m_ui.OkPushButton,
94 SIGNAL(clicked()),
95 SLOT(accept()));
96 QObject::connect(m_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(m_ui.InstrumentFileComboBox);
142
143 // Populate maps list.
144 m_ui.MapComboBox->clear();
145 m_ui.MapComboBox->insertItems(0, qsamplerInstrument::getMapNames());
146
147 // Populate Engines list.
148 const char **ppszEngines
149 = ::lscp_list_available_engines(pMainForm->client());
150 if (ppszEngines) {
151 m_ui.EngineNameComboBox->clear();
152 for (int iEngine = 0; ppszEngines[iEngine]; iEngine++)
153 m_ui.EngineNameComboBox->addItem(ppszEngines[iEngine]);
154 }
155 else pMainForm->appendMessagesClient("lscp_list_available_engines");
156
157 // Read proper instrument information,
158 // and populate the instrument form fields.
159
160 // Instrument map name...
161 int iMap = (bNew ? pOptions->iMidiMap : m_pInstrument->map());
162 if (iMap < 0)
163 iMap = 0;
164 const QString& sMapName = qsamplerInstrument::getMapName(iMap);
165 if (!sMapName.isEmpty()) {
166 m_ui.MapComboBox->setItemText(
167 m_ui.MapComboBox->currentIndex(),
168 sMapName);
169 }
170 // It might be no maps around...
171 bool bMapEnabled = (m_ui.MapComboBox->count() > 0);
172 m_ui.MapTextLabel->setEnabled(bMapEnabled);
173 m_ui.MapComboBox->setEnabled(bMapEnabled);
174
175 // Instrument bank/program...
176 int iBank = (bNew ? pOptions->iMidiBank : m_pInstrument->bank());
177 int iProg = (bNew ? pOptions->iMidiProg : m_pInstrument->prog()) + 1;
178 if (bNew && iProg > 128) {
179 iProg = 1;
180 iBank++;
181 }
182 m_ui.BankSpinBox->setValue(iBank);
183 m_ui.ProgSpinBox->setValue(iProg);
184
185 // Instrument name...
186 m_ui.NameLineEdit->setText(m_pInstrument->name());
187
188 // Engine name...
189 QString sEngineName = m_pInstrument->engineName();
190 if (sEngineName.isEmpty() || bNew)
191 sEngineName = pOptions->sEngineName;
192 if (sEngineName.isEmpty())
193 sEngineName = qsamplerChannel::noEngineName();
194 if (m_ui.EngineNameComboBox->findText(sEngineName,
195 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
196 m_ui.EngineNameComboBox->addItem(sEngineName);
197 }
198 m_ui.EngineNameComboBox->setCurrentIndex(
199 m_ui.EngineNameComboBox->findText(sEngineName,
200 Qt::MatchExactly | Qt::MatchCaseSensitive));
201
202 // Instrument filename and index...
203 QString sInstrumentFile = m_pInstrument->instrumentFile();
204 if (sInstrumentFile.isEmpty())
205 sInstrumentFile = qsamplerChannel::noInstrumentName();
206 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
207 m_ui.InstrumentNrComboBox->clear();
208 m_ui.InstrumentNrComboBox->insertItems(0,
209 qsamplerChannel::getInstrumentList(sInstrumentFile,
210 pOptions->bInstrumentNames));
211 m_ui.InstrumentNrComboBox->setCurrentIndex(m_pInstrument->instrumentNr());
212
213 // Instrument volume....
214 int iVolume = (bNew ? pOptions->iVolume :
215 ::lroundf(100.0f * m_pInstrument->volume()));
216 m_ui.VolumeSpinBox->setValue(iVolume);
217
218 // Instrument load mode...
219 int iLoadMode = (bNew ? pOptions->iLoadMode :
220 m_pInstrument->loadMode());
221 m_ui.LoadModeComboBox->setCurrentIndex(iLoadMode);
222
223 // Done.
224 m_iDirtySetup--;
225 stabilizeForm();
226
227 // Done.
228 m_iDirtySetup--;
229 stabilizeForm();
230 }
231
232
233 // Special case for name change,
234 void InstrumentForm::nameChanged ( const QString& /* sName */ )
235 {
236 if (m_iDirtySetup > 0)
237 return;
238
239 m_iDirtyName++;
240 changed();
241 }
242
243
244 // Browse and open an instrument file.
245 void InstrumentForm::openInstrumentFile (void)
246 {
247 MainForm* pMainForm = MainForm::getInstance();
248 if (pMainForm == NULL)
249 return;
250
251 qsamplerOptions *pOptions = pMainForm->options();
252 if (pOptions == NULL)
253 return;
254
255 // FIXME: the instrument file filters should be restricted,
256 // depending on the current engine.
257 QString sInstrumentFile = QFileDialog::getOpenFileName(this,
258 QSAMPLER_TITLE ": " + tr("Instrument files"), // Caption.
259 pOptions->sInstrumentDir, // Start here.
260 tr("Instrument files") + " (*.gig *.dls)" // Filter (GIG and DLS files)
261 );
262
263 if (sInstrumentFile.isEmpty())
264 return;
265
266 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
267 updateInstrumentName();
268 }
269
270
271 // Refresh the actual instrument name.
272 void InstrumentForm::updateInstrumentName (void)
273 {
274 MainForm* pMainForm = MainForm::getInstance();
275 if (pMainForm == NULL)
276 return;
277
278 qsamplerOptions *pOptions = pMainForm->options();
279 if (pOptions == NULL)
280 return;
281
282 // TODO: this better idea would be to use libgig
283 // to retrieve the REAL instrument names.
284 m_ui.InstrumentNrComboBox->clear();
285 m_ui.InstrumentNrComboBox->insertItems(0,
286 qsamplerChannel::getInstrumentList(
287 m_ui.InstrumentFileComboBox->currentText(),
288 pOptions->bInstrumentNames)
289 );
290
291 instrumentNrChanged();
292 }
293
294
295 // Special case for instrumnet index change,
296 void InstrumentForm::instrumentNrChanged (void)
297 {
298 if (m_iDirtySetup > 0)
299 return;
300
301 if (m_ui.NameLineEdit->text().isEmpty() || m_iDirtyName == 0) {
302 m_ui.NameLineEdit->setText(m_ui.InstrumentNrComboBox->currentText());
303 m_iDirtyName = 0;
304 }
305
306 changed();
307 }
308
309
310 // Accept settings (OK button slot).
311 void InstrumentForm::accept (void)
312 {
313 if (m_pInstrument == NULL)
314 return;
315
316 MainForm* pMainForm = MainForm::getInstance();
317 if (pMainForm == NULL)
318 return;
319 if (pMainForm->client() == NULL)
320 return;
321
322 qsamplerOptions *pOptions = pMainForm->options();
323 if (pOptions == NULL)
324 return;
325
326 if (m_iDirtyCount > 0) {
327 m_pInstrument->setMap(m_ui.MapComboBox->currentIndex());
328 m_pInstrument->setBank(m_ui.BankSpinBox->value());
329 m_pInstrument->setProg(m_ui.ProgSpinBox->value() - 1);
330 m_pInstrument->setName(m_ui.NameLineEdit->text());
331 m_pInstrument->setEngineName(m_ui.EngineNameComboBox->currentText());
332 m_pInstrument->setInstrumentFile(m_ui.InstrumentFileComboBox->currentText());
333 m_pInstrument->setInstrumentNr(m_ui.InstrumentNrComboBox->currentIndex());
334 m_pInstrument->setVolume(0.01f * float(m_ui.VolumeSpinBox->value()));
335 m_pInstrument->setLoadMode(m_ui.LoadModeComboBox->currentIndex());
336 }
337
338 // Save default engine name, instrument directory and history...
339 pOptions->sInstrumentDir = QFileInfo(
340 m_ui.InstrumentFileComboBox->currentText()).dir().absolutePath();
341 pOptions->sEngineName = m_ui.EngineNameComboBox->currentText();
342 pOptions->iMidiMap = m_ui.MapComboBox->currentIndex();
343 pOptions->iMidiBank = m_ui.BankSpinBox->value();
344 pOptions->iMidiProg = m_ui.ProgSpinBox->value();
345 pOptions->iVolume = m_ui.VolumeSpinBox->value();
346 pOptions->iLoadMode = m_ui.LoadModeComboBox->currentIndex();
347 pOptions->saveComboBoxHistory(m_ui.InstrumentFileComboBox);
348
349 // Just go with dialog acceptance.
350 QDialog::accept();
351 }
352
353
354 // Reject settings (Cancel button slot).
355 void InstrumentForm::reject (void)
356 {
357 bool bReject = true;
358
359 // Check if there's any pending changes...
360 if (m_iDirtyCount > 0 && m_ui.OkPushButton->isEnabled()) {
361 switch (QMessageBox::warning(this,
362 QSAMPLER_TITLE ": " + tr("Warning"),
363 tr("Some channel settings have been changed.\n\n"
364 "Do you want to apply the changes?"),
365 tr("Apply"), tr("Discard"), tr("Cancel"))) {
366 case 0: // Apply...
367 accept();
368 return;
369 case 1: // Discard
370 break;
371 default: // Cancel.
372 bReject = false;
373 break;
374 }
375 }
376
377 if (bReject)
378 QDialog::reject();
379 }
380
381
382 // Dirty up settings.
383 void InstrumentForm::changed (void)
384 {
385 if (m_iDirtySetup > 0)
386 return;
387
388 m_iDirtyCount++;
389 stabilizeForm();
390 }
391
392
393 // Stabilize current form state.
394 void InstrumentForm::stabilizeForm (void)
395 {
396 bool bValid =
397 !m_ui.NameLineEdit->text().isEmpty() &&
398 m_ui.EngineNameComboBox->currentIndex() >= 0 &&
399 m_ui.EngineNameComboBox->currentText() !=
400 qsamplerChannel::noEngineName();
401
402 const QString& sPath = m_ui.InstrumentFileComboBox->currentText();
403 bValid = bValid && !sPath.isEmpty() && QFileInfo(sPath).exists();
404
405 m_ui.OkPushButton->setEnabled(m_iDirtyCount > 0 && bValid);
406 }
407
408 } // namespace QSampler
409
410
411 // end of qsamplerInstrumentForm.cpp

  ViewVC Help
Powered by ViewVC