<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qlandmarkabstractrequest.h"
#include "qlandmarkabstractrequest_p.h"
#include "qlandmarkmanagerengine.h"
#include "qlandmarkmanager_p.h"
#include <QDebug>
#include <QMutexLocker>

QTM_USE_NAMESPACE

QLandmarkAbstractRequestPrivate::QLandmarkAbstractRequestPrivate(QLandmarkManager *mgr)
    : type(QLandmarkAbstractRequest::InvalidRequest),
      state(QLandmarkAbstractRequest::InactiveState),
      error(QLandmarkManager::NoError),
      errorString(QString()),
      manager(mgr)
{
}

/*!
    \class QLandmarkAbstractRequest
    \brief The QLandmarkAbstractRequest class provides the interface
    from which all asynchronous request classes inherit.

    \inmodule QtLocation

    \ingroup landmarks-request

    It allows a client to asynchronously request some functionality of a
    particular QLandmarkManager. Instances of the class will emit signals when
    the state of the request changes, or when more results become available.

    Clients should not attempt to create instances of this class directly, but
    should instead use the use-case-specific classes derived from this class.

    All such request classes have a similar interface: clients set the
    parameters of the asynchronous call, then call the start() slot of the request. The manager
    will then enqueue or begin to process the request, at which point the
    request's state will transition from the \c InactiveState to \c ActiveState.
    After any state transition, the request will emit the stateChanged()
    signal. The manager may (if it supports it)
    periodically update the request with results, at
    which point the request will emit the resultsAvailable() signal. These
    results are not guaranteed to have a stable ordering. Error information is
    considered a result, so some requests will emit the resultsAvailable()
    signal even if no results are possible from the request (for example, a
    landmark remove request) when the manager updates the request with
    information about any errors which may have occurred.

    Clients can choose which signals they wish to handle from a request. If the
    client is not interested in interim results, they can choose to handle only
    the stateChanged() signal, and in the slot to which that signal is
    connected, check whether the state has changed to the \c FinishedState
    (which signifies that the manager has finished handling the request, and
    that the request will not be updated with any more results).  If the client
    is not interested in any results (including error information), they may
    choose to delete the request after calling \l start(), or simply may not
    connect the the request's signals to any slots.  (Please see the note
    below if you are working on Symbian with QtMobility 1.1.0)

    If the request is allocated via operator new, the client must delete the
    request when they are no longer using it in order to avoid leaking memory.
    That is, the client retains ownership of the request.

    The client may delete a heap-allocated request in various ways: by deleting
    it directly (but not within a slot connected to a signal emitted by the
    request), or by using the deleteLater() slot to schedule the request for
    deletion when control returns to the event loop (from within a slot
    connected to a signal emitted by the request, for example \l
    stateChanged()).

    An active request may be deleted by the client, but the client will
    not receive notifications about whether the request succeeded or not,
    nor the results of the request.

    Because clients retain ownership of any request object, and may delete a
    request object at any time, the manager engine,  implementers must be
    careful to ensue that they do not assume that a request has not been
    deleted at some time point during processing of a request, particularly
    if the engine has a multithreaded implementation.
*/

QLandmarkAbstractRequestPrivate::~QLandmarkAbstractRequestPrivate()
{
}

void QLandmarkAbstractRequestPrivate::notifyEngine(QLandmarkAbstractRequest* request)
{
        Q_ASSERT(request);
        QLandmarkAbstractRequestPrivate* d = request->d_ptr;
        if (d) {
            QMutexLocker ml(&d->mutex);
            QLandmarkManagerEngine *engine = QLandmarkManagerPrivate::getEngine(d->manager);
            ml.unlock();
            if (engine) {
                engine->requestDestroyed(request);
            }
        }
}

/*!
    \enum QLandmarkAbstractRequest::RequestType
    Defines the possible types of asynchronous requests.
    \value  InvalidRequest An invalid request
    \value  LandmarkIdFetchRequest A request to fetch a list of landmark
            identifiers.
    \value  CategoryIdFetchRequest A request to fetch a list of catgory
            identifiers.

    \value  LandmarkFetchRequest A request to fetch a list of landmarks
    \value  LandmarkFetchByIdRequest A request to fetch a list of landmarks by id.
    \value  CategoryFetchRequest A request to fetch a list of categories
    \value  CategoryFetchByIdRequest A request to fetch a list of categories by id
    \value  LandmarkSaveRequest A request to save a list of landmarks.
    \value  LandmarkRemoveRequest A request to remove a list of landmarks.
    \value  CategorySaveRequest A request to save a list of categories.
    \value  CategoryRemoveRequest A request to remove a list of categories.
    \value  ImportRequest A request import landmarks.
    \value  ExportRequest A request export landmarks.
*/

/*!
    \enum QLandmarkAbstractRequest::State
    Defines the possible states of asynchronous requests.
    \value  InactiveState Operation not yet started.
    \value  ActiveState Operation started, not yet finished.
    \value  FinishedState Operation completed.  (Can be mean either successful or
            unsuccessful completion).
*/

/*!
    Constructs a new, invalid asynchronous request with the given \a manager and \a parent.
*/
QLandmarkAbstractRequest::QLandmarkAbstractRequest(QLandmarkManager *manager, QObject *parent)
    : QObject(parent),
      d_ptr(new QLandmarkAbstractRequestPrivate(manager))
{
}

/*!
    \internal
*/
QLandmarkAbstractRequest::QLandmarkAbstractRequest(QLandmarkAbstractRequestPrivate *dd, QObject *parent)
    : QObject(parent),
     d_ptr(dd)
{
}

/*!
    Destroys the asynchronous request.  Because the request object is effectiely a handle to a
    request operation, the operation may continue or it may just be canceled, depending upon
    the enine implementation, even though the request itself has been destroyed.
    The sqlite engine continues the operation behind the scenes if the
    request is destroyed whilst active.  For the symbian engine see the note below.
*/
QLandmarkAbstractRequest::~QLandmarkAbstractRequest()
{
    QLandmarkAbstractRequestPrivate::notifyEngine(this);
    delete d_ptr;
}

/*!
    Returns the type of this asynchronous request.
*/
QLandmarkAbstractRequest::RequestType QLandmarkAbstractRequest::type() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->type;
}

/*!
    Returns the state of the request
*/
QLandmarkAbstractRequest::State QLandmarkAbstractRequest::state()
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Inactive state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isInactive() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::InactiveState;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Active state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isActive() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::ActiveState;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Finished state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isFinished() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::FinishedState;
}

/*!
    Returns the overall error of the most recent asynchronous operation.
    \sa errorString()
*/
QLandmarkManager::Error QLandmarkAbstractRequest::error() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->error;
}

/*!
    Returns a human readable string of the last error
    that occurred.  This error string is intended to be used
    by developers only and should not be seen by end users.
    \sa error()
*/
QString QLandmarkAbstractRequest::errorString() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->errorString;
}

/*!
    Returns a pointer to the landmark manager which
    this request operates on.
*/
QLandmarkManager *QLandmarkAbstractRequest::manager() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->manager;
}

/*!
    Sets the \a manager which this request operates on.

    Note that if a NULL manager is set, the functions
    start(), cancel() and waitForFinished() will return false and
    error will be set to QLandmarkManager::InvalidManagerError.

    A manager cannot be assigned while the request is in the
    QLandmarkAbstractRequest::ActiveState.
*/
void QLandmarkAbstractRequest::setManager(QLandmarkManager *manager)
{
    QMutexLocker ml(&d_ptr->mutex);
    if (d_ptr->state == QLandmarkAbstractRequest::ActiveState && d_ptr->manager)
        return;
    d_ptr->manager = manager;
}

/*!
    Attempts to start the request.

    Returns true if the request was started, otherwise false. Trying to start a
    request that is already active returns false.
    \sa cancel().
*/
bool QLandmarkAbstractRequest::start()
{
    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();
    if (!engine) {
        d_ptr->error = QLandmarkManager::InvalidManagerError;
        d_ptr->errorString = "The manager is invalid";
        return false;
    }

    if (d_ptr->state != QLandmarkAbstractRequest::ActiveState) {
        ml.unlock();
        return engine->startRequest(this);
    }
     else {
        return false;
     }
}

/*!
    Notifies the request that it should be canceled.

    Returns true if the request was successfully notified
    that it should be canceled.  The request may or may not honor
    the cancel notification.  Returns false if the notification
    could not be made or the request is not in the
    QLandmarkManager::Active state.

    \sa start()
*/
bool QLandmarkAbstractRequest::cancel()
{
    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();

    if(d_ptr->state == QLandmarkAbstractRequest::ActiveState) {
        ml.unlock();
        return engine->cancelRequest(this);
    }
    else
        return false;
}

/*!
    Blocks until the request has been completed or until \a msecs milliseconds
    has elapsed.  If \a msecs is zero or negative, this function will block indefinitely.

    Returns true if the request was canceled or completed
    within the given period, otherwise returns false.  Some backends may be unable
    to support this  operation safely and will return false immediately.
    The sqlite and sparql managers currently do not support waitForFinished(),
    while the symbian manager does. (with the exception of an import request,
    which will always return false on symbian when waitForFinished() is called).

    Note that any signals generated while waiting for the request to be complete
    may be queued and delivered sometime after this function has returned, when
    the calling thread's event loop is dispatched.  If your code depends on
    your slots being invoked, you may need to process events after calling
    this function.
*/
bool QLandmarkAbstractRequest::waitForFinished(int msecs)
{

    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();

    switch(d_ptr->state) {
        case QLandmarkAbstractRequest::ActiveState:
            ml.unlock();
            return engine->waitForRequestFinished(this, msecs);
        case QLandmarkAbstractRequest::FinishedState:
            return true;
        default:
            return false;
    }
    return false;
}

/*!
  \fn void QLandmarkAbstractRequest::resultsAvailable()
  This signal is emitted when new results are available.  Results
  can include the operation error which may be accessed via error(),
  or derived-class specific results which are accessible through
  the derived class API.

  \sa error()
*/

/*!
    \fn void QLandmarkAbstractRequest::stateChanged(QLandmarkAbstractRequest::State newState)
    This signal is emitted when the state of the request is changed.  The new state of
    the request will be contained in \a newState.
*/

#include "moc_qlandmarkabstractrequest.cpp"

<commit_msg>Update documentation<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qlandmarkabstractrequest.h"
#include "qlandmarkabstractrequest_p.h"
#include "qlandmarkmanagerengine.h"
#include "qlandmarkmanager_p.h"
#include <QDebug>
#include <QMutexLocker>

QTM_USE_NAMESPACE

