// qcoreapplication.sip generated by MetaSIP
//
// This file is part of the QtCore Python extension module.
//
// Copyright (c) 2024 Riverbank Computing Limited <info@riverbankcomputing.com>
// 
// This file is part of PyQt5.
// 
// This file may be used under the terms of the GNU General Public License
// version 3.0 as published by the Free Software Foundation and appearing in
// the file LICENSE included in the packaging of this file.  Please review the
// following information to ensure the GNU General Public License version 3.0
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
// 
// If you do not wish to use this file under the terms of the GPL version 3.0
// then you may purchase a commercial license.  For more information contact
// info@riverbankcomputing.com.
// 
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.


%ModuleCode
#include <qcoreapplication.h>
%End

class QCoreApplication : public QObject
{
%TypeHeaderCode
#include <qcoreapplication.h>
%End

public:
    QCoreApplication(SIP_PYLIST argv /TypeHint="List[str]"/) /PostHook=__pyQtQAppHook__/ [(int &argc, char **argv)];
%MethodCode
        // The Python interface is a list of argument strings that is modified.
        
        int argc;
        char **argv;
        
        // Convert the list.
        if ((argv = pyqt5_from_argv_list(a0, argc)) == NULL)
            sipIsErr = 1;
        else
        {
            // Create it now the arguments are right.
            static int nargc;
            nargc = argc;
        
            Py_BEGIN_ALLOW_THREADS
            sipCpp = new sipQCoreApplication(nargc, argv);
            Py_END_ALLOW_THREADS
        
            // Now modify the original list.
            pyqt5_update_argv_list(a0, argc, argv);
        }
%End

    virtual ~QCoreApplication() /ReleaseGIL/;
%MethodCode
        pyqt5_cleanup_qobjects();
%End

    static void setOrganizationDomain(const QString &orgDomain);
    static QString organizationDomain();
    static void setOrganizationName(const QString &orgName);
    static QString organizationName();
    static void setApplicationName(const QString &application);
    static QString applicationName();
    static QStringList arguments();
    static QCoreApplication *instance();
    static int exec() /PostHook=__pyQtPostEventLoopHook__,PreHook=__pyQtPreEventLoopHook__,PyName=exec_,ReleaseGIL/;
%If (Py_v3)
    static int exec() /PostHook=__pyQtPostEventLoopHook__,PreHook=__pyQtPreEventLoopHook__,ReleaseGIL/;
%End
    static void processEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::ProcessEventsFlag::AllEvents) /ReleaseGIL/;
    static void processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime) /ReleaseGIL/;
    static void exit(int returnCode = 0);
    static bool sendEvent(QObject *receiver, QEvent *event) /ReleaseGIL/;
    static void postEvent(QObject *receiver, QEvent *event /Transfer/, int priority = Qt::EventPriority::NormalEventPriority);
    static void sendPostedEvents(QObject *receiver = 0, int eventType = 0) /ReleaseGIL/;
    static void removePostedEvents(QObject *receiver, int eventType = 0);
    static bool hasPendingEvents();
    virtual bool notify(QObject *, QEvent *) /ReleaseGIL/;
    static bool startingUp();
    static bool closingDown();
    static QString applicationDirPath();
    static QString applicationFilePath();
    static void setLibraryPaths(const QStringList &);
    static QStringList libraryPaths();
    static void addLibraryPath(const QString &);
    static void removeLibraryPath(const QString &);
    static bool installTranslator(QTranslator *messageFile);
    static bool removeTranslator(QTranslator *messageFile);
    static QString translate(const char *context, const char *sourceText /Encoding="UTF-8"/, const char *disambiguation = 0, int n = -1);
    static void flush() /ReleaseGIL/;
    static void setAttribute(Qt::ApplicationAttribute attribute, bool on = true);
    static bool testAttribute(Qt::ApplicationAttribute attribute);

public slots:
    static void quit();

signals:
    void aboutToQuit();

protected:
    virtual bool event(QEvent *);

