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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1509 - (hide annotations) (download)
Thu Nov 22 11:10:44 2007 UTC (16 years, 5 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 capela 1464 // 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 schoenebeck 1461 #include "qsamplerInstrumentForm.h"
24    
25     #include "qsamplerAbout.h"
26     #include "qsamplerMainForm.h"
27    
28 capela 1499 #include <QFileDialog>
29     #include <QMessageBox>
30    
31 schoenebeck 1461 // Needed for lroundf()
32     #include <math.h>
33    
34 capela 1499
35 schoenebeck 1461 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 capela 1504 InstrumentForm::InstrumentForm ( QWidget* pParent )
48     : QDialog(pParent)
49     {
50 capela 1509 m_ui.setupUi(this);
51 schoenebeck 1461
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 capela 1466
62    
63 capela 1509 QObject::connect(m_ui.MapComboBox,
64 capela 1466 SIGNAL(activated(int)),
65     SLOT(changed()));
66 capela 1509 QObject::connect(m_ui.BankSpinBox,
67 capela 1466 SIGNAL(valueChanged(int)),
68     SLOT(changed()));
69 capela 1509 QObject::connect(m_ui.ProgSpinBox,
70 capela 1466 SIGNAL(valueChanged(int)),
71     SLOT(changed()));
72 capela 1509 QObject::connect(m_ui.NameLineEdit,
73 schoenebeck 1474 SIGNAL(textChanged(const QString&)),
74     SLOT(nameChanged(const QString&)));
75 capela 1509 QObject::connect(m_ui.EngineNameComboBox,
76 capela 1466 SIGNAL(activated(int)),
77     SLOT(changed()));
78 capela 1509 QObject::connect(m_ui.InstrumentFileComboBox,
79 schoenebeck 1474 SIGNAL(activated(const QString&)),
80 capela 1466 SLOT(updateInstrumentName()));
81 capela 1509 QObject::connect(m_ui.InstrumentFileToolButton,
82 capela 1466 SIGNAL(clicked()),
83     SLOT(openInstrumentFile()));
84 capela 1509 QObject::connect(m_ui.InstrumentNrComboBox,
85 capela 1466 SIGNAL(activated(int)),
86     SLOT(instrumentNrChanged()));
87 capela 1509 QObject::connect(m_ui.VolumeSpinBox,
88 capela 1466 SIGNAL(valueChanged(int)),
89     SLOT(changed()));
90 capela 1509 QObject::connect(m_ui.LoadModeComboBox,
91 capela 1466 SIGNAL(activated(int)),
92     SLOT(changed()));
93 capela 1509 QObject::connect(m_ui.OkPushButton,
94 capela 1466 SIGNAL(clicked()),
95     SLOT(accept()));
96 capela 1509 QObject::connect(m_ui.CancelPushButton,
97 capela 1466 SIGNAL(clicked()),
98     SLOT(reject()));
99 schoenebeck 1461 }
100    
101 capela 1504
102     InstrumentForm::~InstrumentForm (void)
103     {
104 schoenebeck 1461 }
105    
106 capela 1504
107 schoenebeck 1461 // 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 capela 1509 pOptions->loadComboBoxHistory(m_ui.InstrumentFileComboBox);
142 schoenebeck 1461
143     // Populate maps list.
144 capela 1509 m_ui.MapComboBox->clear();
145     m_ui.MapComboBox->insertItems(0, qsamplerInstrument::getMapNames());
146 schoenebeck 1461
147     // Populate Engines list.
148 capela 1509 const char **ppszEngines
149     = ::lscp_list_available_engines(pMainForm->client());
150 schoenebeck 1461 if (ppszEngines) {
151 capela 1509 m_ui.EngineNameComboBox->clear();
152 schoenebeck 1461 for (int iEngine = 0; ppszEngines[iEngine]; iEngine++)
153 capela 1509 m_ui.EngineNameComboBox->addItem(ppszEngines[iEngine]);
154 schoenebeck 1461 }
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 capela 1499 if (!sMapName.isEmpty()) {
166 capela 1509 m_ui.MapComboBox->setItemText(
167     m_ui.MapComboBox->currentIndex(),
168 capela 1499 sMapName);
169     }
170 schoenebeck 1461 // It might be no maps around...
171 capela 1509 bool bMapEnabled = (m_ui.MapComboBox->count() > 0);
172     m_ui.MapTextLabel->setEnabled(bMapEnabled);
173     m_ui.MapComboBox->setEnabled(bMapEnabled);
174 schoenebeck 1461
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 capela 1509 m_ui.BankSpinBox->setValue(iBank);
183     m_ui.ProgSpinBox->setValue(iProg);
184 schoenebeck 1461
185     // Instrument name...
186 capela 1509 m_ui.NameLineEdit->setText(m_pInstrument->name());
187 schoenebeck 1461
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 capela 1509 if (m_ui.EngineNameComboBox->findText(sEngineName,
195 schoenebeck 1474 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
196 capela 1509 m_ui.EngineNameComboBox->addItem(sEngineName);
197 schoenebeck 1461 }
198 capela 1509 m_ui.EngineNameComboBox->setCurrentIndex(
199     m_ui.EngineNameComboBox->findText(sEngineName,
200 capela 1504 Qt::MatchExactly | Qt::MatchCaseSensitive));
201    
202 schoenebeck 1461 // Instrument filename and index...
203     QString sInstrumentFile = m_pInstrument->instrumentFile();
204     if (sInstrumentFile.isEmpty())
205     sInstrumentFile = qsamplerChannel::noInstrumentName();
206 capela 1509 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
207     m_ui.InstrumentNrComboBox->clear();
208     m_ui.InstrumentNrComboBox->insertItems(0,
209 schoenebeck 1461 qsamplerChannel::getInstrumentList(sInstrumentFile,
210     pOptions->bInstrumentNames));
211 capela 1509 m_ui.InstrumentNrComboBox->setCurrentIndex(m_pInstrument->instrumentNr());
212 schoenebeck 1461
213     // Instrument volume....
214     int iVolume = (bNew ? pOptions->iVolume :
215     ::lroundf(100.0f * m_pInstrument->volume()));
216 capela 1509 m_ui.VolumeSpinBox->setValue(iVolume);
217 schoenebeck 1461
218     // Instrument load mode...
219     int iLoadMode = (bNew ? pOptions->iLoadMode :
220     m_pInstrument->loadMode());
221 capela 1509 m_ui.LoadModeComboBox->setCurrentIndex(iLoadMode);
222 schoenebeck 1461
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 capela 1499 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 schoenebeck 1461 );
262    
263     if (sInstrumentFile.isEmpty())
264     return;
265    
266 capela 1509 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
267 schoenebeck 1461 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 capela 1509 m_ui.InstrumentNrComboBox->clear();
285     m_ui.InstrumentNrComboBox->insertItems(0,
286 schoenebeck 1461 qsamplerChannel::getInstrumentList(
287 capela 1509 m_ui.InstrumentFileComboBox->currentText(),
288 schoenebeck 1461 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 capela 1509 if (m_ui.NameLineEdit->text().isEmpty() || m_iDirtyName == 0) {
302     m_ui.NameLineEdit->setText(m_ui.InstrumentNrComboBox->currentText());
303 schoenebeck 1461 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 capela 1509 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 schoenebeck 1461 }
337    
338     // Save default engine name, instrument directory and history...
339 capela 1499 pOptions->sInstrumentDir = QFileInfo(
340 capela 1509 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 schoenebeck 1461
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 capela 1509 if (m_iDirtyCount > 0 && m_ui.OkPushButton->isEnabled()) {
361 schoenebeck 1461 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 schoenebeck 1506 bool bValid =
397 capela 1509 !m_ui.NameLineEdit->text().isEmpty() &&
398     m_ui.EngineNameComboBox->currentIndex() >= 0 &&
399     m_ui.EngineNameComboBox->currentText() !=
400 schoenebeck 1506 qsamplerChannel::noEngineName();
401 schoenebeck 1461
402 capela 1509 const QString& sPath = m_ui.InstrumentFileComboBox->currentText();
403 schoenebeck 1461 bValid = bValid && !sPath.isEmpty() && QFileInfo(sPath).exists();
404    
405 capela 1509 m_ui.OkPushButton->setEnabled(m_iDirtyCount > 0 && bValid);
406 schoenebeck 1461 }
407    
408     } // namespace QSampler
409 capela 1464
410    
411     // end of qsamplerInstrumentForm.cpp

  ViewVC Help
Powered by ViewVC