QLandmarkAbstractRequestPrivate::QLandmarkAbstractRequestPrivate(QLandmarkManager *mgr)
    : type(QLandmarkAbstractRequest::InvalidRequest),
      state(QLandmarkAbstractRequest::InactiveState),
      error(QLandmarkManager::NoError),
      errorString(QString()),
      manager(mgr)
{
}

/*!
    \class QLandmarkAbstractRequest
    \brief The QLandmarkAbstractRequest class provides the interface
    from which all asynchronous request classes inherit.

    \inmodule QtLocation

    \ingroup landmarks-request

    It allows a client to asynchronously request some functionality of a
    particular QLandmarkManager. Instances of the class will emit signals when
    the state of the request changes, or when more results become available.

    Clients should not attempt to create instances of this class directly, but
    should instead use the use-case-specific classes derived from this class.

    All such request classes have a similar interface: clients set the
    parameters of the asynchronous call, then call the start() slot of the request. The manager
    will then enqueue or begin to process the request, at which point the
    request's state will transition from the \c InactiveState to \c ActiveState.
    After any state transition, the request will emit the stateChanged()
    signal. The manager may (if it supports it)
    periodically update the request with results, at
    which point the request will emit the resultsAvailable() signal. These
    results are not guaranteed to have a stable ordering. Error information is
    considered a result, so some requests will emit the resultsAvailable()
    signal even if no results are possible from the request (for example, a
    landmark remove request) when the manager updates the request with
    information about any errors which may have occurred.

    Clients can choose which signals they wish to handle from a request. If the
    client is not interested in interim results, they can choose to handle only
    the stateChanged() signal, and in the slot to which that signal is
    connected, check whether the state has changed to the \c FinishedState
    (which signifies that the manager has finished handling the request, and
    that the request will not be updated with any more results).  If the client
    is not interested in any results (including error information), they may
    choose to delete the request after calling \l start(), or simply may not
    connect the the request's signals to any slots.  (Please see the note
    below if you are working on Symbian with QtMobility 1.1.0)

    If the request is allocated via operator new, the client must delete the
    request when they are no longer using it in order to avoid leaking memory.
    That is, the client retains ownership of the request.

    The client may delete a heap-allocated request in various ways: by deleting
    it directly (but not within a slot connected to a signal emitted by the
    request), or by using the deleteLater() slot to schedule the request for
    deletion when control returns to the event loop (from within a slot
    connected to a signal emitted by the request, for example \l
    stateChanged()).

    An active request may be deleted by the client, but the client will
    not receive notifications about whether the request succeeded or not,
    nor the results of the request.

    Because clients retain ownership of any request object, and may delete a
    request object at any time, the manager engine,  implementers must be
    careful to ensue that they do not assume that a request has not been
    deleted at some time point during processing of a request, particularly
    if the engine has a multithreaded implementation.
*/

QLandmarkAbstractRequestPrivate::~QLandmarkAbstractRequestPrivate()
{
}

void QLandmarkAbstractRequestPrivate::notifyEngine(QLandmarkAbstractRequest* request)
{
        Q_ASSERT(request);
        QLandmarkAbstractRequestPrivate* d = request->d_ptr;
        if (d) {
            QMutexLocker ml(&d->mutex);
            QLandmarkManagerEngine *engine = QLandmarkManagerPrivate::getEngine(d->manager);
            ml.unlock();
            if (engine) {
                engine->requestDestroyed(request);
            }
        }
}

/*!
    \enum QLandmarkAbstractRequest::RequestType
    Defines the possible types of asynchronous requests.
    \value  InvalidRequest An invalid request
    \value  LandmarkIdFetchRequest A request to fetch a list of landmark
            identifiers.
    \value  CategoryIdFetchRequest A request to fetch a list of catgory
            identifiers.

    \value  LandmarkFetchRequest A request to fetch a list of landmarks
    \value  LandmarkFetchByIdRequest A request to fetch a list of landmarks by id.
    \value  CategoryFetchRequest A request to fetch a list of categories
    \value  CategoryFetchByIdRequest A request to fetch a list of categories by id
    \value  LandmarkSaveRequest A request to save a list of landmarks.
    \value  LandmarkRemoveRequest A request to remove a list of landmarks.
    \value  CategorySaveRequest A request to save a list of categories.
    \value  CategoryRemoveRequest A request to remove a list of categories.
    \value  ImportRequest A request import landmarks.
    \value  ExportRequest A request export landmarks.
*/

/*!
    \enum QLandmarkAbstractRequest::State
    Defines the possible states of asynchronous requests.
    \value  InactiveState Operation not yet started.
    \value  ActiveState Operation started, not yet finished.
    \value  FinishedState Operation completed.  (Can be mean either successful or
            unsuccessful completion).
*/

/*!
    Constructs a new, invalid asynchronous request with the given \a manager and \a parent.
*/
QLandmarkAbstractRequest::QLandmarkAbstractRequest(QLandmarkManager *manager, QObject *parent)
    : QObject(parent),
      d_ptr(new QLandmarkAbstractRequestPrivate(manager))
{
}

/*!
    \internal
*/
QLandmarkAbstractRequest::QLandmarkAbstractRequest(QLandmarkAbstractRequestPrivate *dd, QObject *parent)
    : QObject(parent),
     d_ptr(dd)
{
}

/*!
    Destroys the asynchronous request.  Because the request object is effectiely a handle to a
    request operation, the operation may continue or it may just be canceled, depending upon
    the enine implementation, even though the request itself has been destroyed.
    The sqlite engine continues the operation behind the scenes if the
    request is destroyed whilst active.  For the symbian engine see the note below.
*/
QLandmarkAbstractRequest::~QLandmarkAbstractRequest()
{
    QLandmarkAbstractRequestPrivate::notifyEngine(this);
    delete d_ptr;
}

/*!
    Returns the type of this asynchronous request.
*/
QLandmarkAbstractRequest::RequestType QLandmarkAbstractRequest::type() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->type;
}

/*!
    Returns the state of the request
*/
QLandmarkAbstractRequest::State QLandmarkAbstractRequest::state()
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Inactive state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isInactive() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::InactiveState;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Active state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isActive() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::ActiveState;
}

/*!
    Returns true if the request is in the \c QLandmarkAbstractRequest::Finished state;
    otherwise, returns false.
    \sa state()
*/
bool QLandmarkAbstractRequest::isFinished() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->state == QLandmarkAbstractRequest::FinishedState;
}

/*!
    Returns the overall error of the most recent asynchronous operation.
    \sa errorString()
*/
QLandmarkManager::Error QLandmarkAbstractRequest::error() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->error;
}

/*!
    Returns a human readable string of the last error
    that occurred.  This error string is intended to be used
    by developers only and should not be seen by end users.
    \sa error()
*/
QString QLandmarkAbstractRequest::errorString() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->errorString;
}

/*!
    Returns a pointer to the landmark manager which
    this request operates on.
*/
QLandmarkManager *QLandmarkAbstractRequest::manager() const
{
    QMutexLocker ml(&d_ptr->mutex);
    return d_ptr->manager;
}

/*!
    Sets the \a manager which this request operates on.

    Note that if a NULL manager is set, the functions
    start(), cancel() and waitForFinished() will return false and
    error will be set to QLandmarkManager::InvalidManagerError.

    A manager cannot be assigned while the request is in the
    QLandmarkAbstractRequest::ActiveState.
*/
void QLandmarkAbstractRequest::setManager(QLandmarkManager *manager)
{
    QMutexLocker ml(&d_ptr->mutex);
    if (d_ptr->state == QLandmarkAbstractRequest::ActiveState && d_ptr->manager)
        return;
    d_ptr->manager = manager;
}

/*!
    Attempts to start the request.

    Returns true if the request was started, otherwise false. Trying to start a
    request that is already active returns false.
    \sa cancel().
*/
bool QLandmarkAbstractRequest::start()
{
    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();
    if (!engine) {
        d_ptr->error = QLandmarkManager::InvalidManagerError;
        d_ptr->errorString = "The manager is invalid";
        return false;
    }

    if (d_ptr->state != QLandmarkAbstractRequest::ActiveState) {
        ml.unlock();
        return engine->startRequest(this);
    }
     else {
        return false;
     }
}

/*!
    Notifies the request that it should be canceled.

    Returns true if the request was successfully notified
    that it should be canceled.  The request may or may not honor
    the cancel notification.  Returns false if the notification
    could not be made or the request is not in the
    QLandmarkManager::Active state.

    \sa start()
*/
bool QLandmarkAbstractRequest::cancel()
{
    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();

    if(d_ptr->state == QLandmarkAbstractRequest::ActiveState) {
        ml.unlock();
        return engine->cancelRequest(this);
    }
    else
        return false;
}

/*!
    Blocks until the request has been completed or until \a msecs milliseconds
    has elapsed.  If \a msecs is zero or negative, this function will block indefinitely.

    Returns true if the request was canceled or completed
    within the given period, otherwise returns false.  Some backends may be unable
    to support this operation safely and will return false immediately.

    (Note that this function is not supported for the import request
    on symbian and it will always return false when waitForFinished() is called.
    As of Qt Mobility 1.1.1 this function is supported with the sqlite manager).

    Note that any signals generated while waiting for the request to be complete
    may be queued and delivered sometime after this function has returned, when
    the calling thread's event loop is dispatched.  If your code depends on
    your slots being invoked, you may need to process events after calling
    this function.
*/
bool QLandmarkAbstractRequest::waitForFinished(int msecs)
{

    QMutexLocker ml(&d_ptr->mutex);
    if (!d_ptr->manager) {
        d_ptr->error = QLandmarkManager::BadArgumentError;
        d_ptr->errorString = "No manager assigned to landmark request object";
        qWarning() << d_ptr->errorString;
        return false;
    }
    QLandmarkManagerEngine *engine = d_ptr->manager->engine();

    switch(d_ptr->state) {
        case QLandmarkAbstractRequest::ActiveState:
            ml.unlock();
            return engine->waitForRequestFinished(this, msecs);
        case QLandmarkAbstractRequest::FinishedState:
            return true;
        default:
            return false;
    }
    return false;
}

/*!
  \fn void QLandmarkAbstractRequest::resultsAvailable()
  This signal is emitted when new results are available.  Results
  can include the operation error which may be accessed via error(),
  or derived-class specific results which are accessible through
  the derived class API.

  \sa error()
*/

/*!
    \fn void QLandmarkAbstractRequest::stateChanged(QLandmarkAbstractRequest::State newState)
    This signal is emitted when the state of the request is changed.  The new state of
    the request will be contained in \a newState.
*/