public:
    static void setApplicationVersion(const QString &version);
    static QString applicationVersion();
    static qint64 applicationPid();
    static QAbstractEventDispatcher *eventDispatcher();
    static void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher /Transfer/);
    static bool isQuitLockEnabled();
    static void setQuitLockEnabled(bool enabled);
    void installNativeEventFilter(QAbstractNativeEventFilter *filterObj);
    void removeNativeEventFilter(QAbstractNativeEventFilter *filterObj);
%If (Qt_5_3_0 -)
    static void setSetuidAllowed(bool allow);
%End
%If (Qt_5_3_0 -)
    static bool isSetuidAllowed();
%End
    SIP_PYOBJECT __enter__();
%MethodCode
        // Just return a reference to self.
        sipRes = sipSelf;
        Py_INCREF(sipRes);
%End

    void __exit__(SIP_PYOBJECT type, SIP_PYOBJECT value, SIP_PYOBJECT traceback);
%MethodCode
        // Make sure the QCoreApplication is destroyed.
        delete sipCpp;
%End
};

void qAddPostRoutine(SIP_PYCALLABLE);
%MethodCode
    // Add it to the list of post routines if it already exists.
    if (qtcore_PostRoutines != NULL)
    {
        // See if there is an empty slot.
        bool app = true;
    
        for (Py_ssize_t i = 0; i < PyList_Size(qtcore_PostRoutines); ++i)
            if (PyList_GetItem(qtcore_PostRoutines, i) == Py_None)
            {
                Py_INCREF(a0);
                PyList_SetItem(qtcore_PostRoutines, i, a0);
    
                app = false;
    
                break;
            }
    
        if (app && PyList_Append(qtcore_PostRoutines, a0) < 0)
            sipIsErr = 1;
    }
    else if ((qtcore_PostRoutines = PyList_New(1)) != NULL)
    {
        Py_INCREF(a0);
        PyList_SetItem(qtcore_PostRoutines, 0, a0);
    
        qAddPostRoutine(qtcore_CallPostRoutines);
    }
    else
    {
        sipIsErr = 1;
    }
%End

void qRemovePostRoutine(SIP_PYCALLABLE);
%MethodCode
    // Remove it from the list of post routines if it exists.
    if (qtcore_PostRoutines != NULL)
        for (Py_ssize_t i = 0; i < PyList_Size(qtcore_PostRoutines); ++i)
            if (PyList_GetItem(qtcore_PostRoutines, i) == a0)
            {
                Py_INCREF(Py_None);
                PyList_SetItem(qtcore_PostRoutines, i, Py_None);
    
                break;
            }
%End

%If (Qt_5_1_0 -)
void qAddPreRoutine(SIP_PYCALLABLE routine /TypeHint="Callable[[], None]"/);
%MethodCode
    // Add it to the list of pre routines if it already exists.
    if (qtcore_PreRoutines != NULL)
    {
        if (PyList_Append(qtcore_PreRoutines, a0) < 0)
            sipIsErr = 1;
    }
    else if ((qtcore_PreRoutines = PyList_New(1)) != NULL)
    {
        Py_INCREF(a0);
        PyList_SetItem(qtcore_PreRoutines, 0, a0);
    
        qAddPreRoutine(qtcore_CallPreRoutines);
    }
    else
    {
        sipIsErr = 1;
    }
%End

%End
// Module code needed by qAddPreRoutine, qAddPostRoutine() and qRemovePostRoutine().
%ModuleCode
#if QT_VERSION >= 0x050100
// The list of Python pre routines.
static PyObject *qtcore_PreRoutines = NULL;

// Call all of the registered Python pre routines.
static void qtcore_CallPreRoutines()
{
    for (Py_ssize_t i = 0; i < PyList_Size(qtcore_PreRoutines); ++i)
    {
        PyObject *pr = PyList_GetItem(qtcore_PreRoutines, i);

        if (pr != Py_None)
        {
            PyObject *res = PyObject_CallObject(pr, NULL);

            Py_XDECREF(res);
        }
    }
}
#endif


// The list of Python post routines.
static PyObject *qtcore_PostRoutines = NULL;

