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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3555 - (hide annotations) (download)
Tue Aug 13 10:19:32 2019 UTC (4 years, 7 months ago) by capela
File size: 11678 byte(s)
- In late compliance to C++11, all NULL constants replaced for nullptr.
1 capela 1464 // qsamplerInstrumentForm.cpp
2     //
3     /****************************************************************************
4 capela 3555 Copyright (C) 2003-2019, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 1464 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 capela 1513 #include "qsamplerAbout.h"
24 schoenebeck 1461 #include "qsamplerInstrumentForm.h"
25    
26 capela 1513 #include "qsamplerOptions.h"
27     #include "qsamplerChannel.h"
28 schoenebeck 1461 #include "qsamplerMainForm.h"
29    
30 capela 2107 #include <QMessageBox>
31     #include <QPushButton>
32 capela 1499 #include <QFileDialog>
33    
34 schoenebeck 1461 // Needed for lroundf()
35     #include <math.h>
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 1514
48     namespace QSampler {
49    
50 capela 1558 //-------------------------------------------------------------------------
51     // QSampler::InstrumentForm -- Instrument map item form implementation.
52     //
53    
54 capela 2069 InstrumentForm::InstrumentForm ( QWidget *pParent )
55 capela 1504 : QDialog(pParent)
56     {
57 capela 1509 m_ui.setupUi(this);
58 schoenebeck 1461
59     // Initialize locals.
60 capela 3555 m_pInstrument = nullptr;
61 schoenebeck 1461
62     m_iDirtySetup = 0;
63     m_iDirtyCount = 0;
64     m_iDirtyName = 0;
65    
66     // Try to restore normal window positioning.
67     adjustSize();
68 capela 1466
69    
70 capela 1509 QObject::connect(m_ui.MapComboBox,
71 capela 1466 SIGNAL(activated(int)),
72     SLOT(changed()));
73 capela 1509 QObject::connect(m_ui.BankSpinBox,
74 capela 1466 SIGNAL(valueChanged(int)),
75     SLOT(changed()));
76 capela 1509 QObject::connect(m_ui.ProgSpinBox,
77 capela 1466 SIGNAL(valueChanged(int)),
78     SLOT(changed()));
79 capela 1509 QObject::connect(m_ui.NameLineEdit,
80 schoenebeck 1474 SIGNAL(textChanged(const QString&)),
81     SLOT(nameChanged(const QString&)));
82 capela 1509 QObject::connect(m_ui.EngineNameComboBox,
83 capela 1466 SIGNAL(activated(int)),
84     SLOT(changed()));
85 capela 1509 QObject::connect(m_ui.InstrumentFileComboBox,
86 schoenebeck 1474 SIGNAL(activated(const QString&)),
87 capela 1466 SLOT(updateInstrumentName()));
88 capela 1509 QObject::connect(m_ui.InstrumentFileToolButton,
89 capela 1466 SIGNAL(clicked()),
90     SLOT(openInstrumentFile()));
91 capela 1509 QObject::connect(m_ui.InstrumentNrComboBox,
92 capela 1466 SIGNAL(activated(int)),
93     SLOT(instrumentNrChanged()));
94 capela 1509 QObject::connect(m_ui.VolumeSpinBox,
95 capela 1466 SIGNAL(valueChanged(int)),
96     SLOT(changed()));
97 capela 1509 QObject::connect(m_ui.LoadModeComboBox,
98 capela 1466 SIGNAL(activated(int)),
99     SLOT(changed()));
100 capela 2107 QObject::connect(m_ui.DialogButtonBox,
101     SIGNAL(accepted()),
102 capela 1466 SLOT(accept()));
103 capela 2107 QObject::connect(m_ui.DialogButtonBox,
104     SIGNAL(rejected()),
105 capela 1466 SLOT(reject()));
106 schoenebeck 1461 }
107    
108 capela 1504
109     InstrumentForm::~InstrumentForm (void)
110     {
111 schoenebeck 1461 }
112    
113 capela 1504
114 schoenebeck 1461 // Channel dialog setup formal initializer.
115 capela 1558 void InstrumentForm::setup ( Instrument *pInstrument )
116 schoenebeck 1461 {
117     m_pInstrument = pInstrument;
118    
119     m_iDirtySetup = 0;
120     m_iDirtyCount = 0;
121     m_iDirtyName = 0;
122    
123 capela 3555 if (m_pInstrument == nullptr)
124 schoenebeck 1461 return;
125    
126     // Check if we're up and connected.
127     MainForm* pMainForm = MainForm::getInstance();
128 capela 3555 if (pMainForm == nullptr)
129 schoenebeck 1461 return;
130 capela 3555 if (pMainForm->client() == nullptr)
131 schoenebeck 1461 return;
132    
133 capela 1558 Options *pOptions = pMainForm->options();
134 capela 3555 if (pOptions == nullptr)
135 schoenebeck 1461 return;
136    
137     // It can be a brand new channel, remember?
138     bool bNew = (m_pInstrument->bank() < 0 || m_pInstrument->prog() < 0);
139     if (!bNew) {
140     m_pInstrument->getInstrument();
141     m_iDirtyName++;
142     }
143    
144     // Avoid nested changes.
145     m_iDirtySetup++;
146    
147     // Load combo box history...
148 capela 1509 pOptions->loadComboBoxHistory(m_ui.InstrumentFileComboBox);
149 schoenebeck 1461
150     // Populate maps list.
151 capela 1509 m_ui.MapComboBox->clear();
152 capela 1558 m_ui.MapComboBox->insertItems(0, Instrument::getMapNames());
153 schoenebeck 1461
154     // Populate Engines list.
155 capela 1509 const char **ppszEngines
156     = ::lscp_list_available_engines(pMainForm->client());
157 schoenebeck 1461 if (ppszEngines) {
158 capela 1509 m_ui.EngineNameComboBox->clear();
159 schoenebeck 1461 for (int iEngine = 0; ppszEngines[iEngine]; iEngine++)
160 capela 1509 m_ui.EngineNameComboBox->addItem(ppszEngines[iEngine]);
161 schoenebeck 1461 }
162     else pMainForm->appendMessagesClient("lscp_list_available_engines");
163    
164     // Read proper instrument information,
165     // and populate the instrument form fields.
166    
167     // Instrument map name...
168     int iMap = (bNew ? pOptions->iMidiMap : m_pInstrument->map());
169     if (iMap < 0)
170     iMap = 0;
171 capela 1558 const QString& sMapName = Instrument::getMapName(iMap);
172 capela 1499 if (!sMapName.isEmpty()) {
173 capela 1526 m_ui.MapComboBox->setCurrentIndex(
174     m_ui.MapComboBox->findText(sMapName,
175     Qt::MatchExactly | Qt::MatchCaseSensitive));
176 capela 1499 }
177 capela 1526
178 schoenebeck 1461 // It might be no maps around...
179 capela 1509 bool bMapEnabled = (m_ui.MapComboBox->count() > 0);
180     m_ui.MapTextLabel->setEnabled(bMapEnabled);
181     m_ui.MapComboBox->setEnabled(bMapEnabled);
182 schoenebeck 1461
183     // Instrument bank/program...
184     int iBank = (bNew ? pOptions->iMidiBank : m_pInstrument->bank());
185     int iProg = (bNew ? pOptions->iMidiProg : m_pInstrument->prog()) + 1;
186     if (bNew && iProg > 128) {
187     iProg = 1;
188     iBank++;
189     }
190 capela 1509 m_ui.BankSpinBox->setValue(iBank);
191     m_ui.ProgSpinBox->setValue(iProg);
192 schoenebeck 1461
193     // Instrument name...
194 capela 1509 m_ui.NameLineEdit->setText(m_pInstrument->name());
195 schoenebeck 1461
196     // Engine name...
197     QString sEngineName = m_pInstrument->engineName();
198     if (sEngineName.isEmpty() || bNew)
199     sEngineName = pOptions->sEngineName;
200     if (sEngineName.isEmpty())
201 capela 1558 sEngineName = Channel::noEngineName();
202 capela 1509 if (m_ui.EngineNameComboBox->findText(sEngineName,
203 schoenebeck 1474 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
204 capela 1509 m_ui.EngineNameComboBox->addItem(sEngineName);
205 schoenebeck 1461 }
206 capela 1509 m_ui.EngineNameComboBox->setCurrentIndex(
207     m_ui.EngineNameComboBox->findText(sEngineName,
208 capela 1504 Qt::MatchExactly | Qt::MatchCaseSensitive));
209    
210 schoenebeck 1461 // Instrument filename and index...
211     QString sInstrumentFile = m_pInstrument->instrumentFile();
212     if (sInstrumentFile.isEmpty())
213 capela 1558 sInstrumentFile = Channel::noInstrumentName();
214 capela 1509 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
215     m_ui.InstrumentNrComboBox->clear();
216     m_ui.InstrumentNrComboBox->insertItems(0,
217 capela 1558 Channel::getInstrumentList(sInstrumentFile,
218 schoenebeck 1461 pOptions->bInstrumentNames));
219 capela 1509 m_ui.InstrumentNrComboBox->setCurrentIndex(m_pInstrument->instrumentNr());
220 schoenebeck 1461
221     // Instrument volume....
222     int iVolume = (bNew ? pOptions->iVolume :
223     ::lroundf(100.0f * m_pInstrument->volume()));
224 capela 1509 m_ui.VolumeSpinBox->setValue(iVolume);
225 schoenebeck 1461
226     // Instrument load mode...
227     int iLoadMode = (bNew ? pOptions->iLoadMode :
228     m_pInstrument->loadMode());
229 capela 1509 m_ui.LoadModeComboBox->setCurrentIndex(iLoadMode);
230 schoenebeck 1461
231     // Done.
232     m_iDirtySetup--;
233     stabilizeForm();
234     }
235    
236    
237     // Special case for name change,
238     void InstrumentForm::nameChanged ( const QString& /* sName */ )
239     {
240     if (m_iDirtySetup > 0)
241     return;
242    
243     m_iDirtyName++;
244     changed();
245     }
246    
247    
248     // Browse and open an instrument file.
249     void InstrumentForm::openInstrumentFile (void)
250     {
251     MainForm* pMainForm = MainForm::getInstance();
252 capela 3555 if (pMainForm == nullptr)
253 schoenebeck 1461 return;
254    
255 capela 1558 Options *pOptions = pMainForm->options();
256 capela 3555 if (pOptions == nullptr)
257 schoenebeck 1461 return;
258    
259     // FIXME: the instrument file filters should be restricted,
260     // depending on the current engine.
261 capela 2110 const QString& sEngineName = m_ui.EngineNameComboBox->currentText().toUpper();
262 capela 2108 QStringList filters;
263 capela 2110 if (sEngineName.contains("GIG"))
264     filters << tr("GIG Instrument files") + " (*.gig *.dls)";
265     if (sEngineName.contains("SFZ"))
266     filters << tr("SFZ Instrument files") + " (*.sfz)";
267     if (sEngineName.contains("SF2"))
268     filters << tr("SF2 Instrument files") + " (*.sf2)";
269 capela 2108 const QString& filter = filters.join(";;");
270    
271 capela 1499 QString sInstrumentFile = QFileDialog::getOpenFileName(this,
272     QSAMPLER_TITLE ": " + tr("Instrument files"), // Caption.
273 capela 2108 pOptions->sInstrumentDir, // Start here.
274     filter // File filter.
275 schoenebeck 1461 );
276    
277     if (sInstrumentFile.isEmpty())
278     return;
279    
280 capela 1509 m_ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
281 schoenebeck 1461 updateInstrumentName();
282     }
283    
284    
285     // Refresh the actual instrument name.
286     void InstrumentForm::updateInstrumentName (void)
287     {
288     MainForm* pMainForm = MainForm::getInstance();
289 capela 3555 if (pMainForm == nullptr)
290 schoenebeck 1461 return;
291    
292 capela 1558 Options *pOptions = pMainForm->options();
293 capela 3555 if (pOptions == nullptr)
294 schoenebeck 1461 return;
295    
296     // TODO: this better idea would be to use libgig
297     // to retrieve the REAL instrument names.
298 capela 1509 m_ui.InstrumentNrComboBox->clear();
299     m_ui.InstrumentNrComboBox->insertItems(0,
300 capela 1558 Channel::getInstrumentList(
301 capela 1509 m_ui.InstrumentFileComboBox->currentText(),
302 schoenebeck 1461 pOptions->bInstrumentNames)
303     );
304    
305     instrumentNrChanged();
306     }
307    
308    
309     // Special case for instrumnet index change,
310     void InstrumentForm::instrumentNrChanged (void)
311     {
312     if (m_iDirtySetup > 0)
313     return;
314    
315 capela 1509 if (m_ui.NameLineEdit->text().isEmpty() || m_iDirtyName == 0) {
316     m_ui.NameLineEdit->setText(m_ui.InstrumentNrComboBox->currentText());
317 schoenebeck 1461 m_iDirtyName = 0;
318     }
319    
320     changed();
321     }
322    
323    
324     // Accept settings (OK button slot).
325     void InstrumentForm::accept (void)
326     {
327 capela 3555 if (m_pInstrument == nullptr)
328 schoenebeck 1461 return;
329    
330     MainForm* pMainForm = MainForm::getInstance();
331 capela 3555 if (pMainForm == nullptr)
332 schoenebeck 1461 return;
333 capela 3555 if (pMainForm->client() == nullptr)
334 schoenebeck 1461 return;
335    
336 capela 1558 Options *pOptions = pMainForm->options();
337 capela 3555 if (pOptions == nullptr)
338 schoenebeck 1461 return;
339    
340     if (m_iDirtyCount > 0) {
341 capela 1509 m_pInstrument->setMap(m_ui.MapComboBox->currentIndex());
342     m_pInstrument->setBank(m_ui.BankSpinBox->value());
343     m_pInstrument->setProg(m_ui.ProgSpinBox->value() - 1);
344     m_pInstrument->setName(m_ui.NameLineEdit->text());
345     m_pInstrument->setEngineName(m_ui.EngineNameComboBox->currentText());
346     m_pInstrument->setInstrumentFile(m_ui.InstrumentFileComboBox->currentText());
347     m_pInstrument->setInstrumentNr(m_ui.InstrumentNrComboBox->currentIndex());
348     m_pInstrument->setVolume(0.01f * float(m_ui.VolumeSpinBox->value()));
349     m_pInstrument->setLoadMode(m_ui.LoadModeComboBox->currentIndex());
350 schoenebeck 1461 }
351    
352     // Save default engine name, instrument directory and history...
353 capela 1499 pOptions->sInstrumentDir = QFileInfo(
354 capela 1509 m_ui.InstrumentFileComboBox->currentText()).dir().absolutePath();
355     pOptions->sEngineName = m_ui.EngineNameComboBox->currentText();
356     pOptions->iMidiMap = m_ui.MapComboBox->currentIndex();
357     pOptions->iMidiBank = m_ui.BankSpinBox->value();
358     pOptions->iMidiProg = m_ui.ProgSpinBox->value();
359     pOptions->iVolume = m_ui.VolumeSpinBox->value();
360     pOptions->iLoadMode = m_ui.LoadModeComboBox->currentIndex();
361     pOptions->saveComboBoxHistory(m_ui.InstrumentFileComboBox);
362 schoenebeck 1461
363     // Just go with dialog acceptance.
364     QDialog::accept();
365     }
366    
367    
368     // Reject settings (Cancel button slot).
369     void InstrumentForm::reject (void)
370     {
371     bool bReject = true;
372    
373     // Check if there's any pending changes...
374 capela 2107 if (m_iDirtyCount > 0) {
375 schoenebeck 1461 switch (QMessageBox::warning(this,
376     QSAMPLER_TITLE ": " + tr("Warning"),
377     tr("Some channel settings have been changed.\n\n"
378     "Do you want to apply the changes?"),
379 capela 1840 QMessageBox::Apply |
380     QMessageBox::Discard |
381     QMessageBox::Cancel)) {
382     case QMessageBox::Apply:
383 schoenebeck 1461 accept();
384     return;
385 capela 1840 case QMessageBox::Discard:
386 schoenebeck 1461 break;
387     default: // Cancel.
388     bReject = false;
389     break;
390     }
391     }
392    
393     if (bReject)
394     QDialog::reject();
395     }
396    
397    
398     // Dirty up settings.
399     void InstrumentForm::changed (void)
400     {
401     if (m_iDirtySetup > 0)
402     return;
403    
404     m_iDirtyCount++;
405     stabilizeForm();
406     }
407    
408    
409     // Stabilize current form state.
410     void InstrumentForm::stabilizeForm (void)
411     {
412 capela 2069 bool bValid = !m_ui.NameLineEdit->text().isEmpty()
413     && m_ui.EngineNameComboBox->currentIndex() >= 0
414     && m_ui.EngineNameComboBox->currentText() != Channel::noEngineName();
415 schoenebeck 1461
416 capela 1509 const QString& sPath = m_ui.InstrumentFileComboBox->currentText();
417 schoenebeck 1461 bValid = bValid && !sPath.isEmpty() && QFileInfo(sPath).exists();
418    
419 capela 2107 m_ui.DialogButtonBox->button(
420     QDialogButtonBox::Ok)->setEnabled(m_iDirtyCount > 0 && bValid);
421 schoenebeck 1461 }
422    
423     } // namespace QSampler
424 capela 1464
425    
426     // end of qsamplerInstrumentForm.cpp

  ViewVC Help
Powered by ViewVC