#include "moc_qlandmarkabstractrequest.cpp"

<|endoftext|>


<commit_before>/* GG is a GUI for SDL and OpenGL.
   Copyright (C) 2003-2008 T. Zachary Laine

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation; either version 2.1
   of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA

   If you do not wish to comply with the terms of the LGPL please
   contact the author as other terms are available for a fee.

   Zach Laine
   whatwasthataddress@gmail.com */

#include <GG/DropDownList.h>

#include <GG/GUI.h>
#include <GG/DrawUtil.h>
#include <GG/Scroll.h>
#include <GG/StyleFactory.h>
#include <GG/WndEvent.h>

using namespace GG;

namespace {
    struct SelChangedEcho
    {
        SelChangedEcho(const DropDownList& drop_list) :
            m_drop_list(drop_list)
            {}
        void operator()(const DropDownList::iterator& it)
            {
                std::cerr << "GG SIGNAL : DropDownList::SelChangedSignal(row="
                          << m_drop_list.IteratorToIndex(it)
                          << ")\n";
            }
        const DropDownList& m_drop_list;
    };

    const int BORDER_THICK = 2; // should be the same as the BORDER_THICK value in GGListBox.h

    class ModalListPicker : public Wnd
    {
    public:
        ModalListPicker(DropDownList* drop_wnd, ListBox* lb_wnd) :
            Wnd(X0, Y0, GUI::GetGUI()->AppWidth(), GUI::GetGUI()->AppHeight(),
                INTERACTIVE | MODAL),
            m_drop_wnd(drop_wnd),
            m_lb_wnd(lb_wnd),
            m_old_lb_ul(m_lb_wnd->UpperLeft())
        {
            m_connection_1 =
                Connect(m_lb_wnd->SelChangedSignal, &ModalListPicker::LBSelChangedSlot, this);
            m_connection_2 =
                Connect(m_lb_wnd->LeftClickedSignal, &ModalListPicker::LBLeftClickSlot, this);
            m_lb_ul = m_old_lb_ul + m_drop_wnd->UpperLeft();
            AttachChild(m_lb_wnd);
        }

        virtual void Render()
        { m_lb_wnd->MoveTo(m_lb_ul); }

        ~ModalListPicker()
        {
            m_lb_wnd->MoveTo(m_old_lb_ul);
            DetachChild(m_lb_wnd);
        }

    protected:
        virtual void LClick(const Pt& pt, Flags<ModKey> mod_keys)
        { m_done = true; }

    private:
        void LBSelChangedSlot(const ListBox::SelectionSet& rows)
        {
            if (!rows.empty()) {
                m_drop_wnd->Select(*rows.begin());
                m_drop_wnd->SelChangedSignal(m_drop_wnd->CurrentItem());
                m_done = true;
            }
        }

        void LBLeftClickSlot(ListBox::iterator it, const Pt&)
        { m_done = true; }

        DropDownList*  m_drop_wnd;
        ListBox*       m_lb_wnd;
        Pt             m_old_lb_ul;
        Pt             m_lb_ul;

        boost::signals::scoped_connection m_connection_1;
        boost::signals::scoped_connection m_connection_2;
    };
}

////////////////////////////////////////////////
// GG::DropDownList
////////////////////////////////////////////////
DropDownList::DropDownList(X x, Y y, X w, Y h, Y drop_ht, Clr color,
                           Flags<WndFlag> flags/* = INTERACTIVE*/) :
    Control(x, y, w, h, flags),
    m_current_item(),
    m_LB(GetStyleFactory()->NewDropDownListListBox(x, y, w, drop_ht, color, color, flags))
{
    SetStyle(LIST_SINGLESEL);
    // adjust size to keep correct height based on row height, etc.
    Wnd::SizeMove(Pt(x, y), Pt(x + Size().x, y + h + 2 * static_cast<int>(m_LB->CellMargin()) + 2 * BORDER_THICK));
    m_LB->SizeMove(Pt(X0, Height()), Pt(Width(), Height() + m_LB->Height()));
    m_current_item = m_LB->end();

    if (INSTRUMENT_ALL_SIGNALS)
        Connect(SelChangedSignal, SelChangedEcho(*this));
}

DropDownList::~DropDownList()
{ delete m_LB; }

DropDownList::iterator DropDownList::CurrentItem() const
{ return m_current_item; }

std::size_t DropDownList::CurrentItemIndex() const
{ return IteratorToIndex(m_current_item); }

std::size_t DropDownList::IteratorToIndex(iterator it) const
{ return it == m_LB->end() ? -1 : std::distance(m_LB->begin(), it); }

DropDownList::iterator DropDownList::IndexToIterator(std::size_t n) const
{ return n < m_LB->NumRows() ? boost::next(m_LB->begin(), n) : m_LB->end(); }

bool DropDownList::Empty() const
{ return m_LB->Empty(); }

DropDownList::const_iterator DropDownList::begin() const
{ return m_LB->begin(); }

DropDownList::const_iterator DropDownList::end() const
{ return m_LB->end(); }

DropDownList::const_reverse_iterator DropDownList::rbegin() const
{ return m_LB->rbegin(); }

DropDownList::const_reverse_iterator DropDownList::rend() const
{ return m_LB->rend(); }

const DropDownList::Row& DropDownList::GetRow(std::size_t n) const
{ return m_LB->GetRow(n); }

bool DropDownList::Selected(iterator it) const
{ return m_LB->Selected(it); }

bool DropDownList::Selected(std::size_t n) const
{ return n < m_LB->NumRows() ? m_LB->Selected(boost::next(m_LB->begin(), n)) : false; }

Clr DropDownList::InteriorColor() const
{ return m_LB->InteriorColor(); }

Y DropDownList::DropHeight() const
{ return m_LB->Height(); }

Flags<ListBoxStyle> DropDownList::Style() const
{ return m_LB->Style(); }

std::size_t DropDownList::NumRows() const
{ return m_LB->NumRows(); }

std::size_t DropDownList::NumCols() const
{ return m_LB->NumCols(); }

std::size_t DropDownList::SortCol() const
{ return m_LB->SortCol(); }

X DropDownList::ColWidth(std::size_t n) const
{ return m_LB->ColWidth(n); }

Alignment DropDownList::ColAlignment(std::size_t n) const
{ return m_LB->ColAlignment(n); }

Alignment DropDownList::RowAlignment(iterator it) const
{ return m_LB->RowAlignment(it); }

Pt DropDownList::ClientUpperLeft() const
{ return UpperLeft() + Pt(X(BORDER_THICK), Y(BORDER_THICK)); }

Pt DropDownList::ClientLowerRight() const
{ return LowerRight() - Pt(X(BORDER_THICK), Y(BORDER_THICK)); }

void DropDownList::Render()
{
    // draw beveled rectangle around client area
    Pt ul = UpperLeft(), lr = LowerRight();
    Clr color_to_use = Disabled() ? DisabledColor(m_LB->Color()) : m_LB->Color();
    Clr int_color_to_use = Disabled() ? DisabledColor(m_LB->m_int_color) : m_LB->m_int_color;

    BeveledRectangle(ul, lr, int_color_to_use, color_to_use, false, BORDER_THICK);

    // Draw the ListBox::Row of currently displayed item, if any.
    if (m_current_item != m_LB->end()) {
        Row* current_item = *m_current_item;
        Pt offset = ClientUpperLeft() - current_item->UpperLeft();
        bool visible = current_item->Visible();
        current_item->OffsetMove(offset);
        if (!visible)
            current_item->Show();
        BeginClipping();
        GUI::GetGUI()->RenderWindow(current_item);
        EndClipping();
        current_item->OffsetMove(-offset);
        if (!visible)
            current_item->Hide();
    }
}

void DropDownList::SizeMove(const Pt& ul, const Pt& lr)
{
    // adjust size to keep correct height based on row height, etc.
    Wnd::SizeMove(ul, lr);
    m_LB->SizeMove(Pt(X0, Height()), Pt(Width(), Height() + m_LB->Height()));
}

void DropDownList::SetColor(Clr c)
{ m_LB->SetColor(c); }

DropDownList::iterator DropDownList::Insert(Row* row, iterator it)
{
    row->SetDragDropDataType("");
    return m_LB->Insert(row, it);
}

DropDownList::iterator DropDownList::Insert(Row* row)
{
    row->SetDragDropDataType("");
    return m_LB->Insert(row);
}

DropDownList::Row* DropDownList::Erase(iterator it)
{
    if (it == m_current_item)
        m_current_item = m_LB->end();
    return m_LB->Erase(it);
}

void DropDownList::Clear()
{
    m_current_item = m_LB->end();
    m_LB->Clear();
}

DropDownList::iterator DropDownList::begin()
{ return m_LB->begin(); }

DropDownList::iterator DropDownList::end()
{ return m_LB->end(); }

DropDownList::reverse_iterator DropDownList::rbegin()
{ return m_LB->rbegin(); }

DropDownList::reverse_iterator DropDownList::rend()
{ return m_LB->rend(); }

DropDownList::Row& DropDownList::GetRow(std::size_t n)
{ return m_LB->GetRow(n); }

void DropDownList::Select(iterator it)
{ SelectImpl(it, false); }

void DropDownList::Select(std::size_t n)
{ SelectImpl(n < m_LB->NumRows() ? boost::next(m_LB->begin(), n) : m_LB->end(), false); }

void DropDownList::SetInteriorColor(Clr c)
{ m_LB->SetInteriorColor(c); }

void DropDownList::SetDropHeight(Y h)
{ m_LB->Resize(Pt(Width(), h)); }

void DropDownList::SetStyle(Flags<ListBoxStyle> s)
{
    s &= ~(LIST_NOSEL | LIST_QUICKSEL | LIST_USERDELETE | LIST_BROWSEUPDATES);
    s |= LIST_SINGLESEL;
    m_LB->SetStyle(s);
    m_current_item = m_LB->end();
}

void DropDownList::SetNumCols(std::size_t n)
{ m_LB->SetNumCols(n); }

void DropDownList::SetSortCol(std::size_t n)
{
    m_LB->SetSortCol(n);
    m_current_item = m_LB->end();
}

void DropDownList::SetColWidth(std::size_t n, X w)
{ m_LB->SetColWidth(n, w); }

void DropDownList::LockColWidths()
{ m_LB->LockColWidths(); }

void DropDownList::UnLockColWidths()
{ m_LB->UnLockColWidths(); }

void DropDownList::SetColAlignment(std::size_t n, Alignment align)
{ m_LB->SetColAlignment(n, align); }

void DropDownList::SetRowAlignment(iterator it, Alignment align)
{ m_LB->SetRowAlignment(it, align); }

