1 |
// qsamplerMainForm.cpp |
// qsamplerMainForm.cpp |
2 |
// |
// |
3 |
/**************************************************************************** |
/**************************************************************************** |
4 |
Copyright (C) 2004-2012, rncbc aka Rui Nuno Capela. All rights reserved. |
Copyright (C) 2004-2015, rncbc aka Rui Nuno Capela. All rights reserved. |
5 |
Copyright (C) 2007, 2008 Christian Schoenebeck |
Copyright (C) 2007,2008,2015 Christian Schoenebeck |
6 |
|
|
7 |
This program is free software; you can redistribute it and/or |
This program is free software; you can redistribute it and/or |
8 |
modify it under the terms of the GNU General Public License |
modify it under the terms of the GNU General Public License |
65 |
#if QT_VERSION < 0x040500 |
#if QT_VERSION < 0x040500 |
66 |
namespace Qt { |
namespace Qt { |
67 |
const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000); |
const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000); |
|
#if QT_VERSION < 0x040200 |
|
|
const WindowFlags CustomizeWindowHint = WindowFlags(0x02000000); |
|
|
#endif |
|
68 |
} |
} |
69 |
#endif |
#endif |
70 |
|
|
254 |
QObject::connect(m_pVolumeSlider, |
QObject::connect(m_pVolumeSlider, |
255 |
SIGNAL(valueChanged(int)), |
SIGNAL(valueChanged(int)), |
256 |
SLOT(volumeChanged(int))); |
SLOT(volumeChanged(int))); |
|
//m_ui.channelsToolbar->setHorizontallyStretchable(true); |
|
|
//m_ui.channelsToolbar->setStretchableWidget(m_pVolumeSlider); |
|
257 |
m_ui.channelsToolbar->addWidget(m_pVolumeSlider); |
m_ui.channelsToolbar->addWidget(m_pVolumeSlider); |
258 |
// Volume spin-box |
// Volume spin-box |
259 |
m_ui.channelsToolbar->addSeparator(); |
m_ui.channelsToolbar->addSeparator(); |
260 |
m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar); |
m_pVolumeSpinBox = new QSpinBox(m_ui.channelsToolbar); |
|
m_pVolumeSpinBox->setMaximumHeight(24); |
|
261 |
m_pVolumeSpinBox->setSuffix(" %"); |
m_pVolumeSpinBox->setSuffix(" %"); |
262 |
m_pVolumeSpinBox->setMinimum(0); |
m_pVolumeSpinBox->setMinimum(0); |
263 |
m_pVolumeSpinBox->setMaximum(100); |
m_pVolumeSpinBox->setMaximum(100); |
270 |
|
|
271 |
// Make it an MDI workspace. |
// Make it an MDI workspace. |
272 |
m_pWorkspace = new QMdiArea(this); |
m_pWorkspace = new QMdiArea(this); |
273 |
|
m_pWorkspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
274 |
|
m_pWorkspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
275 |
// Set the activation connection. |
// Set the activation connection. |
276 |
QObject::connect(m_pWorkspace, |
QObject::connect(m_pWorkspace, |
277 |
SIGNAL(subWindowActivated(QMdiSubWindow *)), |
SIGNAL(subWindowActivated(QMdiSubWindow *)), |
392 |
QObject::connect(m_ui.channelsMenu, |
QObject::connect(m_ui.channelsMenu, |
393 |
SIGNAL(aboutToShow()), |
SIGNAL(aboutToShow()), |
394 |
SLOT(channelsMenuAboutToShow())); |
SLOT(channelsMenuAboutToShow())); |
395 |
|
#ifdef CONFIG_VOLUME |
396 |
|
QObject::connect(m_ui.channelsToolbar, |
397 |
|
SIGNAL(orientationChanged(Qt::Orientation)), |
398 |
|
SLOT(channelsToolbarOrientation(Qt::Orientation))); |
399 |
|
#endif |
400 |
} |
} |
401 |
|
|
402 |
// Destructor. |
// Destructor. |
908 |
pChannel->removeChannel(); |
pChannel->removeChannel(); |
909 |
delete pChannelStrip; |
delete pChannelStrip; |
910 |
} |
} |
911 |
|
if (pMdiSubWindow) |
912 |
|
delete pMdiSubWindow; |
913 |
} |
} |
914 |
m_pWorkspace->setUpdatesEnabled(true); |
m_pWorkspace->setUpdatesEnabled(true); |
915 |
// We're now clean, for sure. |
// We're now clean, for sure. |
1253 |
ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl; |
ts << "SET CHANNEL MUTE " << iChannel << " 1" << endl; |
1254 |
if (pChannel->channelSolo()) |
if (pChannel->channelSolo()) |
1255 |
ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl; |
ts << "SET CHANNEL SOLO " << iChannel << " 1" << endl; |
1256 |
#ifdef CONFIG_MIDI_INSTRUMENT |
#ifdef CONFIG_MIDI_INSTRUMENT |
1257 |
if (pChannel->midiMap() >= 0) { |
if (pChannel->midiMap() >= 0) { |
1258 |
ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel |
ts << "SET CHANNEL MIDI_INSTRUMENT_MAP " << iChannel |
1259 |
<< " " << midiInstrumentMap[pChannel->midiMap()] << endl; |
<< " " << midiInstrumentMap[pChannel->midiMap()] << endl; |
1260 |
} |
} |
1261 |
#endif |
#endif |
1262 |
#ifdef CONFIG_FXSEND |
#ifdef CONFIG_FXSEND |
1263 |
int iChannelID = pChannel->channelID(); |
int iChannelID = pChannel->channelID(); |
1264 |
int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID); |
int *piFxSends = ::lscp_list_fxsends(m_pClient, iChannelID); |
1265 |
for (int iFxSend = 0; |
for (int iFxSend = 0; |
1283 |
<< " " << iAudioSrc |
<< " " << iAudioSrc |
1284 |
<< " " << piRouting[iAudioSrc] << endl; |
<< " " << piRouting[iAudioSrc] << endl; |
1285 |
} |
} |
1286 |
#ifdef CONFIG_FXSEND_LEVEL |
#ifdef CONFIG_FXSEND_LEVEL |
1287 |
ts << "SET FX_SEND LEVEL " << iChannel |
ts << "SET FX_SEND LEVEL " << iChannel |
1288 |
<< " " << iFxSend |
<< " " << iFxSend |
1289 |
<< " " << pFxSendInfo->level << endl; |
<< " " << pFxSendInfo->level << endl; |
1290 |
#endif |
#endif |
1291 |
} // Check for errors... |
} // Check for errors... |
1292 |
else if (::lscp_client_get_errno(m_pClient)) { |
else if (::lscp_client_get_errno(m_pClient)) { |
1293 |
appendMessagesClient("lscp_get_fxsend_info"); |
appendMessagesClient("lscp_get_fxsend_info"); |
1294 |
iErrors++; |
iErrors++; |
1295 |
} |
} |
1296 |
} |
} |
1297 |
#endif |
#endif |
1298 |
ts << endl; |
ts << endl; |
1299 |
} |
} |
1300 |
} |
} |
1405 |
return; |
return; |
1406 |
|
|
1407 |
// Ask user whether he/she want's an internal sampler reset... |
// Ask user whether he/she want's an internal sampler reset... |
1408 |
if (QMessageBox::warning(this, |
if (m_pOptions && m_pOptions->bConfirmReset) { |
1409 |
QSAMPLER_TITLE ": " + tr("Warning"), |
const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning"); |
1410 |
tr("Resetting the sampler instance will close\n" |
const QString& sText = tr( |
1411 |
"all device and channel configurations.\n\n" |
"Resetting the sampler instance will close\n" |
1412 |
"Please note that this operation may cause\n" |
"all device and channel configurations.\n\n" |
1413 |
"temporary MIDI and Audio disruption.\n\n" |
"Please note that this operation may cause\n" |
1414 |
"Do you want to reset the sampler engine now?"), |
"temporary MIDI and Audio disruption.\n\n" |
1415 |
QMessageBox::Ok | QMessageBox::Cancel) |
"Do you want to reset the sampler engine now?"); |
1416 |
== QMessageBox::Cancel) |
#if 0 |
1417 |
return; |
if (QMessageBox::warning(this, sTitle, sText, |
1418 |
|
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) |
1419 |
|
return; |
1420 |
|
#else |
1421 |
|
QMessageBox mbox(this); |
1422 |
|
mbox.setIcon(QMessageBox::Warning); |
1423 |
|
mbox.setWindowTitle(sTitle); |
1424 |
|
mbox.setText(sText); |
1425 |
|
mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
1426 |
|
QCheckBox cbox(tr("Don't ask this again")); |
1427 |
|
cbox.setChecked(false); |
1428 |
|
cbox.blockSignals(true); |
1429 |
|
mbox.addButton(&cbox, QMessageBox::ActionRole); |
1430 |
|
if (mbox.exec() == QMessageBox::Cancel) |
1431 |
|
return; |
1432 |
|
if (cbox.isChecked()) |
1433 |
|
m_pOptions->bConfirmReset = false; |
1434 |
|
#endif |
1435 |
|
} |
1436 |
|
|
1437 |
// Trye closing the current session, first... |
// Trye closing the current session, first... |
1438 |
if (!closeSession(true)) |
if (!closeSession(true)) |
1464 |
|
|
1465 |
// Ask user whether he/she want's a complete restart... |
// Ask user whether he/she want's a complete restart... |
1466 |
// (if we're currently up and running) |
// (if we're currently up and running) |
1467 |
if (bRestart && m_pClient) { |
if (m_pOptions && m_pOptions->bConfirmRestart) { |
1468 |
bRestart = (QMessageBox::warning(this, |
const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning"); |
1469 |
QSAMPLER_TITLE ": " + tr("Warning"), |
const QString& sText = tr( |
1470 |
tr("New settings will be effective after\n" |
"New settings will be effective after\n" |
1471 |
"restarting the client/server connection.\n\n" |
"restarting the client/server connection.\n\n" |
1472 |
"Please note that this operation may cause\n" |
"Please note that this operation may cause\n" |
1473 |
"temporary MIDI and Audio disruption.\n\n" |
"temporary MIDI and Audio disruption.\n\n" |
1474 |
"Do you want to restart the connection now?"), |
"Do you want to restart the connection now?"); |
1475 |
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok); |
#if 0 |
1476 |
|
if (QMessageBox::warning(this, sTitle, sText, |
1477 |
|
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) |
1478 |
|
bRestart = false; |
1479 |
|
#else |
1480 |
|
QMessageBox mbox(this); |
1481 |
|
mbox.setIcon(QMessageBox::Warning); |
1482 |
|
mbox.setWindowTitle(sTitle); |
1483 |
|
mbox.setText(sText); |
1484 |
|
mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
1485 |
|
QCheckBox cbox(tr("Don't ask this again")); |
1486 |
|
cbox.setChecked(false); |
1487 |
|
cbox.blockSignals(true); |
1488 |
|
mbox.addButton(&cbox, QMessageBox::ActionRole); |
1489 |
|
if (mbox.exec() == QMessageBox::Cancel) |
1490 |
|
bRestart = false; |
1491 |
|
else |
1492 |
|
if (cbox.isChecked()) |
1493 |
|
m_pOptions->bConfirmRestart = false; |
1494 |
|
#endif |
1495 |
} |
} |
1496 |
|
|
1497 |
// Are we still for it? |
// Are we still for it? |
1566 |
|
|
1567 |
// Prompt user if he/she's sure about this... |
// Prompt user if he/she's sure about this... |
1568 |
if (m_pOptions && m_pOptions->bConfirmRemove) { |
if (m_pOptions && m_pOptions->bConfirmRemove) { |
1569 |
if (QMessageBox::warning(this, |
const QString& sTitle = QSAMPLER_TITLE ": " + tr("Warning"); |
1570 |
QSAMPLER_TITLE ": " + tr("Warning"), |
const QString& sText = tr( |
1571 |
tr("About to remove channel:\n\n" |
"About to remove channel:\n\n" |
1572 |
"%1\n\n" |
"%1\n\n" |
1573 |
"Are you sure?") |
"Are you sure?") |
1574 |
.arg(pChannelStrip->windowTitle()), |
.arg(pChannelStrip->windowTitle()); |
1575 |
QMessageBox::Ok | QMessageBox::Cancel) |
#if 0 |
1576 |
== QMessageBox::Cancel) |
if (QMessageBox::warning(this, sTitle, sText, |
1577 |
|
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) |
1578 |
return; |
return; |
1579 |
|
#else |
1580 |
|
QMessageBox mbox(this); |
1581 |
|
mbox.setIcon(QMessageBox::Warning); |
1582 |
|
mbox.setWindowTitle(sTitle); |
1583 |
|
mbox.setText(sText); |
1584 |
|
mbox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); |
1585 |
|
QCheckBox cbox(tr("Don't ask this again")); |
1586 |
|
cbox.setChecked(false); |
1587 |
|
cbox.blockSignals(true); |
1588 |
|
mbox.addButton(&cbox, QMessageBox::ActionRole); |
1589 |
|
if (mbox.exec() == QMessageBox::Cancel) |
1590 |
|
return; |
1591 |
|
if (cbox.isChecked()) |
1592 |
|
m_pOptions->bConfirmRemove = false; |
1593 |
|
#endif |
1594 |
} |
} |
1595 |
|
|
1596 |
// Remove the existing sampler channel. |
// Remove the existing sampler channel. |
1597 |
if (!pChannel->removeChannel()) |
if (!pChannel->removeChannel()) |
1598 |
return; |
return; |
1599 |
|
|
|
// Just delete the channel strip. |
|
|
delete pChannelStrip; |
|
|
|
|
|
// Do we auto-arrange? |
|
|
if (m_pOptions && m_pOptions->bAutoArrange) |
|
|
channelsArrange(); |
|
|
|
|
1600 |
// We'll be dirty, for sure... |
// We'll be dirty, for sure... |
1601 |
m_iDirtyCount++; |
m_iDirtyCount++; |
1602 |
stabilizeForm(); |
|
1603 |
|
// Just delete the channel strip. |
1604 |
|
destroyChannelStrip(pChannelStrip); |
1605 |
} |
} |
1606 |
|
|
1607 |
|
|
2401 |
m_pMessages->appendMessagesText(s); |
m_pMessages->appendMessagesText(s); |
2402 |
} |
} |
2403 |
|
|
2404 |
void MainForm::appendMessagesError( const QString& s ) |
void MainForm::appendMessagesError( const QString& sText ) |
2405 |
{ |
{ |
2406 |
if (m_pMessages) |
if (m_pMessages) |
2407 |
m_pMessages->show(); |
m_pMessages->show(); |
2408 |
|
|
2409 |
appendMessagesColor(s.simplified(), "#ff0000"); |
appendMessagesColor(sText.simplified(), "#ff0000"); |
2410 |
|
|
2411 |
// Make it look responsive...:) |
// Make it look responsive...:) |
2412 |
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); |
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); |
2413 |
|
|
2414 |
QMessageBox::critical(this, |
if (m_pOptions && m_pOptions->bConfirmError) { |
2415 |
QSAMPLER_TITLE ": " + tr("Error"), s, QMessageBox::Cancel); |
const QString& sTitle = QSAMPLER_TITLE ": " + tr("Error"); |
2416 |
|
#if 0 |
2417 |
|
QMessageBox::critical(this, sTitle, sText, QMessageBox::Cancel); |
2418 |
|
#else |
2419 |
|
QMessageBox mbox(this); |
2420 |
|
mbox.setIcon(QMessageBox::Critical); |
2421 |
|
mbox.setWindowTitle(sTitle); |
2422 |
|
mbox.setText(sText); |
2423 |
|
mbox.setStandardButtons(QMessageBox::Cancel); |
2424 |
|
QCheckBox cbox(tr("Don't show this again")); |
2425 |
|
cbox.setChecked(false); |
2426 |
|
cbox.blockSignals(true); |
2427 |
|
mbox.addButton(&cbox, QMessageBox::ActionRole); |
2428 |
|
if (mbox.exec() && cbox.isChecked()) |
2429 |
|
m_pOptions->bConfirmError = false; |
2430 |
|
#endif |
2431 |
|
} |
2432 |
} |
} |
2433 |
|
|
2434 |
|
|
2514 |
} |
} |
2515 |
|
|
2516 |
// Add it to workspace... |
// Add it to workspace... |
2517 |
m_pWorkspace->addSubWindow(pChannelStrip, Qt::FramelessWindowHint); |
m_pWorkspace->addSubWindow(pChannelStrip, |
2518 |
|
Qt::SubWindow | Qt::FramelessWindowHint); |
2519 |
|
|
2520 |
// Actual channel strip setup... |
// Actual channel strip setup... |
2521 |
pChannelStrip->setup(pChannel); |
pChannelStrip->setup(pChannel); |
2537 |
|
|
2538 |
void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip ) |
void MainForm::destroyChannelStrip ( ChannelStrip *pChannelStrip ) |
2539 |
{ |
{ |
2540 |
|
QMdiSubWindow *pMdiSubWindow |
2541 |
|
= static_cast<QMdiSubWindow *> (pChannelStrip->parentWidget()); |
2542 |
|
if (pMdiSubWindow == NULL) |
2543 |
|
return; |
2544 |
|
|
2545 |
// Just delete the channel strip. |
// Just delete the channel strip. |
2546 |
delete pChannelStrip; |
delete pChannelStrip; |
2547 |
|
delete pMdiSubWindow; |
2548 |
|
|
2549 |
// Do we auto-arrange? |
// Do we auto-arrange? |
2550 |
if (m_pOptions && m_pOptions->bAutoArrange) |
if (m_pOptions && m_pOptions->bAutoArrange) |
2763 |
|
|
2764 |
// Setup stdout/stderr capture... |
// Setup stdout/stderr capture... |
2765 |
// if (m_pOptions->bStdoutCapture) { |
// if (m_pOptions->bStdoutCapture) { |
|
#if QT_VERSION >= 0x040200 |
|
2766 |
m_pServer->setProcessChannelMode(QProcess::ForwardedChannels); |
m_pServer->setProcessChannelMode(QProcess::ForwardedChannels); |
|
#endif |
|
2767 |
QObject::connect(m_pServer, |
QObject::connect(m_pServer, |
2768 |
SIGNAL(readyReadStandardOutput()), |
SIGNAL(readyReadStandardOutput()), |
2769 |
SLOT(readServerStdout())); |
SLOT(readServerStdout())); |
2818 |
"according to your current sampler session and you could alter the\n" |
"according to your current sampler session and you could alter the\n" |
2819 |
"sampler session at any time by relaunching QSampler.\n\n" |
"sampler session at any time by relaunching QSampler.\n\n" |
2820 |
"Do you want LinuxSampler to stop?"), |
"Do you want LinuxSampler to stop?"), |
2821 |
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) |
QMessageBox::Yes | QMessageBox::No, |
2822 |
|
QMessageBox::Yes) == QMessageBox::No) |
2823 |
{ |
{ |
2824 |
bForceServerStop = false; |
bForceServerStop = false; |
2825 |
} |
} |
2829 |
if (m_pServer && bForceServerStop) { |
if (m_pServer && bForceServerStop) { |
2830 |
appendMessages(tr("Server is stopping...")); |
appendMessages(tr("Server is stopping...")); |
2831 |
if (m_pServer->state() == QProcess::Running) { |
if (m_pServer->state() == QProcess::Running) { |
2832 |
#if defined(WIN32) |
#if defined(WIN32) |
2833 |
// Try harder... |
// Try harder... |
2834 |
m_pServer->kill(); |
m_pServer->kill(); |
2835 |
#else |
#else |
2836 |
// Try softly... |
// Try softly... |
2837 |
m_pServer->terminate(); |
m_pServer->terminate(); |
2838 |
#endif |
#endif |
2839 |
} |
} |
2840 |
} // Do final processing anyway. |
} // Do final processing anyway. |
2841 |
else processServerExit(); |
else processServerExit(); |
3076 |
} |
} |
3077 |
|
|
3078 |
|
|
3079 |
|
// Channel toolbar orientation change. |
3080 |
|
void MainForm::channelsToolbarOrientation ( Qt::Orientation orientation ) |
3081 |
|
{ |
3082 |
|
#ifdef CONFIG_VOLUME |
3083 |
|
m_pVolumeSlider->setOrientation(orientation); |
3084 |
|
if (orientation == Qt::Horizontal) { |
3085 |
|
m_pVolumeSlider->setMinimumHeight(24); |
3086 |
|
m_pVolumeSlider->setMaximumHeight(32); |
3087 |
|
m_pVolumeSlider->setMinimumWidth(120); |
3088 |
|
m_pVolumeSlider->setMaximumWidth(640); |
3089 |
|
m_pVolumeSpinBox->setMaximumWidth(64); |
3090 |
|
m_pVolumeSpinBox->setButtonSymbols(QSpinBox::UpDownArrows); |
3091 |
|
} else { |
3092 |
|
m_pVolumeSlider->setMinimumHeight(120); |
3093 |
|
m_pVolumeSlider->setMaximumHeight(480); |
3094 |
|
m_pVolumeSlider->setMinimumWidth(24); |
3095 |
|
m_pVolumeSlider->setMaximumWidth(32); |
3096 |
|
m_pVolumeSpinBox->setMaximumWidth(32); |
3097 |
|
m_pVolumeSpinBox->setButtonSymbols(QSpinBox::NoButtons); |
3098 |
|
} |
3099 |
|
#endif |
3100 |
|
} |
3101 |
|
|
3102 |
|
|
3103 |
} // namespace QSampler |
} // namespace QSampler |
3104 |
|
|
3105 |
|
|