// Call all of the registered Python post routines.
static void qtcore_CallPostRoutines()
{
    for (Py_ssize_t i = 0; i < PyList_Size(qtcore_PostRoutines); ++i)
    {
        PyObject *pr = PyList_GetItem(qtcore_PostRoutines, i);

        if (pr != Py_None)
        {
            PyObject *res = PyObject_CallObject(pr, NULL);

            Py_XDECREF(res);
        }
    }
}
%End
void pyqtRemoveInputHook();
%MethodCode
    // Clear the Python input hook installed when the module was initialised.
    PyOS_InputHook = 0;
%End

void pyqtRestoreInputHook();
%MethodCode
    // Restore the input hook.
    PyOS_InputHook = qtcore_input_hook;
%End

%ModuleCode
#include <QCoreApplication>
#include <QThread>

#if defined(Q_OS_WIN)
#include <conio.h>
#include <QTimer>
#else
#include <QSocketNotifier>
#endif

// This is the input hook that will process events while the interpreter is
// waiting for interactive input.
extern "C" {static int qtcore_input_hook();}

static int qtcore_input_hook()
{
    QCoreApplication *app = QCoreApplication::instance();

    if (app && app->thread() == QThread::currentThread())
    {
#if defined(Q_OS_WIN)
        QTimer timer;
        QObject::connect(&timer, SIGNAL(timeout()), app, SLOT(quit()));

        while (!_kbhit())
        {
            // The delay is based on feedback from users.
            timer.start(35);
            QCoreApplication::exec();
            timer.stop();
        }

        QObject::disconnect(&timer, SIGNAL(timeout()), app, SLOT(quit()));
#else
        QSocketNotifier notifier(0, QSocketNotifier::Read, 0);
        QObject::connect(&notifier, SIGNAL(activated(int)), app, SLOT(quit()));
        QCoreApplication::exec();
        QObject::disconnect(&notifier, SIGNAL(activated(int)), app, SLOT(quit()));
#endif
    }

    return 0;
}
%End

%PostInitialisationCode
// Process events from the input hook.
PyOS_InputHook = qtcore_input_hook;
%End

%ExportedTypeHintCode
# Support for QDate, QDateTime and QTime.
import datetime

# Convenient type aliases.
PYQT_SIGNAL = typing.Union[QtCore.pyqtSignal, QtCore.pyqtBoundSignal]
PYQT_SLOT = typing.Union[typing.Callable[..., Any], QtCore.pyqtBoundSignal]
%End

%TypeHintCode
# Support for QDate, QDateTime and QTime.
import datetime

# Support for Q_ENUM and Q_FLAG.
import enum


# Support for new-style signals and slots.
class pyqtSignal:

    signatures = ...    # type: typing.Tuple[str, ...]

    def __init__(self, *types: typing.Any, name: str = ...) -> None: ...

    @typing.overload
    def __get__(self, instance: None, owner: typing.Type['QObject']) -> 'pyqtSignal': ...

    @typing.overload
    def __get__(self, instance: 'QObject', owner: typing.Type['QObject']) -> 'pyqtBoundSignal': ...



class pyqtBoundSignal:

    signal = ...        # type: str

    def __getitem__(self, key: object) -> 'pyqtBoundSignal': ...

    def connect(self, slot: 'PYQT_SLOT') -> 'QMetaObject.Connection': ...

    @typing.overload
    def disconnect(self) -> None: ...

    @typing.overload
    def disconnect(self, slot: typing.Union['PYQT_SLOT', 'QMetaObject.Connection']) -> None: ...

    def emit(self, *args: typing.Any) -> None: ...


FuncT = typing.TypeVar('FuncT', bound=typing.Callable)
def pyqtSlot(*types, name: typing.Optional[str] = ..., result: typing.Optional[str] = ...) -> typing.Callable[[FuncT], FuncT]: ...


# For QObject.findChild() and QObject.findChildren().
QObjectT = typing.TypeVar('QObjectT', bound=QObject)


# Convenient type aliases.
PYQT_SIGNAL = typing.Union[pyqtSignal, pyqtBoundSignal]
PYQT_SLOT = typing.Union[typing.Callable[..., None], pyqtBoundSignal]
%End