void DropDownList::LClick(const Pt& pt, Flags<ModKey> mod_keys)
{
    if (!Disabled()) {
        ModalListPicker picker(this, m_LB);
        const ListBox::SelectionSet& LB_sels = m_LB->Selections();
        if (!LB_sels.empty()) {
            if (m_LB->m_vscroll) {
                m_LB->m_vscroll->ScrollTo(0);
                SignalScroll(*m_LB->m_vscroll, true);
            }
        }
        m_LB->m_first_col_shown = 0;
        picker.Run();
    }
}

void DropDownList::KeyPress(Key key, boost::uint32_t key_code_point, Flags<ModKey> mod_keys)
{
    if (!Disabled()) {
        switch (key) {
        case GGK_UP: // arrow-up (not numpad arrow)
            if (m_current_item != m_LB->end() && m_current_item != m_LB->begin())
                SelectImpl(boost::prior(m_current_item), true);
            break;
        case GGK_DOWN: // arrow-down (not numpad arrow)
            if (m_current_item != m_LB->end() && m_current_item != --m_LB->end())
                SelectImpl(boost::next(m_current_item), true);
            break;
        case GGK_PAGEUP: // page up key (not numpad key)
            if (m_LB->NumRows() && m_current_item != m_LB->end()) {
                std::size_t i = 10;
                iterator it = m_current_item;
                while (i && it != m_LB->begin()) {
                    --it;
                    --i;
                }
                SelectImpl(it, true);
            }
            break;
        case GGK_PAGEDOWN: // page down key (not numpad key)
            if (m_LB->NumRows()) {
                std::size_t i = 10;
                iterator it = m_current_item;
                while (i && it != --m_LB->end()) {
                    ++it;
                    ++i;
                }
                SelectImpl(it, true);
            }
            break;
        case GGK_HOME: // home key (not numpad)
            if (m_LB->NumRows())
                SelectImpl(m_LB->begin(), true);
            break;
        case GGK_END: // end key (not numpad)
            if (m_LB->NumRows() && !m_LB->Empty())
                SelectImpl(--m_LB->end(), true);
            break;
        default:
            Control::KeyPress(key, key_code_point, mod_keys);
        }
    } else {
        Control::KeyPress(key, key_code_point, mod_keys);
    }
}

ListBox* DropDownList::LB()
{ return m_LB; }

void DropDownList::SelectImpl(iterator it, bool signal)
{
    iterator old_m_current_item = m_current_item;
    if (it == m_LB->end()) {
        m_current_item = m_LB->end();
        m_LB->DeselectAll();
    } else {
        m_current_item = it;
        m_LB->SelectRow(m_current_item);
    }

    if (signal && m_current_item != old_m_current_item)
        SelChangedSignal(m_current_item);
}
<commit_msg>Changed wonky placement logic for DropDownList's ListBox to that the placement happens immediately, instead of on the next frame.<commit_after>/* GG is a GUI for SDL and OpenGL.
   Copyright (C) 2003-2008 T. Zachary Laine

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation; either version 2.1
   of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA

   If you do not wish to comply with the terms of the LGPL please
   contact the author as other terms are available for a fee.

   Zach Laine
   whatwasthataddress@gmail.com */

#include <GG/DropDownList.h>

#include <GG/GUI.h>
#include <GG/DrawUtil.h>
#include <GG/Scroll.h>
#include <GG/StyleFactory.h>
#include <GG/WndEvent.h>

using namespace GG;

namespace {
    struct SelChangedEcho
    {
        SelChangedEcho(const DropDownList& drop_list) :
            m_drop_list(drop_list)
            {}
        void operator()(const DropDownList::iterator& it)
            {
                std::cerr << "GG SIGNAL : DropDownList::SelChangedSignal(row="
                          << m_drop_list.IteratorToIndex(it)
                          << ")\n";
            }
        const DropDownList& m_drop_list;
    };

    const int BORDER_THICK = 2; // should be the same as the BORDER_THICK value in GGListBox.h

    class ModalListPicker : public Wnd
    {
    public:
        ModalListPicker(DropDownList* drop_wnd, ListBox* lb_wnd) :
            Wnd(X0, Y0, GUI::GetGUI()->AppWidth(), GUI::GetGUI()->AppHeight(),
                INTERACTIVE | MODAL),
            m_drop_wnd(drop_wnd),
            m_lb_wnd(lb_wnd),
            m_old_lb_ul(m_lb_wnd->UpperLeft())
        {
            m_connection_1 =
                Connect(m_lb_wnd->SelChangedSignal, &ModalListPicker::LBSelChangedSlot, this);
            m_connection_2 =
                Connect(m_lb_wnd->LeftClickedSignal, &ModalListPicker::LBLeftClickSlot, this);
            m_lb_ul = m_old_lb_ul + m_drop_wnd->UpperLeft();
            m_lb_wnd->MoveTo(m_lb_ul);
            AttachChild(m_lb_wnd);
        }

        ~ModalListPicker()
        {
            m_lb_wnd->MoveTo(m_old_lb_ul);
            DetachChild(m_lb_wnd);
        }

    protected:
        virtual void LClick(const Pt& pt, Flags<ModKey> mod_keys)
        { m_done = true; }

    private:
        void LBSelChangedSlot(const ListBox::SelectionSet& rows)
        {
            if (!rows.empty()) {
                m_drop_wnd->Select(*rows.begin());
                m_drop_wnd->SelChangedSignal(m_drop_wnd->CurrentItem());
                m_done = true;
            }
        }

        void LBLeftClickSlot(ListBox::iterator it, const Pt&)
        { m_done = true; }

        DropDownList*  m_drop_wnd;
        ListBox*       m_lb_wnd;
        Pt             m_old_lb_ul;
        Pt             m_lb_ul;

        boost::signals::scoped_connection m_connection_1;
        boost::signals::scoped_connection m_connection_2;
    };
}

////////////////////////////////////////////////
// GG::DropDownList
////////////////////////////////////////////////
DropDownList::DropDownList(X x, Y y, X w, Y h, Y drop_ht, Clr color,
                           Flags<WndFlag> flags/* = INTERACTIVE*/) :
    Control(x, y, w, h, flags),
    m_current_item(),
    m_LB(GetStyleFactory()->NewDropDownListListBox(x, y, w, drop_ht, color, color, flags))
{
    SetStyle(LIST_SINGLESEL);
    // adjust size to keep correct height based on row height, etc.
    Wnd::SizeMove(Pt(x, y), Pt(x + Size().x, y + h + 2 * static_cast<int>(m_LB->CellMargin()) + 2 * BORDER_THICK));
    m_LB->SizeMove(Pt(X0, Height()), Pt(Width(), Height() + m_LB->Height()));
    m_current_item = m_LB->end();

    if (INSTRUMENT_ALL_SIGNALS)
        Connect(SelChangedSignal, SelChangedEcho(*this));
}

DropDownList::~DropDownList()
{ delete m_LB; }

DropDownList::iterator DropDownList::CurrentItem() const
{ return m_current_item; }

std::size_t DropDownList::CurrentItemIndex() const
{ return IteratorToIndex(m_current_item); }

std::size_t DropDownList::IteratorToIndex(iterator it) const
{ return it == m_LB->end() ? -1 : std::distance(m_LB->begin(), it); }

DropDownList::iterator DropDownList::IndexToIterator(std::size_t n) const
{ return n < m_LB->NumRows() ? boost::next(m_LB->begin(), n) : m_LB->end(); }

bool DropDownList::Empty() const
{ return m_LB->Empty(); }

DropDownList::const_iterator DropDownList::begin() const
{ return m_LB->begin(); }

DropDownList::const_iterator DropDownList::end() const
{ return m_LB->end(); }

DropDownList::const_reverse_iterator DropDownList::rbegin() const
{ return m_LB->rbegin(); }

DropDownList::const_reverse_iterator DropDownList::rend() const
{ return m_LB->rend(); }

const DropDownList::Row& DropDownList::GetRow(std::size_t n) const
{ return m_LB->GetRow(n); }

bool DropDownList::Selected(iterator it) const
{ return m_LB->Selected(it); }

bool DropDownList::Selected(std::size_t n) const
{ return n < m_LB->NumRows() ? m_LB->Selected(boost::next(m_LB->begin(), n)) : false; }

Clr DropDownList::InteriorColor() const
{ return m_LB->InteriorColor(); }

Y DropDownList::DropHeight() const
{ return m_LB->Height(); }

Flags<ListBoxStyle> DropDownList::Style() const
{ return m_LB->Style(); }

std::size_t DropDownList::NumRows() const
{ return m_LB->NumRows(); }

std::size_t DropDownList::NumCols() const
{ return m_LB->NumCols(); }

std::size_t DropDownList::SortCol() const
{ return m_LB->SortCol(); }

X DropDownList::ColWidth(std::size_t n) const
{ return m_LB->ColWidth(n); }

Alignment DropDownList::ColAlignment(std::size_t n) const
{ return m_LB->ColAlignment(n); }

Alignment DropDownList::RowAlignment(iterator it) const
{ return m_LB->RowAlignment(it); }

Pt DropDownList::ClientUpperLeft() const
{ return UpperLeft() + Pt(X(BORDER_THICK), Y(BORDER_THICK)); }

Pt DropDownList::ClientLowerRight() const
{ return LowerRight() - Pt(X(BORDER_THICK), Y(BORDER_THICK)); }

void DropDownList::Render()
{
    // draw beveled rectangle around client area
    Pt ul = UpperLeft(), lr = LowerRight();
    Clr color_to_use = Disabled() ? DisabledColor(m_LB->Color()) : m_LB->Color();
    Clr int_color_to_use = Disabled() ? DisabledColor(m_LB->m_int_color) : m_LB->m_int_color;

    BeveledRectangle(ul, lr, int_color_to_use, color_to_use, false, BORDER_THICK);

    // Draw the ListBox::Row of currently displayed item, if any.
    if (m_current_item != m_LB->end()) {
        Row* current_item = *m_current_item;
        Pt offset = ClientUpperLeft() - current_item->UpperLeft();
        bool visible = current_item->Visible();
        current_item->OffsetMove(offset);
        if (!visible)
            current_item->Show();
        BeginClipping();
        GUI::GetGUI()->RenderWindow(current_item);
        EndClipping();
        current_item->OffsetMove(-offset);
        if (!visible)
            current_item->Hide();
    }
}

void DropDownList::SizeMove(const Pt& ul, const Pt& lr)
{
    // adjust size to keep correct height based on row height, etc.
    Wnd::SizeMove(ul, lr);
    m_LB->SizeMove(Pt(X0, Height()), Pt(Width(), Height() + m_LB->Height()));
}

