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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1506 - (hide 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 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 schoenebeck 1461 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 capela 1466
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 schoenebeck 1474 SIGNAL(textChanged(const QString&)),
74     SLOT(nameChanged(const QString&)));
75 capela 1466 QObject::connect(ui.EngineNameComboBox,
76     SIGNAL(activated(int)),
77     SLOT(changed()));
78     QObject::connect(ui.InstrumentFileComboBox,
79 schoenebeck 1474 SIGNAL(activated(const QString&)),
80 capela 1466 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 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     pOptions->loadComboBoxHistory(ui.InstrumentFileComboBox);
142    
143     // Populate maps list.
144     ui.MapComboBox->clear();
145 capela 1499 ui.MapComboBox->insertItems(0, qsamplerInstrument::getMapNames());
146 schoenebeck 1461
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 capela 1499 ui.EngineNameComboBox->addItem(ppszEngines[iEngine]);
153 schoenebeck 1461 }
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 capela 1499 if (!sMapName.isEmpty()) {
165     ui.MapComboBox->setItemText(
166     ui.MapComboBox->currentIndex(),
167     sMapName);
168     }
169 schoenebeck 1461 // 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 schoenebeck 1474 Qt::MatchExactly | Qt::MatchCaseSensitive) < 0) {
195 capela 1499 ui.EngineNameComboBox->addItem(sEngineName);
196 schoenebeck 1461 }
197 capela 1504 ui.EngineNameComboBox->setCurrentIndex(
198     ui.EngineNameComboBox->findText(sEngineName,
199     Qt::MatchExactly | Qt::MatchCaseSensitive));
200    
201 schoenebeck 1461 // Instrument filename and index...
202     QString sInstrumentFile = m_pInstrument->instrumentFile();
203     if (sInstrumentFile.isEmpty())
204     sInstrumentFile = qsamplerChannel::noInstrumentName();
205 capela 1505 ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
206 schoenebeck 1461 ui.InstrumentNrComboBox->clear();
207 capela 1499 ui.InstrumentNrComboBox->insertItems(0,
208 schoenebeck 1461 qsamplerChannel::getInstrumentList(sInstrumentFile,
209     pOptions->bInstrumentNames));
210 capela 1499 ui.InstrumentNrComboBox->setCurrentIndex(m_pInstrument->instrumentNr());
211 schoenebeck 1461
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 capela 1499 ui.LoadModeComboBox->setCurrentIndex(iLoadMode);
221 schoenebeck 1461
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 capela 1499 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 schoenebeck 1461 );
261    
262     if (sInstrumentFile.isEmpty())
263     return;
264    
265 capela 1505 ui.InstrumentFileComboBox->setEditText(sInstrumentFile);
266 schoenebeck 1461 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 capela 1499 ui.InstrumentNrComboBox->insertItems(0,
285 schoenebeck 1461 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 capela 1499 m_pInstrument->setMap(ui.MapComboBox->currentIndex());
327 schoenebeck 1461 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 capela 1499 m_pInstrument->setInstrumentNr(ui.InstrumentNrComboBox->currentIndex());
333 schoenebeck 1461 m_pInstrument->setVolume(0.01f * float(ui.VolumeSpinBox->value()));
334 capela 1499 m_pInstrument->setLoadMode(ui.LoadModeComboBox->currentIndex());
335 schoenebeck 1461 }
336    
337     // Save default engine name, instrument directory and history...
338 capela 1499 pOptions->sInstrumentDir = QFileInfo(
339     ui.InstrumentFileComboBox->currentText()).dir().absolutePath();
340 schoenebeck 1461 pOptions->sEngineName = ui.EngineNameComboBox->currentText();
341 capela 1499 pOptions->iMidiMap = ui.MapComboBox->currentIndex();
342 schoenebeck 1461 pOptions->iMidiBank = ui.BankSpinBox->value();
343     pOptions->iMidiProg = ui.ProgSpinBox->value();
344     pOptions->iVolume = ui.VolumeSpinBox->value();
345 capela 1499 pOptions->iLoadMode = ui.LoadModeComboBox->currentIndex();
346 schoenebeck 1461 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 schoenebeck 1506 bool bValid =
396     !ui.NameLineEdit->text().isEmpty() &&
397     ui.EngineNameComboBox->currentIndex() >= 0 &&
398     ui.EngineNameComboBox->currentText() !=
399     qsamplerChannel::noEngineName();
400 schoenebeck 1461
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 capela 1464
409    
410     // end of qsamplerInstrumentForm.cpp

  ViewVC Help
Powered by ViewVC