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

Diff of /qsampler/trunk/src/qsamplerMainForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1840 by capela, Thu Feb 19 11:44:57 2009 UTC revision 2113 by capela, Thu Jul 22 08:12:12 2010 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2009, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2010, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, 2008 Christian Schoenebeck     Copyright (C) 2007, 2008 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
# Line 56  Line 56 
56  #include <QTimer>  #include <QTimer>
57  #include <QDateTime>  #include <QDateTime>
58    
59    #if QT_VERSION < 0x040500
60    namespace Qt {
61    const WindowFlags WindowCloseButtonHint = WindowFlags(0x08000000);
62    #if QT_VERSION < 0x040200
63    const WindowFlags CustomizeWindowHint   = WindowFlags(0x02000000);
64    #endif
65    }
66    #endif
67    
68  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
69  #include <signal.h>  #include <signal.h>
# Line 85  static WSADATA _wsaData; Line 93  static WSADATA _wsaData;
93  #endif  #endif
94    
95    
96    //-------------------------------------------------------------------------
97    // LADISH Level 1 support stuff.
98    
99    #ifdef HAVE_SIGNAL_H
100    
101    #include <QSocketNotifier>
102    
103    #include <sys/types.h>
104    #include <sys/socket.h>
105    
106    #include <signal.h>
107    
108    // File descriptor for SIGUSR1 notifier.
109    static int g_fdUsr1[2];
110    
111    // Unix SIGUSR1 signal handler.
112    static void qsampler_sigusr1_handler ( int /* signo */ )
113    {
114            char c = 1;
115    
116            (::write(g_fdUsr1[0], &c, sizeof(c)) > 0);
117    }
118    
119    #endif  // HAVE_SIGNAL_H
120    
121    
122    //-------------------------------------------------------------------------
123    // qsampler -- namespace
124    
125    
126  namespace QSampler {  namespace QSampler {
127    
128  // Timer constant stuff.  // Timer constant stuff.
# Line 97  namespace QSampler { Line 135  namespace QSampler {
135  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
136    
137    
138    // Specialties for thread-callback comunication.
139    #define QSAMPLER_LSCP_EVENT   QEvent::Type(QEvent::User + 1)
140    
141    
142  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
143  // CustomEvent -- specialty for callback comunication.  // LscpEvent -- specialty for LSCP callback comunication.
144    
 #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  
145    
146  class CustomEvent : public QEvent  class LscpEvent : public QEvent
147  {  {
148  public:  public:
149    
150          // Constructor.          // Constructor.
151          CustomEvent(lscp_event_t event, const char *pchData, int cchData)          LscpEvent(lscp_event_t event, const char *pchData, int cchData)
152                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_LSCP_EVENT)
153          {          {
154                  m_event = event;                  m_event = event;
155                  m_data  = QString::fromUtf8(pchData, cchData);                  m_data  = QString::fromUtf8(pchData, cchData);
# Line 162  MainForm::MainForm ( QWidget *pParent ) Line 203  MainForm::MainForm ( QWidget *pParent )
203          m_iTimerSlot = 0;          m_iTimerSlot = 0;
204    
205  #ifdef HAVE_SIGNAL_H  #ifdef HAVE_SIGNAL_H
206    
207          // Set to ignore any fatal "Broken pipe" signals.          // Set to ignore any fatal "Broken pipe" signals.
208          ::signal(SIGPIPE, SIG_IGN);          ::signal(SIGPIPE, SIG_IGN);
209  #endif  
210            // LADISH Level 1 suport.
211    
212            // Initialize file descriptors for SIGUSR1 socket notifier.
213            ::socketpair(AF_UNIX, SOCK_STREAM, 0, g_fdUsr1);
214            m_pUsr1Notifier
215                    = new QSocketNotifier(g_fdUsr1[1], QSocketNotifier::Read, this);
216    
217            QObject::connect(m_pUsr1Notifier,
218                    SIGNAL(activated(int)),
219                    SLOT(handle_sigusr1()));
220    
221            // Install SIGUSR1 signal handler.
222        struct sigaction usr1;
223        usr1.sa_handler = qsampler_sigusr1_handler;
224        ::sigemptyset(&usr1.sa_mask);
225        usr1.sa_flags = 0;
226        usr1.sa_flags |= SA_RESTART;
227        ::sigaction(SIGUSR1, &usr1, NULL);
228    
229    #else   // HAVE_SIGNAL_H
230    
231            m_pUsr1Notifier = NULL;
232            
233    #endif  // !HAVE_SIGNAL_H
234    
235  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
236          // Make some extras into the toolbar...          // Make some extras into the toolbar...
# Line 337  MainForm::~MainForm() Line 403  MainForm::~MainForm()
403          WSACleanup();          WSACleanup();
404  #endif  #endif
405    
406    #ifdef HAVE_SIGNAL_H
407            if (m_pUsr1Notifier)
408                    delete m_pUsr1Notifier;
409    #endif
410    
411          // Finally drop any widgets around...          // Finally drop any widgets around...
412          if (m_pDeviceForm)          if (m_pDeviceForm)
413                  delete m_pDeviceForm;                  delete m_pDeviceForm;
# Line 375  void MainForm::setup ( Options *pOptions Line 446  void MainForm::setup ( Options *pOptions
446    
447          // What style do we create these forms?          // What style do we create these forms?
448          Qt::WindowFlags wflags = Qt::Window          Qt::WindowFlags wflags = Qt::Window
 #if QT_VERSION >= 0x040200  
449                  | Qt::CustomizeWindowHint                  | Qt::CustomizeWindowHint
 #endif  
450                  | Qt::WindowTitleHint                  | Qt::WindowTitleHint
451                  | Qt::WindowSystemMenuHint                  | Qt::WindowSystemMenuHint
452                  | Qt::WindowMinMaxButtonsHint;                  | Qt::WindowMinMaxButtonsHint
453                    | Qt::WindowCloseButtonHint;
454          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
455                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
456    
457          // Some child forms are to be created right now.          // Some child forms are to be created right now.
458          m_pMessages = new Messages(this);          m_pMessages = new Messages(this);
459          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
460  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
461          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
462  #else  #else
463          viewInstrumentsAction->setEnabled(false);          m_ui.viewInstrumentsAction->setEnabled(false);
464  #endif  #endif
465    
466          // Setup messages logging appropriately...          // Setup messages logging appropriately...
467          m_pMessages->setLogging(          m_pMessages->setLogging(
468                  m_pOptions->bMessagesLog,                  m_pOptions->bMessagesLog,
469                  m_pOptions->sMessagesLogPath);                  m_pOptions->sMessagesLogPath);
470    
471          // Set message defaults...          // Set message defaults...
472          updateMessagesFont();          updateMessagesFont();
473          updateMessagesLimit();          updateMessagesLimit();
# Line 425  void MainForm::setup ( Options *pOptions Line 498  void MainForm::setup ( Options *pOptions
498          }          }
499    
500          // Try to restore old window positioning and initial visibility.          // Try to restore old window positioning and initial visibility.
501          m_pOptions->loadWidgetGeometry(this);          m_pOptions->loadWidgetGeometry(this, true);
502          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);          m_pOptions->loadWidgetGeometry(m_pInstrumentListForm);
503          m_pOptions->loadWidgetGeometry(m_pDeviceForm);          m_pOptions->loadWidgetGeometry(m_pDeviceForm);
504    
# Line 469  bool MainForm::queryClose (void) Line 542  bool MainForm::queryClose (void)
542                          // And the children, and the main windows state,.                          // And the children, and the main windows state,.
543                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);                          m_pOptions->saveWidgetGeometry(m_pDeviceForm);
544                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);                          m_pOptions->saveWidgetGeometry(m_pInstrumentListForm);
545                          m_pOptions->saveWidgetGeometry(this);                          m_pOptions->saveWidgetGeometry(this, true);
546                          // Close popup widgets.                          // Close popup widgets.
547                          if (m_pInstrumentListForm)                          if (m_pInstrumentListForm)
548                                  m_pInstrumentListForm->close();                                  m_pInstrumentListForm->close();
# Line 518  void MainForm::dropEvent ( QDropEvent* p Line 591  void MainForm::dropEvent ( QDropEvent* p
591                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
592                  while (iter.hasNext()) {                  while (iter.hasNext()) {
593                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
594                          if (Channel::isInstrumentFile(sPath)) {                  //      if (Channel::isDlsInstrumentFile(sPath)) {
595                            if (QFileInfo(sPath).exists()) {
596                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
597                                  Channel *pChannel = new Channel();                                  Channel *pChannel = new Channel();
598                                  if (pChannel == NULL)                                  if (pChannel == NULL)
# Line 552  void MainForm::dropEvent ( QDropEvent* p Line 626  void MainForm::dropEvent ( QDropEvent* p
626    
627    
628  // Custome event handler.  // Custome event handler.
629  void MainForm::customEvent(QEvent* pCustomEvent)  void MainForm::customEvent ( QEvent* pEvent )
630  {  {
631          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
632          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pEvent->type() == QSAMPLER_LSCP_EVENT) {
633                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);                  LscpEvent *pLscpEvent = static_cast<LscpEvent *> (pEvent);
634                  switch (pEvent->event()) {                  switch (pLscpEvent->event()) {
635                          case LSCP_EVENT_CHANNEL_COUNT:                          case LSCP_EVENT_CHANNEL_COUNT:
636                                  updateAllChannelStrips(true);                                  updateAllChannelStrips(true);
637                                  break;                                  break;
638                          case LSCP_EVENT_CHANNEL_INFO: {                          case LSCP_EVENT_CHANNEL_INFO: {
639                                  int iChannelID = pEvent->data().toInt();                                  int iChannelID = pLscpEvent->data().toInt();
640                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
641                                  if (pChannelStrip)                                  if (pChannelStrip)
642                                          channelStripChanged(pChannelStrip);                                          channelStripChanged(pChannelStrip);
# Line 575  void MainForm::customEvent(QEvent* pCust Line 649  void MainForm::customEvent(QEvent* pCust
649                                  break;                                  break;
650                          case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {                          case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
651                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
652                                  const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
653                                  DeviceStatusForm::onDeviceChanged(iDeviceID);                                  DeviceStatusForm::onDeviceChanged(iDeviceID);
654                                  break;                                  break;
655                          }                          }
# Line 585  void MainForm::customEvent(QEvent* pCust Line 659  void MainForm::customEvent(QEvent* pCust
659                          case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:                          case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
660                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();                                  if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
661                                  break;                                  break;
662  #if CONFIG_EVENT_CHANNEL_MIDI                  #if CONFIG_EVENT_CHANNEL_MIDI
663                          case LSCP_EVENT_CHANNEL_MIDI: {                          case LSCP_EVENT_CHANNEL_MIDI: {
664                                  const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iChannelID = pLscpEvent->data().section(' ', 0, 0).toInt();
665                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
666                                  if (pChannelStrip)                                  if (pChannelStrip)
667                                          pChannelStrip->midiArrived();                                          pChannelStrip->midiActivityLedOn();
668                                  break;                                  break;
669                          }                          }
670  #endif                  #endif
671  #if CONFIG_EVENT_DEVICE_MIDI                  #if CONFIG_EVENT_DEVICE_MIDI
672                          case LSCP_EVENT_DEVICE_MIDI: {                          case LSCP_EVENT_DEVICE_MIDI: {
673                                  const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();                                  const int iDeviceID = pLscpEvent->data().section(' ', 0, 0).toInt();
674                                  const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();                                  const int iPortID   = pLscpEvent->data().section(' ', 1, 1).toInt();
675                                  DeviceStatusForm* pDeviceStatusForm =                                  DeviceStatusForm *pDeviceStatusForm
676                                          DeviceStatusForm::getInstance(iDeviceID);                                          = DeviceStatusForm::getInstance(iDeviceID);
677                                  if (pDeviceStatusForm)                                  if (pDeviceStatusForm)
678                                          pDeviceStatusForm->midiArrived(iPortID);                                          pDeviceStatusForm->midiArrived(iPortID);
679                                  break;                                  break;
680                          }                          }
681  #endif                  #endif
682                          default:                          default:
683                                  appendMessagesColor(tr("Notify event: %1 data: %2")                                  appendMessagesColor(tr("LSCP Event: %1 data: %2")
684                                          .arg(::lscp_event_to_text(pEvent->event()))                                          .arg(::lscp_event_to_text(pLscpEvent->event()))
685                                          .arg(pEvent->data()), "#996699");                                          .arg(pLscpEvent->data()), "#996699");
686                  }                  }
687          }          }
688  }  }
689    
690  void MainForm::updateViewMidiDeviceStatusMenu() {  
691    // LADISH Level 1 -- SIGUSR1 signal handler.
692    void MainForm::handle_sigusr1 (void)
693    {
694    #ifdef HAVE_SIGNAL_H
695    
696            char c;
697    
698            if (::read(g_fdUsr1[1], &c, sizeof(c)) > 0)
699                    saveSession(false);
700    
701    #endif
702    }
703    
704    
705    void MainForm::updateViewMidiDeviceStatusMenu (void)
706    {
707          m_ui.viewMidiDeviceStatusMenu->clear();          m_ui.viewMidiDeviceStatusMenu->clear();
708          const std::map<int, DeviceStatusForm*> statusForms =          const std::map<int, DeviceStatusForm *> statusForms
709                  DeviceStatusForm::getInstances();                  = DeviceStatusForm::getInstances();
710          for (          std::map<int, DeviceStatusForm *>::const_iterator iter
711                  std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();                  = statusForms.begin();
712                  iter != statusForms.end(); ++iter          for ( ; iter != statusForms.end(); ++iter) {
713          ) {                  DeviceStatusForm *pStatusForm = iter->second;
                 DeviceStatusForm* pForm = iter->second;  
714                  m_ui.viewMidiDeviceStatusMenu->addAction(                  m_ui.viewMidiDeviceStatusMenu->addAction(
715                          pForm->visibleAction()                          pStatusForm->visibleAction());
                 );  
716          }          }
717  }  }
718    
719    
720  // Context menu event handler.  // Context menu event handler.
721  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
722  {  {
# Line 1870  void MainForm::stabilizeForm (void) Line 1959  void MainForm::stabilizeForm (void)
1959          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));          setWindowTitle(tr(QSAMPLER_TITLE " - [%1]").arg(sSessionName));
1960    
1961          // Update the main menu state...          // Update the main menu state...
1962          ChannelStrip* pChannelStrip = activeChannelStrip();          ChannelStrip *pChannelStrip = activeChannelStrip();
1963          bool bHasClient  = (m_pOptions != NULL && m_pClient != NULL);          bool bHasClient = (m_pOptions != NULL && m_pClient != NULL);
1964          bool bHasChannel = (bHasClient && pChannelStrip != NULL);          bool bHasChannel = (bHasClient && pChannelStrip != NULL);
1965            bool bHasChannels = (bHasClient && m_pWorkspace->windowList().count() > 0);
1966          m_ui.fileNewAction->setEnabled(bHasClient);          m_ui.fileNewAction->setEnabled(bHasClient);
1967          m_ui.fileOpenAction->setEnabled(bHasClient);          m_ui.fileOpenAction->setEnabled(bHasClient);
1968          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);          m_ui.fileSaveAction->setEnabled(bHasClient && m_iDirtyCount > 0);
# Line 1888  void MainForm::stabilizeForm (void) Line 1978  void MainForm::stabilizeForm (void)
1978          m_ui.editEditChannelAction->setEnabled(false);          m_ui.editEditChannelAction->setEnabled(false);
1979  #endif  #endif
1980          m_ui.editResetChannelAction->setEnabled(bHasChannel);          m_ui.editResetChannelAction->setEnabled(bHasChannel);
1981          m_ui.editResetAllChannelsAction->setEnabled(bHasChannel);          m_ui.editResetAllChannelsAction->setEnabled(bHasChannels);
1982          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());          m_ui.viewMessagesAction->setChecked(m_pMessages && m_pMessages->isVisible());
1983  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
1984          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm          m_ui.viewInstrumentsAction->setChecked(m_pInstrumentListForm
# Line 1900  void MainForm::stabilizeForm (void) Line 1990  void MainForm::stabilizeForm (void)
1990          m_ui.viewDevicesAction->setChecked(m_pDeviceForm          m_ui.viewDevicesAction->setChecked(m_pDeviceForm
1991                  && m_pDeviceForm->isVisible());                  && m_pDeviceForm->isVisible());
1992          m_ui.viewDevicesAction->setEnabled(bHasClient);          m_ui.viewDevicesAction->setEnabled(bHasClient);
1993          m_ui.channelsArrangeAction->setEnabled(bHasChannel);          m_ui.viewMidiDeviceStatusMenu->setEnabled(
1994                    DeviceStatusForm::getInstances().size() > 0);
1995            m_ui.channelsArrangeAction->setEnabled(bHasChannels);
1996    
1997  #ifdef CONFIG_VOLUME  #ifdef CONFIG_VOLUME
1998          // Toolbar widgets are also affected...          // Toolbar widgets are also affected...
# Line 2601  void MainForm::stopServer (bool bInterac Line 2693  void MainForm::stopServer (bool bInterac
2693                          "running in the background. The sampler would continue to work\n"                          "running in the background. The sampler would continue to work\n"
2694                          "according to your current sampler session and you could alter the\n"                          "according to your current sampler session and you could alter the\n"
2695                          "sampler session at any time by relaunching QSampler.\n\n"                          "sampler session at any time by relaunching QSampler.\n\n"
2696                          "Do you want LinuxSampler to stop or to keep running in\n"                          "Do you want LinuxSampler to stop?"),
                         "the background?"),  
2697                          QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)                          QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
2698                  {                  {
2699                          bForceServerStop = false;                          bForceServerStop = false;
# Line 2689  lscp_status_t qsampler_client_callback ( Line 2780  lscp_status_t qsampler_client_callback (
2780          // as this is run under some other thread context.          // as this is run under some other thread context.
2781          // A custom event must be posted here...          // A custom event must be posted here...
2782          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2783                  new CustomEvent(event, pchData, cchData));                  new LscpEvent(event, pchData, cchData));
2784    
2785          return LSCP_OK;          return LSCP_OK;
2786  }  }

Legend:
Removed from v.1840  
changed lines
  Added in v.2113

  ViewVC Help
Powered by ViewVC