void DropDownList::SetColor(Clr c)
{ m_LB->SetColor(c); }

DropDownList::iterator DropDownList::Insert(Row* row, iterator it)
{
    row->SetDragDropDataType("");
    return m_LB->Insert(row, it);
}

DropDownList::iterator DropDownList::Insert(Row* row)
{
    row->SetDragDropDataType("");
    return m_LB->Insert(row);
}

DropDownList::Row* DropDownList::Erase(iterator it)
{
    if (it == m_current_item)
        m_current_item = m_LB->end();
    return m_LB->Erase(it);
}

void DropDownList::Clear()
{
    m_current_item = m_LB->end();
    m_LB->Clear();
}

DropDownList::iterator DropDownList::begin()
{ return m_LB->begin(); }

DropDownList::iterator DropDownList::end()
{ return m_LB->end(); }

DropDownList::reverse_iterator DropDownList::rbegin()
{ return m_LB->rbegin(); }

DropDownList::reverse_iterator DropDownList::rend()
{ return m_LB->rend(); }

DropDownList::Row& DropDownList::GetRow(std::size_t n)
{ return m_LB->GetRow(n); }

void DropDownList::Select(iterator it)
{ SelectImpl(it, false); }

void DropDownList::Select(std::size_t n)
{ SelectImpl(n < m_LB->NumRows() ? boost::next(m_LB->begin(), n) : m_LB->end(), false); }

void DropDownList::SetInteriorColor(Clr c)
{ m_LB->SetInteriorColor(c); }

void DropDownList::SetDropHeight(Y h)
{ m_LB->Resize(Pt(Width(), h)); }

void DropDownList::SetStyle(Flags<ListBoxStyle> s)
{
    s &= ~(LIST_NOSEL | LIST_QUICKSEL | LIST_USERDELETE | LIST_BROWSEUPDATES);
    s |= LIST_SINGLESEL;
    m_LB->SetStyle(s);
    m_current_item = m_LB->end();
}

void DropDownList::SetNumCols(std::size_t n)
{ m_LB->SetNumCols(n); }

void DropDownList::SetSortCol(std::size_t n)
{
    m_LB->SetSortCol(n);
    m_current_item = m_LB->end();
}

void DropDownList::SetColWidth(std::size_t n, X w)
{ m_LB->SetColWidth(n, w); }

void DropDownList::LockColWidths()
{ m_LB->LockColWidths(); }

void DropDownList::UnLockColWidths()
{ m_LB->UnLockColWidths(); }

void DropDownList::SetColAlignment(std::size_t n, Alignment align)
{ m_LB->SetColAlignment(n, align); }

void DropDownList::SetRowAlignment(iterator it, Alignment align)
{ m_LB->SetRowAlignment(it, align); }

void DropDownList::LClick(const Pt& pt, Flags<ModKey> mod_keys)
{
    if (!Disabled()) {
        ModalListPicker picker(this, m_LB);
        const ListBox::SelectionSet& LB_sels = m_LB->Selections();
        if (!LB_sels.empty()) {
            if (m_LB->m_vscroll) {
                m_LB->m_vscroll->ScrollTo(0);
                SignalScroll(*m_LB->m_vscroll, true);
            }
        }
        m_LB->m_first_col_shown = 0;
        picker.Run();
    }
}

void DropDownList::KeyPress(Key key, boost::uint32_t key_code_point, Flags<ModKey> mod_keys)
{
    if (!Disabled()) {
        switch (key) {
        case GGK_UP: // arrow-up (not numpad arrow)
            if (m_current_item != m_LB->end() && m_current_item != m_LB->begin())
                SelectImpl(boost::prior(m_current_item), true);
            break;
        case GGK_DOWN: // arrow-down (not numpad arrow)
            if (m_current_item != m_LB->end() && m_current_item != --m_LB->end())
                SelectImpl(boost::next(m_current_item), true);
            break;
        case GGK_PAGEUP: // page up key (not numpad key)
            if (m_LB->NumRows() && m_current_item != m_LB->end()) {
                std::size_t i = 10;
                iterator it = m_current_item;
                while (i && it != m_LB->begin()) {
                    --it;
                    --i;
                }
                SelectImpl(it, true);
            }
            break;
        case GGK_PAGEDOWN: // page down key (not numpad key)
            if (m_LB->NumRows()) {
                std::size_t i = 10;
                iterator it = m_current_item;
                while (i && it != --m_LB->end()) {
                    ++it;
                    ++i;
                }
                SelectImpl(it, true);
            }
            break;
        case GGK_HOME: // home key (not numpad)
            if (m_LB->NumRows())
                SelectImpl(m_LB->begin(), true);
            break;
        case GGK_END: // end key (not numpad)
            if (m_LB->NumRows() && !m_LB->Empty())
                SelectImpl(--m_LB->end(), true);
            break;
        default:
            Control::KeyPress(key, key_code_point, mod_keys);
        }
    } else {
        Control::KeyPress(key, key_code_point, mod_keys);
    }
}

ListBox* DropDownList::LB()
{ return m_LB; }

void DropDownList::SelectImpl(iterator it, bool signal)
{
    iterator old_m_current_item = m_current_item;
    if (it == m_LB->end()) {
        m_current_item = m_LB->end();
        m_LB->DeselectAll();
    } else {
        m_current_item = it;
        m_LB->SelectRow(m_current_item);
    }

    if (signal && m_current_item != old_m_current_item)
        SelChangedSignal(m_current_item);
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "EDDIFrontEnd.hpp"
#include "SemanticalException.hpp"
#include "DebugStopWatch.hpp"
#include "Options.hpp"
#include "StringPool.hpp"
#include "Type.hpp"
#include "GlobalContext.hpp"

#include "parser/SpiritParser.hpp"

#include "ast/SourceFile.hpp"

//Annotators
#include "ast/DefaultValues.hpp"
#include "ast/ContextAnnotator.hpp"
#include "ast/FunctionsAnnotator.hpp"
#include "ast/VariablesAnnotator.hpp"
#include "ast/StructuresAnnotator.hpp"

//Checkers
#include "ast/StringChecker.hpp"
#include "ast/TypeChecker.hpp"

//Visitors
#include "ast/DependenciesResolver.hpp"
#include "ast/OptimizationEngine.hpp"
#include "ast/TransformerEngine.hpp"
#include "ast/WarningsEngine.hpp"
#include "ast/Printer.hpp"
#include "ast/TemplateEngine.hpp"

#include "mtac/Compiler.hpp"
#include "mtac/RegisterAllocation.hpp"

using namespace eddic;

void check_for_main(std::shared_ptr<GlobalContext> context);
void mark_functions(ast::SourceFile& program);
bool still_unmarked_functions(ast::SourceFile& program);

std::shared_ptr<mtac::Program> EDDIFrontEnd::compile(const std::string& file){
    parser::SpiritParser parser;

    //The program to build
    ast::SourceFile program;

    //Parse the file into the program
    bool parsing = parser.parse(file, program);

    //If the parsing was sucessfully
    if(parsing){
        set_string_pool(std::make_shared<StringPool>());

        //Read dependencies
        resolveDependencies(program, parser);

        //Apply some cleaning transformations
        ast::cleanAST(program);

        ast::TemplateEngine template_engine;

        do {
            //Define contexts and structures
            ast::defineContexts(program);
            ast::defineStructures(program);

            //Add default values
            ast::defineDefaultValues(program);

            //Fill the string pool
            ast::checkStrings(program, *pool);

            //Add some more informations to the AST
            ast::defineMemberFunctions(program);
            ast::defineVariables(program);
            ast::defineFunctions(program);

            //Static analysis
            ast::checkTypes(program);

            //Transform the AST
            ast::transformAST(program);

            //Mark all the functions as transformed
            mark_functions(program);

            //Instantiate templates
            template_engine.template_instantiation(program);
        } while(still_unmarked_functions(program));

        //Check for warnings
        ast::checkForWarnings(program);

        //Check that there is a main in the program
        check_for_main(program.Content->context);

        //Optimize the AST
        ast::optimizeAST(program, *pool);

        //If the user asked for it, print the Abstract Syntax Tree
        if(option_defined("ast") || option_defined("ast-only")){
            ast::Printer printer;
            printer.print(program);
        }

        //If the user wants only the AST prints, it is not necessary to compile the AST
        if(option_defined("ast-only")){
            return nullptr;
        }

        std::shared_ptr<mtac::Program> mtacProgram = std::make_shared<mtac::Program>();

        //Generate Three-Address-Code language
        mtac::Compiler compiler;
        compiler.compile(program, pool, mtacProgram);

        return mtacProgram;
    }

    //If the parsing fails, the error is already printed to the console
    return nullptr;
}

void check_for_main(std::shared_ptr<GlobalContext> context){
    if(context->exists("_F4main")){
        context->addReference("_F4main");
    } else if (context->exists("_F4mainAS")){
        context->addReference("_F4mainAS");
    } else {
        throw SemanticalException("The program does not contain a valid main function");
    }
}

void mark_functions(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            ptr->Content->marked = true;
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            for(auto& function : ptr->Content->functions){
               function.Content->marked = true;
            }
        }
    }
}

bool still_unmarked_functions(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            if(!ptr->Content->marked){
                return true;
            }
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            for(auto& function : ptr->Content->functions){
                if(!function.Content->marked){
                    return true;
                }
            }
        }
    }

    return false;
}
<commit_msg>Iterate until there are no struct or function marked<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "EDDIFrontEnd.hpp"
#include "SemanticalException.hpp"
#include "DebugStopWatch.hpp"
#include "Options.hpp"
#include "StringPool.hpp"
#include "Type.hpp"
#include "GlobalContext.hpp"

#include "parser/SpiritParser.hpp"

#include "ast/SourceFile.hpp"

//Annotators
#include "ast/DefaultValues.hpp"
#include "ast/ContextAnnotator.hpp"
#include "ast/FunctionsAnnotator.hpp"
#include "ast/VariablesAnnotator.hpp"
#include "ast/StructuresAnnotator.hpp"

//Checkers
#include "ast/StringChecker.hpp"
#include "ast/TypeChecker.hpp"

//Visitors
#include "ast/DependenciesResolver.hpp"
#include "ast/OptimizationEngine.hpp"
#include "ast/TransformerEngine.hpp"
#include "ast/WarningsEngine.hpp"
#include "ast/Printer.hpp"
#include "ast/TemplateEngine.hpp"

#include "mtac/Compiler.hpp"
#include "mtac/RegisterAllocation.hpp"

