Files
wxWidgets/src/qt/evtloop.cpp
Mariano Reingart 8fc5475e15 Update author's credits comments for wxQT
Commit history was lost in the git to svn merge for trunk, so this reflect work done in two GSOC projects and/or by several authors.
Lines changed by each user was the main metric used to ack major contributions.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@77497 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2014-08-29 03:37:46 +00:00

256 lines
6.8 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/qt/evtloop.cpp
// Author: Mariano Reingart, Peter Most, Sean D'Epagnier, Javier Torres
// Copyright: (c) 2010 wxWidgets dev team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/app.h"
#include "wx/apptrait.h"
#include "wx/evtloop.h"
#include "wx/private/eventloopsourcesmanager.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/QSocketNotifier>
wxQtIdleTimer::wxQtIdleTimer( wxQtEventLoopBase *eventLoop )
{
m_eventLoop = eventLoop;
connect( this, &QTimer::timeout, this, &wxQtIdleTimer::idle );
setSingleShot( true );
start( 0 );
}
bool wxQtIdleTimer::eventFilter( QObject *WXUNUSED( watched ), QEvent *WXUNUSED( event ) )
{
// Called for each Qt event, start with timeout 0 (run as soon as idle)
if ( !isActive() )
start( 0 );
return false; // Continue handling the event
}
void wxQtIdleTimer::idle()
{
// Process pending events
if ( wxTheApp )
wxTheApp->ProcessPendingEvents();
// Send idle event
if ( m_eventLoop->ProcessIdle() )
start( 0 );
}
wxQtEventLoopBase::wxQtEventLoopBase()
{
// We need a QCoreApplication for event loops, create it here if it doesn't
// already exist as we can't modify wxConsoleApp
if ( !QCoreApplication::instance() )
{
new QApplication( wxAppConsole::GetInstance()->argc, wxAppConsole::GetInstance()->argv );
}
// Create an idle timer to run each time there are no events (timeout = 0)
m_qtIdleTimer = new wxQtIdleTimer( this );
// Pass all events to the idle timer, so it can be restarted each time
// an event is received
qApp->installEventFilter( m_qtIdleTimer );
}
wxQtEventLoopBase::~wxQtEventLoopBase()
{
delete m_qtIdleTimer;
}
void wxQtEventLoopBase::ScheduleExit(int rc)
{
wxCHECK_RET( IsInsideRun(), wxT("can't call ScheduleExit() if not started") );
m_shouldExit = true;
QCoreApplication::exit( rc );
}
int wxQtEventLoopBase::DoRun()
{
int ret;
// This is placed inside of a loop to take into account nested event loops
while ( !m_shouldExit )
{
// This will print Qt warnins if app already started:
// "QCoreApplication::exec: The event loop is already running"
// TODO: check the loopLevel (nested) like in wxGTK
ret = QCoreApplication::exec();
// process pending events (if exec was started previously)
// TODO: use a real new QEventLoop() ?
QCoreApplication::processEvents();
}
OnExit();
return ret;
}
bool wxQtEventLoopBase::Pending() const
{
return QCoreApplication::hasPendingEvents();
}
bool wxQtEventLoopBase::Dispatch()
{
QCoreApplication::processEvents();
return true;
}
int wxQtEventLoopBase::DispatchTimeout(unsigned long timeout)
{
QCoreApplication::processEvents( QEventLoop::AllEvents, timeout );
return true;
}
void wxQtEventLoopBase::WakeUp()
{
QAbstractEventDispatcher::instance()->wakeUp();
}
void wxQtEventLoopBase::DoYieldFor(long eventsToProcess)
{
while (wxTheApp && wxTheApp->Pending())
// TODO: implement event filtering using the eventsToProcess mask
wxTheApp->Dispatch();
wxEventLoopBase::DoYieldFor(eventsToProcess);
}
#if wxUSE_EVENTLOOP_SOURCE
template <void (wxEventLoopSourceHandler::*function)()>
class wxQtSocketNotifier : public QSocketNotifier
{
public:
wxQtSocketNotifier(int fd, Type type, wxEventLoopSourceHandler *handler)
: QSocketNotifier(fd, type),
m_handler(handler)
{
setEnabled(true);
connect(this, &wxQtSocketNotifier::activated, this, &wxQtSocketNotifier::OnWaiting);
}
void OnWaiting()
{
(m_handler->*function)();
}
wxEventLoopSourceHandler *m_handler;
};
class wxQtEventLoopSource : public wxEventLoopSource
{
public:
wxQtSocketNotifier<&wxEventLoopSourceHandler::OnReadWaiting> * m_reader;
wxQtSocketNotifier<&wxEventLoopSourceHandler::OnWriteWaiting> * m_writer;
wxQtSocketNotifier<&wxEventLoopSourceHandler::OnExceptionWaiting> * m_exception;
wxQtEventLoopSource(int fd, wxEventLoopSourceHandler *handler, int flags)
: wxEventLoopSource(handler, fd)
{
if ( flags & wxEVENT_SOURCE_INPUT )
m_reader = new wxQtSocketNotifier<&wxEventLoopSourceHandler::OnReadWaiting>
(fd, QSocketNotifier::Read, handler);
else
m_reader = NULL;
if ( flags & wxEVENT_SOURCE_OUTPUT )
m_writer = new wxQtSocketNotifier<&wxEventLoopSourceHandler::OnWriteWaiting>
(fd, QSocketNotifier::Write, handler);
else
m_writer = NULL;
if ( flags & wxEVENT_SOURCE_EXCEPTION )
m_exception = new wxQtSocketNotifier<&wxEventLoopSourceHandler::OnExceptionWaiting>
(fd, QSocketNotifier::Exception, handler);
else
m_exception = NULL;
}
virtual ~wxQtEventLoopSource()
{
// clean up notifiers
if (m_reader)
delete m_reader;
if (m_writer)
delete m_writer;
if (m_exception)
delete m_exception;
}
};
class wxQtEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
{
public:
wxEventLoopSource*
AddSourceForFD(int fd, wxEventLoopSourceHandler* handler, int flags)
{
return new wxQtEventLoopSource(fd, handler, flags);
}
};
wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
{
static wxQtEventLoopSourcesManager s_eventLoopSourcesManager;
return &s_eventLoopSourcesManager;
}
#if !wxUSE_CONSOLE_EVENTLOOP
// Use the GUI event loop sources manager if console support is disabled
// (needed by some common code, will raise an undefinied reference if not done)
wxEventLoopSourcesManagerBase* wxAppTraits::GetEventLoopSourcesManager()
{
static wxQtEventLoopSourcesManager s_eventLoopSourcesManager;
return &s_eventLoopSourcesManager;
}
#endif
wxEventLoopSource *wxQtEventLoopBase::AddSourceForFD(int fd, wxEventLoopSourceHandler *handler, int flags)
{
wxGUIAppTraits *AppTraits = dynamic_cast<wxGUIAppTraits *>(wxApp::GetTraitsIfExists());
if(AppTraits)
return AppTraits->GetEventLoopSourcesManager()->AddSourceForFD(fd, handler, flags);
return NULL;
}
#endif // wxUSE_EVENTLOOP_SOURCE
//#############################################################################
#if wxUSE_GUI
wxGUIEventLoop::wxGUIEventLoop()
{
}
#else // !wxUSE_GUI
//#############################################################################
#if wxUSE_CONSOLE_EVENTLOOP
wxConsoleEventLoop::wxConsoleEventLoop()
{
}
#endif // wxUSE_CONSOLE_EVENTLOOP
#endif // wxUSE_GUI