using namespace eddic;

void check_for_main(std::shared_ptr<GlobalContext> context);
void mark(ast::SourceFile& program);
bool still_unmarked(ast::SourceFile& program);

std::shared_ptr<mtac::Program> EDDIFrontEnd::compile(const std::string& file){
    parser::SpiritParser parser;

    //The program to build
    ast::SourceFile program;

    //Parse the file into the program
    bool parsing = parser.parse(file, program);

    //If the parsing was sucessfully
    if(parsing){
        set_string_pool(std::make_shared<StringPool>());

        //Read dependencies
        resolveDependencies(program, parser);

        //Apply some cleaning transformations
        ast::cleanAST(program);

        ast::TemplateEngine template_engine;

        do {
            std::cout << "Phase " << std::endl;

            //Define contexts and structures
            ast::defineContexts(program);
            ast::defineStructures(program);

            //Add default values
            ast::defineDefaultValues(program);

            //Fill the string pool
            ast::checkStrings(program, *pool);

            //Add some more informations to the AST
            ast::defineMemberFunctions(program);
            ast::defineVariables(program);
            ast::defineFunctions(program);

            //Static analysis
            ast::checkTypes(program);

            //Transform the AST
            ast::transformAST(program);

            //Mark all the functions and struct as transformed
            mark(program);

            //Instantiate templates
            template_engine.template_instantiation(program);

            ast::Printer printer;
            printer.print(program);
        } while(still_unmarked(program));

        //Check for warnings
        ast::checkForWarnings(program);

        //Check that there is a main in the program
        check_for_main(program.Content->context);

        //Optimize the AST
        ast::optimizeAST(program, *pool);

        //If the user asked for it, print the Abstract Syntax Tree
        if(option_defined("ast") || option_defined("ast-only")){
            ast::Printer printer;
            printer.print(program);
        }

        //If the user wants only the AST prints, it is not necessary to compile the AST
        if(option_defined("ast-only")){
            return nullptr;
        }

        std::shared_ptr<mtac::Program> mtacProgram = std::make_shared<mtac::Program>();

        //Generate Three-Address-Code language
        mtac::Compiler compiler;
        compiler.compile(program, pool, mtacProgram);

        return mtacProgram;
    }

    //If the parsing fails, the error is already printed to the console
    return nullptr;
}

void check_for_main(std::shared_ptr<GlobalContext> context){
    if(context->exists("_F4main")){
        context->addReference("_F4main");
    } else if (context->exists("_F4mainAS")){
        context->addReference("_F4mainAS");
    } else {
        throw SemanticalException("The program does not contain a valid main function");
    }
}

void mark(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            ptr->Content->marked = true;
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            ptr->Content->marked = true;

            for(auto& function : ptr->Content->functions){
               function.Content->marked = true;
            }
        }
    }
}

bool still_unmarked(ast::SourceFile& program){
    for(auto& block : program.Content->blocks){
        if(auto* ptr = boost::get<ast::FunctionDeclaration>(&block)){
            if(!ptr->Content->marked){
                return true;
            }
        } else if(auto* ptr = boost::get<ast::Struct>(&block)){
            if(!ptr->Content->marked){
                return true;
            }

            for(auto& function : ptr->Content->functions){
                if(!function.Content->marked){
                    return true;
                }
            }
        }
    }

    return false;
}
<|endoftext|>


<commit_before>#include <iostream> //rem
using namespace std;//rem

#include <cmath>

#include "Mod.h"
#include "PrimeTable.h"
#include "EulerTotient.h"
#include "Eratosthenes.h"

namespace Math {
  namespace Sieve {
    void eratosthenesRange(const mpz_t max, vector<mpz_t*> &primes) {
      vector<mpz_t*> buf;
      mpz_t i, j, p, tmp;
      mpz_inits(i, j, p, tmp, NULL);

      // Loop 2 -> max-1
      for (mpz_set_ui(i, 2); mpz_cmp(i, max) < 0; mpz_add_ui(i, i, 1)) {
        mpz_t *tmp0 = new mpz_t[1];
        mpz_init(*tmp0);
        mpz_set(*tmp0, i);
        buf.push_back(tmp0);
      }

      // Loop p=2 -> p*p <= max
      for (mpz_set_ui(p, 2), mpz_set_ui(j, 0);
           mpz_mul(tmp, p, p), mpz_cmp(tmp, max) <= 0;) {
        // Loop i=j+p -> i < buf.size()
        for (mpz_add(tmp, j, p); mpz_cmp_ui(tmp, buf.size()) < 0;
             mpz_add(tmp, tmp, p)) {
          // buf[i] = 0
          mpz_set_ui(*buf[mpz_get_ui(tmp)], 0);
        }

        // Loop i=j+1 -> i < buf.size()
        for (mpz_add_ui(tmp, j, 1); mpz_cmp_ui(tmp, buf.size()) < 0;
             mpz_add_ui(tmp, tmp, 1)) {
          // If buf[i] > 0
          if (mpz_cmp_ui(*buf[mpz_get_ui(tmp)], 0) > 0) {
            // p = buf[i]
            mpz_set(p, *buf[mpz_get_ui(tmp)]);
            mpz_set(j, tmp);
            break;
          }
        }
      }

      // Put all the found prime numbers into the vector.
      for (size_t i = 0; i < buf.size(); i++) {
        // If buf[i] > 0
        if (mpz_cmp_ui(*buf[i], 0) > 0) {
          primes.push_back(buf[i]);
        }

        // Clean up the ones we don't need.
        else {
          mpz_clear(*buf[i]);
          delete[] buf[i];
        }
      }

      buf.clear();
      mpz_clears(i, j, p, tmp, NULL);
    }

    void eratosthenesRange(const mpz_t min, const mpz_t max,
                           vector<mpz_t*> &primes) {
      if (mpz_cmp_ui(min, 2) == 0 && mpz_cmp_ui(max, 4) >= 0) {
        eratosthenesRange(max, primes);
        return;
      }

      mpz_t P, tot;
      mpz_inits(P, tot, NULL);
      mpz_sqrt(P, max);
      totient(P, tot);

      // Calculate offsets.
      vector<mpz_t*> q;
      mpz_t i, tmp;
      mpz_inits(i, tmp, NULL);
      for (mpz_set_ui(i, 0); mpz_cmp(i, tot) < 0; mpz_add_ui(i, i, 1)) {
         // Skip 2 because it is even.
        int pk = PRIME_TABLE[mpz_get_ui(i) + 1];

        // tmp = min + pk + 1
        mpz_add_ui(tmp, min, pk);
        mpz_add_ui(tmp, tmp, 1);

        // tmp = ceil(-1 * (tmp / 2))
        mpz_cdiv_q_ui(tmp, tmp, 2);
        mpz_mul_si(tmp, tmp, -1);
        mpz_mod_ui(tmp, tmp, pk);

        mpz_t *tmp_ = new mpz_t[1];
        mpz_init(*tmp_);
        mpz_set(*tmp_, tmp);
        q.push_back(tmp_);
      }

      // Find B such that B | (max - min).
      mpz_sub(tmp, max, min);
      mpz_t B, tmp2;
      mpz_inits(B, tmp2, NULL);
      mpz_sqrt(B, tmp);
      mpz_sub_ui(B, B, 1);
      while (true) {
        mpz_add_ui(B, B, 1);
        mpz_mod(tmp2, tmp, B);
        if (mpz_cmp_ui(tmp2, 0) == 0) {
          break;
        }
      }

      // Process blocks and strike out the multiples which are not
      // primes.
      vector<mpz_t*> b;
      mpz_t T, tmp3;
      mpz_inits(T, tmp3, NULL);
      mpz_set(T, min);
      while (mpz_cmp(T, max) < 0) {
        for (mpz_set_ui(tmp, 0); mpz_cmp(tmp, B) < 0; mpz_add_ui(tmp, tmp, 1)) {
          mpz_t *tmp_ = new mpz_t[1];
          mpz_init(*tmp_);
          mpz_set_ui(*tmp_, 1);
          b.push_back(tmp_);
        }

        for (mpz_set_ui(tmp, 0); mpz_cmp(tmp, tot) < 0; mpz_add_ui(tmp, tmp, 1)) {
          int pk = PRIME_TABLE[mpz_get_ui(tmp) + 1];
          // j = q[k]
          mpz_set(tmp2, *q[mpz_get_ui(tmp)]);
          for (; mpz_cmp(tmp2, B) < 0; mpz_add_ui(tmp2, tmp2, pk)) {
            // b[j] = 0
            mpz_set_ui(*b[mpz_get_ui(tmp2)], 0);
          }

          // q[k] = mod(q[k] - B, pk);
          mpz_sub(tmp3, *q[mpz_get_ui(tmp)], B);
          mpz_mod_ui(*q[mpz_get_ui(tmp)], tmp3, pk);
        }

        for (mpz_set_ui(tmp, 0); mpz_cmp(tmp, B) < 0; mpz_add_ui(tmp, tmp, 1)) {
          // b[j] == 1
          if (mpz_cmp_ui(*b[mpz_get_ui(tmp)], 1) == 0) {
            // Found next prime...

            // p = T + 1 + (2 * j)
            mpz_add_ui(tmp2, T, 1);
            mpz_mul_ui(tmp3, tmp, 2);
            mpz_add(tmp2, tmp2, tmp3);

            if (mpz_cmp(tmp2, max) <= 0) {
              mpz_t *tmp_ = new mpz_t[1];
              mpz_init(*tmp_);
              mpz_set(*tmp_, tmp2);
              primes.push_back(tmp_);
            }
          }
        }

        // T += 2 * B
        mpz_mul_ui(tmp3, B, 2);
        mpz_add(T, T, tmp3);
      }

      // Clean up b and q vector.
      for (size_t j = 0; j < b.size(); j++) {
        mpz_clear(*b[j]);
        delete[] b[j];
      }

      for (size_t j = 0; j < q.size(); j++) {
        mpz_clear(*q[j]);
        delete[] q[j];
      }

      mpz_clears(P, tot, i, B, tmp, tmp2, T, tmp3, NULL);
    }

    vector<int> eratosthenesRangeI(int max) {
      vector<int> buf;
      for (int i = 2; i < max; i++) {
        buf.push_back(i);
      }

      for (int p = 2, j = 0; p * p <= max;) {
        for (size_t i = j + p; i < buf.size(); i += p) {
          buf[i] = 0;
        }

        for (size_t i = j + 1; i < buf.size(); i++) {
          if (buf[i] > 0) {
            p = buf[i];
            j = i;
            break;
          }
        }
      }

      vector<int> res;

      // Put all the found prime numbers into the vector.
      for (size_t i = 0; i < buf.size(); i++) {
        if (buf[i] > 0) {
          res.push_back(buf[i]);
        }
      }

      return res;
    }

    vector<int> eratosthenesRangeI(int min, int max) {
      // Don't use the segmented version in this case.
      if (min == 2 && max >= 4) {
        return eratosthenesRangeI(max);
      }

      int P = floor(sqrt(max));
      int tot = totient(P);

      // Calculate offsets.
      vector<int> q;
      for (int i = 0; i < tot; i++) {
        int pk = PRIME_TABLE[i + 1]; // Skip 2 because it is even.
        int qk = ceil(-1.0 * ((double) (min + 1 + pk) / 2.0));

        qk = mod(qk, pk);
        q.push_back(qk);
      }

      // Find B such that B | (max - min).
      int diff = max - min, B = floor(sqrt(diff)) - 1;
      while (mod(diff, ++B) != 0);

      // Process blocks and strike out the multiples which are not
      // primes.
      vector<int> b(B, 1), res;
      int T = min;
      while (T < max) {
        // This loop is essentially not required the first time.
        for (int j = 0; j < B; j++) {
          b[j] = 1;
        }

        for (int k = 0; k < tot; k++) {
          int pk = PRIME_TABLE[k + 1];
          for (int j = q[k]; j < B; j += pk) {
            b[j] = 0;
          }

          q[k] = mod(q[k] - B, pk);
        }

        for (int j = 0; j < B; j++) {
          if (b[j] == 1) {
            // Found next prime...
            int p = T + (2 * j) + 1;
            if (p <= max) {
              res.push_back(p);
            }
          }
        }

        T += 2 * B;
      }

      return res;
    }
  }
}
<commit_msg>Small modification.<commit_after>#include <cmath>

#include "Mod.h"
#include "PrimeTable.h"
#include "EulerTotient.h"
#include "Eratosthenes.h"

namespace Math {
  namespace Sieve {
    void eratosthenesRange(const mpz_t max, vector<mpz_t*> &primes) {
      vector<mpz_t*> buf;
      mpz_t i, j, p, tmp;
      mpz_inits(i, j, p, tmp, NULL);

      // Loop 2 -> max-1
      for (mpz_set_ui(i, 2); mpz_cmp(i, max) < 0; mpz_add_ui(i, i, 1)) {
        mpz_t *tmp0 = new mpz_t[1];
        mpz_init(*tmp0);
        mpz_set(*tmp0, i);
        buf.push_back(tmp0);
      }

      // Loop p=2 -> p*p <= max
      for (mpz_set_ui(p, 2), mpz_set_ui(j, 0);
           mpz_mul(tmp, p, p), mpz_cmp(tmp, max) <= 0;) {
        // Loop i=j+p -> i < buf.size()
        for (mpz_add(tmp, j, p); mpz_cmp_ui(tmp, buf.size()) < 0;
             mpz_add(tmp, tmp, p)) {
          // buf[i] = 0
          mpz_set_ui(*buf[mpz_get_ui(tmp)], 0);
        }

        // Loop i=j+1 -> i < buf.size()
        for (mpz_add_ui(tmp, j, 1); mpz_cmp_ui(tmp, buf.size()) < 0;
             mpz_add_ui(tmp, tmp, 1)) {
          // If buf[i] > 0
          if (mpz_cmp_ui(*buf[mpz_get_ui(tmp)], 0) > 0) {
            // p = buf[i]
            mpz_set(p, *buf[mpz_get_ui(tmp)]);
            mpz_set(j, tmp);
            break;
          }
        }
      }

      // Put all the found prime numbers into the vector.
      for (size_t i = 0; i < buf.size(); i++) {
        // If buf[i] > 0
        if (mpz_cmp_ui(*buf[i], 0) > 0) {
          primes.push_back(buf[i]);
        }

        // Clean up the ones we don't need.
        else {
          mpz_clear(*buf[i]);
          delete[] buf[i];
        }
      }

      buf.clear();
      mpz_clears(i, j, p, tmp, NULL);
    }

    void eratosthenesRange(const mpz_t min, const mpz_t max,
                           vector<mpz_t*> &primes) {
      if (mpz_cmp_ui(min, 2) == 0 && mpz_cmp_ui(max, 4) >= 0) {
        eratosthenesRange(max, primes);
        return;
      }

      mpz_t P, tot;
      mpz_inits(P, tot, NULL);
      mpz_sqrt(P, max);
      totient(P, tot);

      // Calculate offsets.
      vector<mpz_t*> q;
      mpz_t i, tmp;
      mpz_inits(i, tmp, NULL);
      for (mpz_set_ui(i, 0); mpz_cmp(i, tot) < 0; mpz_add_ui(i, i, 1)) {
         // Skip 2 because it is even.
        int pk = PRIME_TABLE[mpz_get_ui(i) + 1];

        // tmp = min + pk + 1
        mpz_add_ui(tmp, min, pk);
        mpz_add_ui(tmp, tmp, 1);

        // tmp = ceil(-1 * (tmp / 2))
        mpz_cdiv_q_ui(tmp, tmp, 2);
        mpz_mul_si(tmp, tmp, -1);
        mpz_mod_ui(tmp, tmp, pk);

        mpz_t *tmp_ = new mpz_t[1];
        mpz_init(*tmp_);
        mpz_set(*tmp_, tmp);
        q.push_back(tmp_);
      }

      // Find B such that B | (max - min).
      mpz_sub(tmp, max, min);
      mpz_t B, tmp2;
      mpz_inits(B, tmp2, NULL);
      mpz_sqrt(B, tmp);
      mpz_sub_ui(B, B, 1);
      while (true) {
        mpz_add_ui(B, B, 1);
        mpz_mod(tmp2, tmp, B);
        if (mpz_cmp_ui(tmp2, 0) == 0) {
          break;
        }
      }

      // Process blocks and strike out the multiples which are not
      // primes.
      vector<mpz_t*> b;
      mpz_t T, tmp3;
      mpz_inits(T, tmp3, NULL);
      mpz_set(T, min);
      while (mpz_cmp(T, max) < 0) {
        for (mpz_set_ui(tmp, 0); mpz_cmp(tmp, B) < 0; mpz_add_ui(tmp, tmp, 1)) {
          mpz_t *tmp_ = new mpz_t[1];
          mpz_init(*tmp_);
          mpz_set_ui(*tmp_, 1);
          b.push_back(tmp_);
        }

        for (mpz_set_ui(tmp, 0); mpz_cmp(tmp, tot) < 0; mpz_add_ui(tmp, tmp, 1)) {
          int pk = PRIME_TABLE[mpz_get_ui(tmp) + 1];
          // j = q[k]
          mpz_set(tmp2, *q[mpz_get_ui(tmp)]);
          for (; mpz_cmp(tmp2, B) < 0; mpz_add_ui(tmp2, tmp2, pk)) {
            // b[j] = 0
            mpz_set_ui(*b[mpz_get_ui(tmp2)], 0);
          }

          // q[k] = mod(q[k] - B, pk);
          mpz_sub(tmp3, *q[mpz_get_ui(tmp)], B);
          mpz_mod_ui(*q[mpz_get_ui(tmp)], tmp3, pk);
        }

        for (mpz_set_ui(tmp, 0); mpz_cmp(tmp, B) < 0; mpz_add_ui(tmp, tmp, 1)) {
          // b[j] == 1
          if (mpz_cmp_ui(*b[mpz_get_ui(tmp)], 1) == 0) {
            // Found next prime...

            // p = T + 1 + (2 * j)
            mpz_add_ui(tmp2, T, 1);
            mpz_mul_ui(tmp3, tmp, 2);
            mpz_add(tmp2, tmp2, tmp3);

            if (mpz_cmp(tmp2, max) <= 0) {
              mpz_t *tmp_ = new mpz_t[1];
              mpz_init(*tmp_);
              mpz_set(*tmp_, tmp2);
              primes.push_back(tmp_);
            }
          }
        }

        // T += 2 * B
        mpz_mul_ui(tmp3, B, 2);
        mpz_add(T, T, tmp3);
      }

      // Clean up b and q vector.
      for (size_t j = 0; j < b.size(); j++) {
        mpz_clear(*b[j]);
        delete[] b[j];
      }

      for (size_t j = 0; j < q.size(); j++) {
        mpz_clear(*q[j]);
        delete[] q[j];
      }

      mpz_clears(P, tot, i, B, tmp, tmp2, T, tmp3, NULL);
    }

    vector<int> eratosthenesRangeI(int max) {
      vector<int> buf;
      for (int i = 2; i < max; i++) {
        buf.push_back(i);
      }

      for (int p = 2, j = 0; p * p <= max;) {
        for (size_t i = j + p; i < buf.size(); i += p) {
          buf[i] = 0;
        }

        for (size_t i = j + 1; i < buf.size(); i++) {
          if (buf[i] > 0) {
            p = buf[i];
            j = i;
            break;
          }
        }
      }

      vector<int> res;

      // Put all the found prime numbers into the vector.
      for (size_t i = 0; i < buf.size(); i++) {
        if (buf[i] > 0) {
          res.push_back(buf[i]);
        }
      }

      return res;
    }

    vector<int> eratosthenesRangeI(int min, int max) {
      // Don't use the segmented version in this case.
      if (min == 2 && max >= 4) {
        return eratosthenesRangeI(max);
      }

      int P = floor(sqrt(max));
      int tot = totient(P);

      // Calculate offsets.
      vector<int> q;
      for (int i = 0; i < tot; i++) {
        int pk = PRIME_TABLE[i + 1]; // Skip 2 because it is even.
        int qk = ceil(-1.0 * ((double) (min + 1 + pk) / 2.0));

        qk = mod(qk, pk);
        q.push_back(qk);
      }

      // Find B such that B | (max - min).
      int diff = max - min, B = floor(sqrt(diff)) - 1;
      while (mod(diff, ++B) != 0);

      // Process blocks and strike out the multiples which are not
      // primes.
      vector<int> b(B, 1), res;
      int T = min;
      while (T < max) {
        // This loop is essentially not required the first time.
        for (int j = 0; j < B; j++) {
          b[j] = 1;
        }

        for (int k = 0; k < tot; k++) {
          int pk = PRIME_TABLE[k + 1];
          for (int j = q[k]; j < B; j += pk) {
            b[j] = 0;
          }

          q[k] = mod(q[k] - B, pk);
        }

        for (int j = 0; j < B; j++) {
          if (b[j] == 1) {
            // Found next prime...
            int p = T + (2 * j) + 1;
            if (p <= max) {
              res.push_back(p);
            }
          }
        }

        T += 2 * B;
      }

      return res;
    }
  }
}
<|endoftext|>


<commit_before>#include    <math.h>

#include    "FTExtrdGlyph.h"
#include    "FTVectoriser.h"

FTExtrdGlyph::FTExtrdGlyph( FT_Glyph glyph, float d)
:   FTGlyph( glyph),
    glList(0),
    depth(d)
{
    if( ft_glyph_format_outline != glyph->format)
    {
        return;
    }

    bBox.upperZ = -depth;

    FTVectoriser* vectoriser = new FTVectoriser( glyph);

    vectoriser->MakeMesh( 1.0);

    unsigned int numPoints = vectoriser->MeshPoints();
    if ( numPoints < 3)
    {
        delete vectoriser;
        return;
    }

    FTGL_DOUBLE* frontMesh = new FTGL_DOUBLE[ numPoints * 3];
    vectoriser->GetMesh( frontMesh);

    vectoriser->MakeMesh( -1.0);

    numPoints = vectoriser->MeshPoints();
    if ( numPoints < 3)
    {
        delete vectoriser;
        delete [] frontMesh;
        return;
    }

    FTGL_DOUBLE* backMesh =  new FTGL_DOUBLE[ numPoints * 3];
    vectoriser->GetMesh( backMesh);

    numPoints = vectoriser->points();
    int numContours = vectoriser->contours(); // FIXME

    if ( ( numContours < 1) || ( numPoints < 3))
    {
        delete vectoriser;
        delete [] frontMesh;
        delete [] backMesh;
        return;
    }

    // Draw the glyph
    int offset = 0;
    glList = glGenLists(1);
    glNewList( glList, GL_COMPILE);
    // Render Front Mesh
        int i;
        int BEPairs = static_cast<int>(frontMesh[0]);
        for( i = 0; i < BEPairs; ++i)
        {
            int polyType = (int)frontMesh[offset + 1];
            glBegin( polyType);
                glNormal3d(0.0, 0.0, 1.0);

                int verts = (int)frontMesh[offset+2];
                offset += 3;
                for( int x = 0; x < verts; ++x)
                {
                    glVertex3dv( frontMesh + offset);
                    offset += 3;
                }
            glEnd();
        }

    // Render Back Mesh
        offset = 0;
        BEPairs = static_cast<int>(backMesh[0]);
        for( i = 0; i < BEPairs; ++i)
        {
            int polyType = (int)backMesh[offset + 1];
            glBegin( polyType);

                glNormal3d(0.0, 0.0, -1.0);
                int verts = (int)backMesh[offset+2];
                offset += 3;
                for( int x = 0; x < verts; ++x)
                {
                    glVertex3d( backMesh[offset], backMesh[offset + 1], -depth); // FIXME
                    offset += 3;
                }
            glEnd();
        }

        int contourFlag = vectoriser->ContourFlag();

        for( unsigned int c = 0; c < vectoriser->contours(); ++c)
        {
            FTContour* contour = vectoriser->Contour(c);
            unsigned int numberOfPoints = contour->Points();

            glBegin( GL_QUAD_STRIP);
                for( unsigned int j = 0; j <= numberOfPoints; ++j)
                {
                    unsigned int index = ( j == numberOfPoints) ? 0 : j;
                    unsigned int nextIndex = ( index == numberOfPoints - 1) ? 0 : index + 1;

                    FTPoint normal = GetNormal( contour->Point(index), contour->Point(nextIndex));
                    glNormal3f( normal.x, normal.y, 0.0f);

                    if( contourFlag & ft_outline_reverse_fill)
                    {
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f);
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth);
                    }
                    else
                    {
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth);
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f);
                    }
                } // for
            glEnd();
        } // for

    glEndList();

    delete vectoriser;

    delete [] frontMesh;
    delete [] backMesh;

    // discard glyph image (bitmap or not)
    FT_Done_Glyph( glyph); // Why does this have to be HERE
}

FTExtrdGlyph::~FTExtrdGlyph()
{}

float FTExtrdGlyph::Render( const FTPoint& pen)
{
    if( glList)
    {
        glTranslatef( pen.x, pen.y, 0);
            glCallList( glList);
        glTranslatef( -pen.x, -pen.y, 0);
    }

    return advance;
}

FTPoint FTExtrdGlyph::GetNormal( const FTPoint &a, const FTPoint &b)
{
    float vectorX = a.x - b.x;
    float vectorY = a.y - b.y;

    float length = sqrt( vectorX * vectorX + vectorY * vectorY );

    if( length > 0.0f)
    {
        length = 1 / length;
    }
    else
    {
        length = 0.0f;
    }

    return FTPoint( -vectorY * length,
                     vectorX * length,
                     0.0f);
}

<commit_msg>Removed data buffers. Now call into vectoriser<commit_after>#include    <math.h>

#include    "FTExtrdGlyph.h"
#include    "FTVectoriser.h"

FTExtrdGlyph::FTExtrdGlyph( FT_Glyph glyph, float d)
:   FTGlyph( glyph),
    glList(0),
    depth(d)
{
    if( ft_glyph_format_outline != glyph->format)
    {
        return;
    }

    bBox.upperZ = -depth;

    FTVectoriser* vectoriser = new FTVectoriser( glyph);
    if ( ( vectoriser->ContourCount() < 1) || ( vectoriser->PointCount() < 3))
    {
        delete vectoriser;
        return;
    }

    glList = glGenLists(1);
    glNewList( glList, GL_COMPILE);

        vectoriser->MakeMesh( 1.0);
        glNormal3d(0.0, 0.0, 1.0);

        FTMesh* mesh = vectoriser->GetMesh();
        for( unsigned int index = 0; index < mesh->TesselationCount(); ++index)
        {
            FTTesselation* subMesh = mesh->Tesselation( index);
            unsigned int polyonType = subMesh->PolygonType();

            glBegin( polyonType);
                for( unsigned int x = 0; x < subMesh->PointCount(); ++x)
                {
                    glVertex3f( subMesh->Point(x).x / 64.0f,
                                subMesh->Point(x).y / 64.0f,
                                0.0f);
                }
            glEnd();
        }

        vectoriser->MakeMesh( -1.0);
        glNormal3d(0.0, 0.0, -1.0);

        mesh = vectoriser->GetMesh();
        for( unsigned int index = 0; index < mesh->TesselationCount(); ++index)
        {
            FTTesselation* subMesh = mesh->Tesselation( index);
            unsigned int polyonType = subMesh->PolygonType();

            glBegin( polyonType);
                for( unsigned int x = 0; x < subMesh->PointCount(); ++x)
                {
                    glVertex3f( subMesh->Point(x).x / 64.0f,
                                subMesh->Point(x).y / 64.0f,
                                -depth);
                }
            glEnd();
        }

        int contourFlag = vectoriser->ContourFlag();

        for( size_t c = 0; c < vectoriser->ContourCount(); ++c)
        {
            FTContour* contour = vectoriser->Contour(c);
            unsigned int numberOfPoints = contour->PointCount();

            glBegin( GL_QUAD_STRIP);
                for( unsigned int j = 0; j <= numberOfPoints; ++j)
                {
                    unsigned int index = ( j == numberOfPoints) ? 0 : j;
                    unsigned int nextIndex = ( index == numberOfPoints - 1) ? 0 : index + 1;

                    FTPoint normal = GetNormal( contour->Point(index), contour->Point(nextIndex));
                    glNormal3f( normal.x, normal.y, 0.0f);

                    if( contourFlag & ft_outline_reverse_fill)
                    {
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f);
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth);
                    }
                    else
                    {
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, -depth);
                        glVertex3f( contour->Point(index).x / 64.0f, contour->Point(index).y / 64.0f, 0.0f);
                    }
                } // for
            glEnd();
        } // for

    glEndList();

    delete vectoriser;

    // discard glyph image (bitmap or not)
    FT_Done_Glyph( glyph); // Why does this have to be HERE
}

FTExtrdGlyph::~FTExtrdGlyph()
{}

float FTExtrdGlyph::Render( const FTPoint& pen)
{
    if( glList)
    {
        glTranslatef( pen.x, pen.y, 0);
            glCallList( glList);
        glTranslatef( -pen.x, -pen.y, 0);
    }

    return advance;
}

FTPoint FTExtrdGlyph::GetNormal( const FTPoint &a, const FTPoint &b)
{
    float vectorX = a.x - b.x;
    float vectorY = a.y - b.y;

    float length = sqrt( vectorX * vectorX + vectorY * vectorY );

    if( length > 0.0f)
    {
        length = 1 / length;
    }
    else
    {
        length = 0.0f;
    }

    return FTPoint( -vectorY * length,
                     vectorX * length,
                     0.0f);
}

<|endoftext|>


<commit_before>#include "Settings.hpp"
#include "misc_ui.hpp"

namespace Slic3r { namespace GUI {

void Settings::Settings() {
    // Initialize fonts
    _small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    if (the_os == OS::Mac) _small_font.SetPointSize(11);
    _small_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    if (the_os == OS::Mac) _small_bold_font.SetPointSize(11);
    _small_bold_font.MakeBold()
    _medium_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    _medium_font.SetPointSize(12);

    _scroll_step = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)->GetPointSize();
}
void Settings::save_settings() {
/*
sub save_settings {
    my ($self) = @_;
    Slic3r::Config->write_ini("$datadir/slic3r.ini", $Settings);
}

*/

}

void Settings::save_window_pos(wxWindow* ref, wxString name) {
}

void Settings::restore_window_pos(wxWindow* ref, wxString name) {
}
}} // namespace Slic3r::GUI
<commit_msg>What's that semicolon?!?<commit_after>#include "Settings.hpp"
#include "misc_ui.hpp"

namespace Slic3r { namespace GUI {

void Settings::Settings() {
    // Initialize fonts
    _small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    if (the_os == OS::Mac) _small_font.SetPointSize(11);
    _small_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    if (the_os == OS::Mac) _small_bold_font.SetPointSize(11);
    _small_bold_font.MakeBold();
    _medium_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    _medium_font.SetPointSize(12);

    _scroll_step = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize();
}
void Settings::save_settings() {
/*
sub save_settings {
    my ($self) = @_;
    Slic3r::Config->write_ini("$datadir/slic3r.ini", $Settings);
}

*/

}

void Settings::save_window_pos(wxWindow* ref, wxString name) {
}

void Settings::restore_window_pos(wxWindow* ref, wxString name) {
}
}} // namespace Slic3r::GUI
<|endoftext|>