<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  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 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
//
//  Current versions can be found at www.libavg.de
//

#include "OGLImagingContext.h"

#include "../base/Exception.h"

#include <assert.h>
#include <iostream>

namespace avg {

using namespace std;

#ifdef _WIN32
LONG WINAPI imagingWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

void registerWindowClass()
{
  static char * pClassName;
  if (pClassName) {
      return;
  }
  pClassName = "GLUT";

  HINSTANCE hInstance = GetModuleHandle(NULL);
  WNDCLASS  wc;
  memset(&wc, 0, sizeof(WNDCLASS));
  wc.style = CS_OWNDC;
  wc.lpfnWndProc = (WNDPROC)imagingWindowProc;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
  wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
  wc.hbrBackground = NULL;
  wc.lpszMenuName = NULL;
  wc.lpszClassName = pClassName;

  BOOL bOK = RegisterClass(&wc);
  assert(bOK);
}
#endif

#ifdef linux
static bool s_bX11Error;
static int (*s_DefaultErrorHandler) (Display *, XErrorEvent *);

int X11ErrorHandler(Display * pDisplay, XErrorEvent * pErrEvent)
{
    if (pErrEvent->request_code == 145 && pErrEvent->minor_code == 7) {
        s_bX11Error = true;
    } else {
        s_DefaultErrorHandler(pDisplay, pErrEvent);
    }
}
#endif

OGLImagingContext::OGLImagingContext(const IntPoint & size)
{
#ifdef __APPLE__
    GLint attributes[] = {AGL_RGBA, AGL_ALL_RENDERERS,AGL_NONE};
    AGLPixelFormat format;
    format = aglChoosePixelFormat(NULL, 0, attributes);
    assert(format);

    m_Context = aglCreateContext(format, NULL);
    assert(m_Context);
    aglDestroyPixelFormat(format);

    bool bOk = aglSetCurrentContext(m_Context);
    assert (bOk);
#else
#ifdef linux
    Display *dpy;
    dpy = XOpenDisplay(0);
    if (!dpy) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "No X windows display available.");
    }
    XVisualInfo *vi;
    static int attributes[] = {GLX_RGBA, 0};
    vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
    m_Context = glXCreateContext(dpy, vi, 0, GL_TRUE);
    assert(m_Context);
    Pixmap pmp = XCreatePixmap(dpy, RootWindow(dpy, vi->screen),
            8, 8, vi->depth);
    GLXPixmap pixmap = glXCreateGLXPixmap(dpy, vi, pmp);

    s_bX11Error = false;
    s_DefaultErrorHandler = XSetErrorHandler(X11ErrorHandler);
    glXMakeCurrent(dpy, pixmap, m_Context);
    XSetErrorHandler(s_DefaultErrorHandler);

    if (s_bX11Error) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "X error creating OpenGL context.");
    }
#else
#ifdef _WIN32
    registerWindowClass();
    m_hwnd = CreateWindow("GLUT", "GLUT",
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
            0, 0, 500, 300, 0, 0, GetModuleHandle(NULL), 0);
    winOGLErrorCheck(m_hDC != 0, "CreateWindow");

    m_hDC = GetDC(m_hwnd);
    winOGLErrorCheck(m_hDC != 0, "GetDC");

    PIXELFORMATDESCRIPTOR pfd;
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 32;
    pfd.iLayerType = PFD_MAIN_PLANE;

    int iFormat = ChoosePixelFormat(m_hDC, &pfd);
    winOGLErrorCheck(iFormat != 0, "ChoosePixelFormat");
    SetPixelFormat(m_hDC, iFormat, &pfd);
    m_Context = wglCreateContext(m_hDC);
    winOGLErrorCheck(m_Context != 0, "wglCreateContext");

    BOOL bOK = wglMakeCurrent(m_hDC, m_Context);
    winOGLErrorCheck(bOK, "wglMakeCurrent");
#endif
#endif
#endif
    glproc::init();

    if (!isSupported()) {
        throw Exception(AVG_ERR_VIDEO_GENERAL,
                "GPU imaging not supported by current OpenGL configuration.");
    }

    // Coordinates
    setSize(size);

    // Shading etc.
    glDisable(GL_BLEND);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_BLEND)");
    glShadeModel(GL_FLAT);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glShadeModel(GL_FLAT)");
    glDisable(GL_DEPTH_TEST);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_DEPTH_TEST)");
    glDisable(GL_STENCIL_TEST);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_STENCIL_TEST)");

    // Texturing
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glTexEnvf()");
    glBlendFunc(GL_ONE, GL_ZERO);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glBlendFunc()");
    glEnable(GL_TEXTURE_RECTANGLE_ARB);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glEnable(GL_TEXTURE_RECTANGLE_ARB);");
    glDisable(GL_MULTISAMPLE);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_MULTISAMPLE);");

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

OGLImagingContext::~OGLImagingContext()
{
#ifdef __APPLE__
    if (m_Context) {
        aglSetCurrentContext(0);
        aglDestroyContext(m_Context);
        m_Context = 0;
    }
#endif
#ifdef _WIN32
    if (m_Context) {
        wglDeleteContext(m_Context);
        DeleteDC(m_hDC);
        DestroyWindow(m_hwnd);
    }
#endif
}

void OGLImagingContext::activate()
{
#ifdef __APPLE__
    bool bOk = aglSetCurrentContext(m_Context);
#elif defined _WIN32
    BOOL bOk = wglMakeCurrent(m_hDC, m_Context);
#endif
    assert(bOk);
}

void OGLImagingContext::setSize(const IntPoint& size)
{
    m_Size = size;
    glViewport(0, 0, m_Size.x, m_Size.y);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glViewport()");
    glMatrixMode(GL_PROJECTION);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glMatrixMode()");
    glLoadIdentity();
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glLoadIdentity()");
    gluOrtho2D(0, m_Size.x, m_Size.y, 0);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "gluOrtho2D()");
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glLoadIdentity()");
}

bool OGLImagingContext::isSupported()
{
    int glMajorVer;
    int glMinorVer;
    int slMajorVer;
    int slMinorVer;
    getGLVersion(glMajorVer, glMinorVer);
    getGLShadingLanguageVersion(slMajorVer, slMinorVer);
    // Not sure if we need shader version 1.2 as well - we'll see.
    return (glMajorVer > 1 && queryOGLExtension("GL_ARB_texture_rectangle") &&
            queryOGLExtension("GL_ARB_pixel_buffer_object") &&
            queryOGLExtension("GL_EXT_framebuffer_object"));
}

}

<commit_msg>src/graphics/OGLImagingContext.cpp: activate(): fix linux build.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  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 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
//
//  Current versions can be found at www.libavg.de
//

#include "OGLImagingContext.h"

#include "../base/Exception.h"

#include <assert.h>
#include <iostream>

namespace avg {

using namespace std;

#ifdef _WIN32
LONG WINAPI imagingWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

void registerWindowClass()
{
  static char * pClassName;
  if (pClassName) {
      return;
  }
  pClassName = "GLUT";

  HINSTANCE hInstance = GetModuleHandle(NULL);
  WNDCLASS  wc;
  memset(&wc, 0, sizeof(WNDCLASS));
  wc.style = CS_OWNDC;
  wc.lpfnWndProc = (WNDPROC)imagingWindowProc;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
  wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
  wc.hbrBackground = NULL;
  wc.lpszMenuName = NULL;
  wc.lpszClassName = pClassName;

  BOOL bOK = RegisterClass(&wc);
  assert(bOK);
}
#endif

#ifdef linux
static bool s_bX11Error;
static int (*s_DefaultErrorHandler) (Display *, XErrorEvent *);

int X11ErrorHandler(Display * pDisplay, XErrorEvent * pErrEvent)
{
    if (pErrEvent->request_code == 145 && pErrEvent->minor_code == 7) {
        s_bX11Error = true;
    } else {
        s_DefaultErrorHandler(pDisplay, pErrEvent);
    }
}
#endif

OGLImagingContext::OGLImagingContext(const IntPoint & size)
{
#ifdef __APPLE__
    GLint attributes[] = {AGL_RGBA, AGL_ALL_RENDERERS,AGL_NONE};
    AGLPixelFormat format;
    format = aglChoosePixelFormat(NULL, 0, attributes);
    assert(format);

    m_Context = aglCreateContext(format, NULL);
    assert(m_Context);
    aglDestroyPixelFormat(format);

    bool bOk = aglSetCurrentContext(m_Context);
    assert (bOk);
#else
#ifdef linux
    Display *dpy;
    dpy = XOpenDisplay(0);
    if (!dpy) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "No X windows display available.");
    }
    XVisualInfo *vi;
    static int attributes[] = {GLX_RGBA, 0};
    vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
    m_Context = glXCreateContext(dpy, vi, 0, GL_TRUE);
    assert(m_Context);
    Pixmap pmp = XCreatePixmap(dpy, RootWindow(dpy, vi->screen),
            8, 8, vi->depth);
    GLXPixmap pixmap = glXCreateGLXPixmap(dpy, vi, pmp);

    s_bX11Error = false;
    s_DefaultErrorHandler = XSetErrorHandler(X11ErrorHandler);
    glXMakeCurrent(dpy, pixmap, m_Context);
    XSetErrorHandler(s_DefaultErrorHandler);

    if (s_bX11Error) {
        throw Exception(AVG_ERR_VIDEO_GENERAL, "X error creating OpenGL context.");
    }
#else
#ifdef _WIN32
    registerWindowClass();
    m_hwnd = CreateWindow("GLUT", "GLUT",
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
            0, 0, 500, 300, 0, 0, GetModuleHandle(NULL), 0);
    winOGLErrorCheck(m_hDC != 0, "CreateWindow");

    m_hDC = GetDC(m_hwnd);
    winOGLErrorCheck(m_hDC != 0, "GetDC");

    PIXELFORMATDESCRIPTOR pfd;
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.cDepthBits = 32;
    pfd.iLayerType = PFD_MAIN_PLANE;

    int iFormat = ChoosePixelFormat(m_hDC, &pfd);
    winOGLErrorCheck(iFormat != 0, "ChoosePixelFormat");
    SetPixelFormat(m_hDC, iFormat, &pfd);
    m_Context = wglCreateContext(m_hDC);
    winOGLErrorCheck(m_Context != 0, "wglCreateContext");

    BOOL bOK = wglMakeCurrent(m_hDC, m_Context);
    winOGLErrorCheck(bOK, "wglMakeCurrent");
#endif
#endif
#endif
    glproc::init();

    if (!isSupported()) {
        throw Exception(AVG_ERR_VIDEO_GENERAL,
                "GPU imaging not supported by current OpenGL configuration.");
    }

    // Coordinates
    setSize(size);

    // Shading etc.
    glDisable(GL_BLEND);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_BLEND)");
    glShadeModel(GL_FLAT);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glShadeModel(GL_FLAT)");
    glDisable(GL_DEPTH_TEST);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_DEPTH_TEST)");
    glDisable(GL_STENCIL_TEST);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_STENCIL_TEST)");

    // Texturing
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glTexEnvf()");
    glBlendFunc(GL_ONE, GL_ZERO);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glBlendFunc()");
    glEnable(GL_TEXTURE_RECTANGLE_ARB);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glEnable(GL_TEXTURE_RECTANGLE_ARB);");
    glDisable(GL_MULTISAMPLE);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glDisable(GL_MULTISAMPLE);");

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

OGLImagingContext::~OGLImagingContext()
{
#ifdef __APPLE__
    if (m_Context) {
        aglSetCurrentContext(0);
        aglDestroyContext(m_Context);
        m_Context = 0;
    }
#endif
#ifdef _WIN32
    if (m_Context) {
        wglDeleteContext(m_Context);
        DeleteDC(m_hDC);
        DestroyWindow(m_hwnd);
    }
#endif
}

void OGLImagingContext::activate()
{
#ifdef __APPLE__
    bool bOk = aglSetCurrentContext(m_Context);
    assert(bOk);
#elif defined _WIN32
    BOOL bOk = wglMakeCurrent(m_hDC, m_Context);
    assert(bOk);
#endif
    // TODO: X version
}

void OGLImagingContext::setSize(const IntPoint& size)
{
    m_Size = size;
    glViewport(0, 0, m_Size.x, m_Size.y);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glViewport()");
    glMatrixMode(GL_PROJECTION);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glMatrixMode()");
    glLoadIdentity();
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glLoadIdentity()");
    gluOrtho2D(0, m_Size.x, m_Size.y, 0);
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "gluOrtho2D()");
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "glLoadIdentity()");
}

bool OGLImagingContext::isSupported()
{
    int glMajorVer;
    int glMinorVer;
    int slMajorVer;
    int slMinorVer;
    getGLVersion(glMajorVer, glMinorVer);
    getGLShadingLanguageVersion(slMajorVer, slMinorVer);
    // Not sure if we need shader version 1.2 as well - we'll see.
    return (glMajorVer > 1 && queryOGLExtension("GL_ARB_texture_rectangle") &&
            queryOGLExtension("GL_ARB_pixel_buffer_object") &&
            queryOGLExtension("GL_EXT_framebuffer_object"));
}

}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, 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.GPL 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 are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgesturemanager_p.h"
#include "qgesture.h"
#include "qevent.h"

#include "qapplication.h"
#include "private/qapplication_p.h"

#include "private/qgesturestandardrecognizers_p.h"

#include "qdebug.h"

// #define GESTURE_DEBUG
#ifndef GESTURE_DEBUG
# define DEBUG if (0) qDebug
#else
# define DEBUG qDebug
#endif

QT_BEGIN_NAMESPACE

bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
static bool qt_sendGestureEvent(QWidget *receiver, QGestureEvent *event)
{
    QSet<Qt::GestureType> eventGestures = event->gestureTypes().toSet();
    while (receiver && (receiver->gestures() & eventGestures).isEmpty())
        receiver = receiver->parentWidget();
    return receiver ? qt_sendSpontaneousEvent(receiver, event) : false;
}

static const unsigned int maximumGestureRecognitionTimeout = 2000;

QGestureManager::QGestureManager()
    : targetWidget(0), state(NotGesture)
{
    recognizers << new QDoubleTapGestureRecognizer();
    recognizers << new QLongTapGestureRecognizer();
    recognizers << new QGestureRecognizerPan();
    // recognizers << new QMultiTouchGestureRecognizer();

    foreach(QGestureRecognizer *r, recognizers)
        connect(r, SIGNAL(triggered(QGestureRecognizer::Result)),
                this, SLOT(recognizerTriggered(QGestureRecognizer::Result)));
}

bool QGestureManager::filterEvent(QEvent *event)
{
    if (!QApplication::testAttribute(Qt::AA_EnableGestures))
        return false;

    QList<QEvent*> events;
    events << event;

    QPoint currentPos;
    switch (event->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseButtonDblClick:
    case QEvent::MouseMove:
        currentPos = static_cast<QMouseEvent*>(event)->pos(); break;
    default: break;
    }

    const QMap<Qt::GestureType, int> &grabbedGestures = qApp->d_func()->grabbedGestures;

    bool ret = false;
    QSet<QGestureRecognizer*> startedGestures;
    QSet<QGestureRecognizer*> finishedGestures;
    QSet<QGestureRecognizer*> newMaybeGestures;
    QSet<QGestureRecognizer*> cancelledGestures;
    QSet<QGestureRecognizer*> notGestures;
    if (state == NotGesture || state == MaybeGesture) {
        DEBUG() << "QGestureManager: current event processing state: "
                << (state == NotGesture ? "NotGesture" : "MaybeGesture");

        Q_ASSERT(targetWidget != 0);
        QSet<QGestureRecognizer*> stillMaybeGestures;
        // try other recognizers.
        foreach(QGestureRecognizer *r, recognizers) {
            if (grabbedGestures.value(r->gestureType(), 0) <= 0)
                continue;
            QGestureRecognizer::Result result = r->recognize(events);
            if (result == QGestureRecognizer::GestureStarted) {
                DEBUG() << "QGestureManager: gesture started: " << r;
                startedGestures << r;
            } else if (result == QGestureRecognizer::GestureFinished) {
                DEBUG() << "QGestureManager: gesture finished: " << r;
                finishedGestures << r;
            } else if (result == QGestureRecognizer::MaybeGesture) {
                DEBUG() << "QGestureManager: maybe gesture: " << r;
                newMaybeGestures << r;
            } else {
                // if it was maybe gesture, but isn't a gesture anymore.
                DEBUG() << "QGestureManager: not gesture: " << r;
                notGestures << r;
            }
        }
        activeGestures -= newMaybeGestures;
        activeGestures += startedGestures;
        foreach(QGestureRecognizer *r, startedGestures+finishedGestures+notGestures) {
            QMap<QGestureRecognizer*, int>::iterator it = maybeGestures.find(r);
            if (it != maybeGestures.end()) {
                killTimer(it.value());
                maybeGestures.erase(it);
            }
        }
        foreach(QGestureRecognizer *r, newMaybeGestures) {
            if (!maybeGestures.contains(r)) {
                int timerId = startTimer(maximumGestureRecognitionTimeout);
                if (!timerId)
                    qWarning("QGestureManager: couldn't start timer!");
                maybeGestures.insert(r, timerId);
            }
        }
        if (!finishedGestures.isEmpty() || !activeGestures.isEmpty()) {
            // gesture found!
            ret = true;
            DEBUG() << "QGestureManager: sending gesture event for: "
                    << activeGestures << " and " << finishedGestures;

            QList<QGesture*> gestures;
            foreach(QGestureRecognizer *r, finishedGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
            foreach(QGestureRecognizer *r, activeGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
            Q_ASSERT(!gestures.isEmpty());
            QGestureEvent event(targetWidget, gestures);
            qt_sendGestureEvent(targetWidget, &event);

            if (!activeGestures.isEmpty()) {
                DEBUG() << "QGestureManager: new state = Gesture";
                state = Gesture;
            } else if (!maybeGestures.isEmpty()) {
                DEBUG() << "QGestureManager: new state = Maybe";
                state = MaybeGesture;
            } else {
                DEBUG() << "QGestureManager: new state = NotGesture";
                state = NotGesture;
            }
        } else if (!maybeGestures.isEmpty()) {
            if (state != MaybeGesture) {
                // We got a new set of events that look like a start
                // of some gesture, so we switch to state MaybeGesture
                // and wait for more events.
                DEBUG() << "QGestureManager: new state = Maybe. Waiting for events";
                state = MaybeGesture;
                // start gesture timer
            } else {
                // we still not sure if it is a gesture or not.
            }
        } else if (state == MaybeGesture) {
            // last time we thought it looks like gesture, but now we
            // know for sure that it isn't.
            DEBUG() << "QGestureManager: new state = NotGesture";
            state = NotGesture;
        }
        foreach(QGestureRecognizer *r, finishedGestures)
            r->reset();
        foreach(QGestureRecognizer *r, cancelledGestures)
            r->reset();
        foreach(QGestureRecognizer *r, notGestures)
            r->reset();
    } else if (state == Gesture) {
        DEBUG() << "QGestureManager: current event processing state: Gesture";
        Q_ASSERT(!activeGestures.isEmpty());

        foreach(QGestureRecognizer *r, recognizers) {
            if (grabbedGestures.value(r->gestureType(), 0) <= 0)
                continue;
            QGestureRecognizer::Result result = r->recognize(events);
            if (result == QGestureRecognizer::GestureStarted) {
                DEBUG() << "QGestureManager: gesture started: " << r;
                startedGestures << r;
            } else if (result == QGestureRecognizer::GestureFinished) {
                DEBUG() << "QGestureManager: gesture finished: " << r;
                finishedGestures << r;
            } else if (result == QGestureRecognizer::MaybeGesture) {
                DEBUG() << "QGestureManager: maybe gesture: " << r;
                newMaybeGestures << r;
            } else {
                // if it was an active gesture, but isn't a gesture anymore.
                if (activeGestures.contains(r)) {
                    DEBUG() << "QGestureManager: cancelled gesture: " << r;
                    cancelledGestures << r;
                } else {
                    DEBUG() << "QGestureManager: not gesture: " << r;
                    notGestures << r;
                }
            }
        }

        activeGestures -= newMaybeGestures;
        activeGestures -= cancelledGestures;
        activeGestures -= finishedGestures;
        activeGestures += startedGestures;
        foreach(QGestureRecognizer *r, startedGestures+finishedGestures+notGestures) {
            QMap<QGestureRecognizer*, int>::iterator it = maybeGestures.find(r);
            if (it != maybeGestures.end()) {
                killTimer(it.value());
                maybeGestures.erase(it);
            }
        }
        foreach(QGestureRecognizer *r, newMaybeGestures) {
            if (!maybeGestures.contains(r)) {
                int timerId = startTimer(maximumGestureRecognitionTimeout);
                if (!timerId)
                    qWarning("QGestureManager: couldn't start timer!");
                maybeGestures.insert(r, timerId);
            }
        }
        QList<QGesture*> gestures;
        if (!finishedGestures.isEmpty() || !activeGestures.isEmpty()) {
            // another gesture found!
            ret = true;
            DEBUG() << "QGestureManager: sending gesture event for: "
                    << activeGestures << " and " << finishedGestures;

            foreach(QGestureRecognizer *r, finishedGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
            foreach(QGestureRecognizer *r, activeGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
        }
        QSet<Qt::GestureType> cancelledGestureNames;
        foreach(QGestureRecognizer *r, cancelledGestures)
            cancelledGestureNames << r->gestureType();
        if(!gestures.isEmpty()) {
            QGestureEvent event(targetWidget, gestures, cancelledGestureNames);
            qt_sendGestureEvent(targetWidget, &event);
        }

        foreach(QGestureRecognizer *r, finishedGestures)
            r->reset();
        foreach(QGestureRecognizer *r, cancelledGestures)
            r->reset();
        foreach(QGestureRecognizer *r, notGestures)
            r->reset();
        if (!activeGestures.isEmpty()) {
            // nothing changed, we are still handling a gesture
        } else if (!maybeGestures.isEmpty()) {
            DEBUG() << "QGestureManager: new state = Maybe. Waiting for events: " << maybeGestures;
            state = MaybeGesture;
        } else {
            DEBUG() << "QGestureManager: new state = NotGesture";
            state = NotGesture;
        }
        ret = true;
    }

    lastPos = currentPos;
    return ret;
}

void QGestureManager::timerEvent(QTimerEvent *event)
{
    // sanity checks, remove later
    Q_ASSERT((state == Gesture && !activeGestures.isEmpty()) || (state != Gesture && activeGestures.isEmpty()));

    typedef QMap<QGestureRecognizer*, int> MaybeGestureMap;
    for (MaybeGestureMap::iterator it = maybeGestures.begin(), e = maybeGestures.end();
         it != e; ++it) {
        if (it.value() == event->timerId()) {
            DEBUG() << "QGestureManager: gesture timeout.";
            QGestureRecognizer *r = it.key();
            r->reset();
            maybeGestures.erase(it);
            killTimer(event->timerId());
            break;
        }
    }

    if (state == MaybeGesture && maybeGestures.isEmpty()) {
        DEBUG() << "QGestureManager: new state = NotGesture because of timeout";
        state = NotGesture;
    }
}

bool QGestureManager::inGestureMode()
{
    return state == Gesture;
}

void QGestureManager::setGestureTargetWidget(QWidget *widget)
{
    targetWidget = widget;
}

void QGestureManager::recognizerTriggered(QGestureRecognizer::Result result)
{
    if (!QApplication::testAttribute(Qt::AA_EnableGestures))
        return;

    QGestureRecognizer *recognizer = qobject_cast<QGestureRecognizer*>(sender());
    if (!recognizer)
        return;
    if (qApp->d_func()->grabbedGestures.value(recognizer->gestureType(), 0) <= 0) {
        recognizer->reset();
        return;
    }

    switch (result) {
    case QGestureRecognizer::GestureStarted:
    case QGestureRecognizer::GestureFinished: {
        if (result == QGestureRecognizer::GestureStarted) {
            DEBUG() << "QGestureManager: gesture started: " << recognizer;
            activeGestures << recognizer;
            DEBUG() << "QGestureManager: new state = Gesture";
            state = Gesture;
        } else {
            DEBUG() << "QGestureManager: gesture finished: " << recognizer;
        }
        if (maybeGestures.contains(recognizer)) {
            killTimer(maybeGestures.value(recognizer));
            maybeGestures.remove(recognizer);
        }
        QList<QGesture*> gestures;
        if (QGesture *gesture = recognizer->makeEvent())
            gestures << gesture;
        if(!gestures.isEmpty()) {
            QGestureEvent event(targetWidget, gestures);
            qt_sendGestureEvent(targetWidget, &event);
        }
        if (result == QGestureRecognizer::GestureFinished)
            recognizer->reset();
    }
        break;
    case QGestureRecognizer::MaybeGesture: {
        DEBUG() << "QGestureManager: maybe gesture: " << recognizer;
        if (activeGestures.contains(recognizer)) {
            QGestureEvent event(targetWidget, QList<QGesture*>(),
                                QSet<Qt::GestureType>() << recognizer->gestureType());
            qt_sendGestureEvent(targetWidget, &event);
        }
        if (!maybeGestures.contains(recognizer)) {
            int timerId = startTimer(maximumGestureRecognitionTimeout);
            if (!timerId)
                qWarning("QGestureManager: couldn't start timer!");
            maybeGestures.insert(recognizer, timerId);
        }
    }
        break;
    case QGestureRecognizer::NotGesture:
        DEBUG() << "QGestureManager: not gesture: " << recognizer;
        if (maybeGestures.contains(recognizer)) {
            killTimer(maybeGestures.value(recognizer));
            maybeGestures.remove(recognizer);
        }
        recognizer->reset();
        break;
    default:
        Q_ASSERT(false);
    }
}

QT_END_NAMESPACE

#include "moc_qgesturemanager_p.cpp"

<commit_msg>If the event wasn't consumed by the gesture target widget, then gesture manager should consume it as well.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, 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.GPL 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 are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgesturemanager_p.h"
#include "qgesture.h"
#include "qevent.h"

#include "qapplication.h"
#include "private/qapplication_p.h"

#include "private/qgesturestandardrecognizers_p.h"

#include "qdebug.h"

// #define GESTURE_DEBUG
#ifndef GESTURE_DEBUG
# define DEBUG if (0) qDebug
#else
# define DEBUG qDebug
#endif

QT_BEGIN_NAMESPACE

bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
static bool qt_sendGestureEvent(QWidget *receiver, QGestureEvent *event)
{
    QSet<Qt::GestureType> eventGestures = event->gestureTypes().toSet();
    while (receiver && (receiver->gestures() & eventGestures).isEmpty())
        receiver = receiver->parentWidget();
    return receiver ? qt_sendSpontaneousEvent(receiver, event) : false;
}

static const unsigned int maximumGestureRecognitionTimeout = 2000;

QGestureManager::QGestureManager()
    : targetWidget(0), state(NotGesture)
{
    recognizers << new QDoubleTapGestureRecognizer();
    recognizers << new QLongTapGestureRecognizer();
    recognizers << new QGestureRecognizerPan();
    // recognizers << new QMultiTouchGestureRecognizer();

    foreach(QGestureRecognizer *r, recognizers)
        connect(r, SIGNAL(triggered(QGestureRecognizer::Result)),
                this, SLOT(recognizerTriggered(QGestureRecognizer::Result)));
}

bool QGestureManager::filterEvent(QEvent *event)
{
    if (!QApplication::testAttribute(Qt::AA_EnableGestures))
        return false;

    QList<QEvent*> events;
    events << event;

    QPoint currentPos;
    switch (event->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseButtonDblClick:
    case QEvent::MouseMove:
        currentPos = static_cast<QMouseEvent*>(event)->pos(); break;
    default: break;
    }

    const QMap<Qt::GestureType, int> &grabbedGestures = qApp->d_func()->grabbedGestures;

    bool ret = false;
    QSet<QGestureRecognizer*> startedGestures;
    QSet<QGestureRecognizer*> finishedGestures;
    QSet<QGestureRecognizer*> newMaybeGestures;
    QSet<QGestureRecognizer*> cancelledGestures;
    QSet<QGestureRecognizer*> notGestures;
    if (state == NotGesture || state == MaybeGesture) {
        DEBUG() << "QGestureManager: current event processing state: "
                << (state == NotGesture ? "NotGesture" : "MaybeGesture");

        Q_ASSERT(targetWidget != 0);
        QSet<QGestureRecognizer*> stillMaybeGestures;
        // try other recognizers.
        foreach(QGestureRecognizer *r, recognizers) {
            if (grabbedGestures.value(r->gestureType(), 0) <= 0)
                continue;
            QGestureRecognizer::Result result = r->recognize(events);
            if (result == QGestureRecognizer::GestureStarted) {
                DEBUG() << "QGestureManager: gesture started: " << r;
                startedGestures << r;
            } else if (result == QGestureRecognizer::GestureFinished) {
                DEBUG() << "QGestureManager: gesture finished: " << r;
                finishedGestures << r;
            } else if (result == QGestureRecognizer::MaybeGesture) {
                DEBUG() << "QGestureManager: maybe gesture: " << r;
                newMaybeGestures << r;
            } else {
                // if it was maybe gesture, but isn't a gesture anymore.
                DEBUG() << "QGestureManager: not gesture: " << r;
                notGestures << r;
            }
        }
        activeGestures -= newMaybeGestures;
        activeGestures += startedGestures;
        foreach(QGestureRecognizer *r, startedGestures+finishedGestures+notGestures) {
            QMap<QGestureRecognizer*, int>::iterator it = maybeGestures.find(r);
            if (it != maybeGestures.end()) {
                killTimer(it.value());
                maybeGestures.erase(it);
            }
        }
        foreach(QGestureRecognizer *r, newMaybeGestures) {
            if (!maybeGestures.contains(r)) {
                int timerId = startTimer(maximumGestureRecognitionTimeout);
                if (!timerId)
                    qWarning("QGestureManager: couldn't start timer!");
                maybeGestures.insert(r, timerId);
            }
        }
        if (!finishedGestures.isEmpty() || !activeGestures.isEmpty()) {
            // gesture found!
            ret = true;
            DEBUG() << "QGestureManager: sending gesture event for: "
                    << activeGestures << " and " << finishedGestures;

            QList<QGesture*> gestures;
            foreach(QGestureRecognizer *r, finishedGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
            foreach(QGestureRecognizer *r, activeGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
            Q_ASSERT(!gestures.isEmpty());
            QGestureEvent event(targetWidget, gestures);
            ret = qt_sendGestureEvent(targetWidget, &event);
            ret = ret && event.isAccepted();

            if (!activeGestures.isEmpty()) {
                DEBUG() << "QGestureManager: new state = Gesture";
                state = Gesture;
            } else if (!maybeGestures.isEmpty()) {
                DEBUG() << "QGestureManager: new state = Maybe";
                state = MaybeGesture;
            } else {
                DEBUG() << "QGestureManager: new state = NotGesture";
                state = NotGesture;
            }
        } else if (!maybeGestures.isEmpty()) {
            if (state != MaybeGesture) {
                // We got a new set of events that look like a start
                // of some gesture, so we switch to state MaybeGesture
                // and wait for more events.
                DEBUG() << "QGestureManager: new state = Maybe. Waiting for events";
                state = MaybeGesture;
                // start gesture timer
            } else {
                // we still not sure if it is a gesture or not.
            }
        } else if (state == MaybeGesture) {
            // last time we thought it looks like gesture, but now we
            // know for sure that it isn't.
            DEBUG() << "QGestureManager: new state = NotGesture";
            state = NotGesture;
        }
        foreach(QGestureRecognizer *r, finishedGestures)
            r->reset();
        foreach(QGestureRecognizer *r, cancelledGestures)
            r->reset();
        foreach(QGestureRecognizer *r, notGestures)
            r->reset();
    } else if (state == Gesture) {
        DEBUG() << "QGestureManager: current event processing state: Gesture";
        Q_ASSERT(!activeGestures.isEmpty());

        foreach(QGestureRecognizer *r, recognizers) {
            if (grabbedGestures.value(r->gestureType(), 0) <= 0)
                continue;
            QGestureRecognizer::Result result = r->recognize(events);
            if (result == QGestureRecognizer::GestureStarted) {
                DEBUG() << "QGestureManager: gesture started: " << r;
                startedGestures << r;
            } else if (result == QGestureRecognizer::GestureFinished) {
                DEBUG() << "QGestureManager: gesture finished: " << r;
                finishedGestures << r;
            } else if (result == QGestureRecognizer::MaybeGesture) {
                DEBUG() << "QGestureManager: maybe gesture: " << r;
                newMaybeGestures << r;
            } else {
                // if it was an active gesture, but isn't a gesture anymore.
                if (activeGestures.contains(r)) {
                    DEBUG() << "QGestureManager: cancelled gesture: " << r;
                    cancelledGestures << r;
                } else {
                    DEBUG() << "QGestureManager: not gesture: " << r;
                    notGestures << r;
                }
            }
        }

        activeGestures -= newMaybeGestures;
        activeGestures -= cancelledGestures;
        activeGestures -= finishedGestures;
        activeGestures += startedGestures;
        foreach(QGestureRecognizer *r, startedGestures+finishedGestures+notGestures) {
            QMap<QGestureRecognizer*, int>::iterator it = maybeGestures.find(r);
            if (it != maybeGestures.end()) {
                killTimer(it.value());
                maybeGestures.erase(it);
            }
        }
        foreach(QGestureRecognizer *r, newMaybeGestures) {
            if (!maybeGestures.contains(r)) {
                int timerId = startTimer(maximumGestureRecognitionTimeout);
                if (!timerId)
                    qWarning("QGestureManager: couldn't start timer!");
                maybeGestures.insert(r, timerId);
            }
        }
        QList<QGesture*> gestures;
        if (!finishedGestures.isEmpty() || !activeGestures.isEmpty()) {
            // another gesture found!
            ret = true;
            DEBUG() << "QGestureManager: sending gesture event for: "
                    << activeGestures << " and " << finishedGestures;

            foreach(QGestureRecognizer *r, finishedGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
            foreach(QGestureRecognizer *r, activeGestures) {
                if (QGesture *gesture = r->makeEvent())
                    gestures << gesture;
            }
        }
        QSet<Qt::GestureType> cancelledGestureNames;
        foreach(QGestureRecognizer *r, cancelledGestures)
            cancelledGestureNames << r->gestureType();
        if(!gestures.isEmpty()) {
            QGestureEvent event(targetWidget, gestures, cancelledGestureNames);
            ret = qt_sendGestureEvent(targetWidget, &event);
            ret = ret && event.isAccepted();
        }

        foreach(QGestureRecognizer *r, finishedGestures)
            r->reset();
        foreach(QGestureRecognizer *r, cancelledGestures)
            r->reset();
        foreach(QGestureRecognizer *r, notGestures)
            r->reset();
        if (!activeGestures.isEmpty()) {
            // nothing changed, we are still handling a gesture
        } else if (!maybeGestures.isEmpty()) {
            DEBUG() << "QGestureManager: new state = Maybe. Waiting for events: " << maybeGestures;
            state = MaybeGesture;
        } else {
            DEBUG() << "QGestureManager: new state = NotGesture";
            state = NotGesture;
        }
    }

    lastPos = currentPos;
    return ret;
}

void QGestureManager::timerEvent(QTimerEvent *event)
{
    // sanity checks, remove later
    Q_ASSERT((state == Gesture && !activeGestures.isEmpty()) || (state != Gesture && activeGestures.isEmpty()));

    typedef QMap<QGestureRecognizer*, int> MaybeGestureMap;
    for (MaybeGestureMap::iterator it = maybeGestures.begin(), e = maybeGestures.end();
         it != e; ++it) {
        if (it.value() == event->timerId()) {
            DEBUG() << "QGestureManager: gesture timeout.";
            QGestureRecognizer *r = it.key();
            r->reset();
            maybeGestures.erase(it);
            killTimer(event->timerId());
            break;
        }
    }

    if (state == MaybeGesture && maybeGestures.isEmpty()) {
        DEBUG() << "QGestureManager: new state = NotGesture because of timeout";
        state = NotGesture;
    }
}

bool QGestureManager::inGestureMode()
{
    return state == Gesture;
}

void QGestureManager::setGestureTargetWidget(QWidget *widget)
{
    targetWidget = widget;
}

void QGestureManager::recognizerTriggered(QGestureRecognizer::Result result)
{
    if (!QApplication::testAttribute(Qt::AA_EnableGestures))
        return;

    QGestureRecognizer *recognizer = qobject_cast<QGestureRecognizer*>(sender());
    if (!recognizer)
        return;
    if (qApp->d_func()->grabbedGestures.value(recognizer->gestureType(), 0) <= 0) {
        recognizer->reset();
        return;
    }

    switch (result) {
    case QGestureRecognizer::GestureStarted:
    case QGestureRecognizer::GestureFinished: {
        if (result == QGestureRecognizer::GestureStarted) {
            DEBUG() << "QGestureManager: gesture started: " << recognizer;
            activeGestures << recognizer;
            DEBUG() << "QGestureManager: new state = Gesture";
            state = Gesture;
        } else {
            DEBUG() << "QGestureManager: gesture finished: " << recognizer;
        }
        if (maybeGestures.contains(recognizer)) {
            killTimer(maybeGestures.value(recognizer));
            maybeGestures.remove(recognizer);
        }
        QList<QGesture*> gestures;
        if (QGesture *gesture = recognizer->makeEvent())
            gestures << gesture;
        if(!gestures.isEmpty()) {
            QGestureEvent event(targetWidget, gestures);
            qt_sendGestureEvent(targetWidget, &event);
        }
        if (result == QGestureRecognizer::GestureFinished)
            recognizer->reset();
    }
        break;
    case QGestureRecognizer::MaybeGesture: {
        DEBUG() << "QGestureManager: maybe gesture: " << recognizer;
        if (activeGestures.contains(recognizer)) {
            QGestureEvent event(targetWidget, QList<QGesture*>(),
                                QSet<Qt::GestureType>() << recognizer->gestureType());
            qt_sendGestureEvent(targetWidget, &event);
        }
        if (!maybeGestures.contains(recognizer)) {
            int timerId = startTimer(maximumGestureRecognitionTimeout);
            if (!timerId)
                qWarning("QGestureManager: couldn't start timer!");
            maybeGestures.insert(recognizer, timerId);
        }
    }
        break;
    case QGestureRecognizer::NotGesture:
        DEBUG() << "QGestureManager: not gesture: " << recognizer;
        if (maybeGestures.contains(recognizer)) {
            killTimer(maybeGestures.value(recognizer));
            maybeGestures.remove(recognizer);
        }
        recognizer->reset();
        break;
    default:
        Q_ASSERT(false);
    }
}

QT_END_NAMESPACE

#include "moc_qgesturemanager_p.cpp"

<|endoftext|>


<commit_before>#include "global.h"
#include "RoleFactory.h"
#include "config/constraints.h"
#include "dclass/file/read.h"
#include "dclass/dc/Class.h"
using dclass::Class;

#include <boost/filesystem.hpp>
#include <cstring>
#include <string>  // std::string
#include <vector>  // std::vector
#include <fstream> // std::ifstream
using namespace std;

static LogCategory mainlog("main", "Main");

static ConfigGroup general_config("general");
static ConfigVariable<vector<string> > dc_files("dc_files", vector<string>(), general_config);
static ConfigVariable<string> eventlogger_addr("eventlogger", "", general_config);
static ValidAddressConstraint valid_eventlogger_addr(eventlogger_addr);

static ConfigList uberdogs_config("uberdogs");
static ConfigVariable<doid_t> uberdog_id("id", INVALID_DO_ID, uberdogs_config);
static ConfigVariable<string> uberdog_class("class", "", uberdogs_config);
static ConfigVariable<bool> uberdog_anon("anonymous", false, uberdogs_config);
static InvalidDoidConstraint id_not_invalid(uberdog_id);
static ReservedDoidConstraint id_not_reserved(uberdog_id);
static BooleanValueConstraint anonymous_is_boolean(uberdog_anon);

static void printHelp(ostream &s);
static void printCompiledOptions(ostream &s);

int main(int argc, char *argv[])
{
	string cfg_file;

	int config_arg_index = -1;
	cfg_file = "astrond.yml";
	LogSeverity sev = g_logger->get_min_severity();
	for(int i = 1; i < argc; i++)
	{
		if((strcmp(argv[i], "--log") == 0 || strcmp(argv[i], "-L") == 0) && i + 1 < argc)
		{
			delete g_logger;
			g_logger = new Logger(argv[++i], sev);
		}
		else if((strcmp(argv[i], "--loglevel") == 0 || strcmp(argv[i], "-l") == 0) && i + 1 < argc)
		{
			string llstr(argv[++i]);
			if(llstr == "packet")
			{
				sev = LSEVERITY_PACKET;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "trace")
			{
				sev = LSEVERITY_TRACE;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "debug")
			{
				sev = LSEVERITY_DEBUG;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "info")
			{
				sev = LSEVERITY_INFO;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "warning")
			{
				sev = LSEVERITY_INFO;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "security")
			{
				sev = LSEVERITY_SECURITY;
				g_logger->set_min_severity(sev);
			}
			else if(llstr != "error" && llstr != "fatal")
			{
				cerr << "Unknown log-level \"" << llstr << "\"." << endl;
				printHelp(cerr);
				exit(1);
			}
		}
		else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
		{
			printHelp(cout);
			exit(0);
		}
        else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0)
        {
             cout << "A Server Technology for Realtime Object Networking (Astron)\n"
                     "http://github.com/astron/astron\n"

#ifdef GIT_SHA1
            "Revision: " << GIT_SHA1 << "\n"
#else
            "Revision: NOT-IN-GIT\n"
#endif
            "Compiled at " << __TIME__ << " on " << __DATE__ << endl;

            printCompiledOptions(cout);

            exit(0);
        }
		else if(argv[i][0] == '-')
		{
			cerr << "Unrecognized option \"" << string(argv[i]) << "\".\n";
			printHelp(cerr);
			exit(1);
		}
		else
		{
			if(config_arg_index != -1)
			{
				cerr << "Recieved additional positional argument \""
				     << string(argv[i]) << "\" but can only accept one."
				     << "\n  First positional: \""
				     << string(argv[config_arg_index]) << "\".\n";
			}
			else
			{
				config_arg_index = i;
			}
		}
	}

	if(config_arg_index != -1)
	{
		string filename = "";
		cfg_file = argv[config_arg_index];

		try
		{
			// seperate path
			boost::filesystem::path p(cfg_file);
			boost::filesystem::path dir = p.parent_path();
			filename = p.filename().string();
			string dir_str = dir.string();

			// change directory
			if(!dir_str.empty())
			{
				boost::filesystem::current_path(dir_str);
			}
		}
		catch(const exception&)
		{
			mainlog.fatal() << "Could not change working directory to config directory.\n";
			exit(1);
		}

		cfg_file = filename;
	}

	mainlog.info() << "Loading configuration file...\n";

	ifstream file(cfg_file.c_str());
	if(!file.is_open())
	{
		mainlog.fatal() << "Failed to open configuration file \"" << cfg_file << "\".\n";
		return 1;
	}

	if(!g_config->load(file))
	{
		mainlog.fatal() << "Errors parsing YAML configuration file \"" << cfg_file << "\"!\n";
		return 1;
	}
	file.close();

	if(!ConfigGroup::root().validate(g_config->copy_node()))
	{
		mainlog.fatal() << "Configuration file contains errors.\n";
		return 1;
	}

	dclass::File* dcf = new dclass::File();
	dcf->add_keyword("required");
	dcf->add_keyword("ram");
	dcf->add_keyword("db");
	dcf->add_keyword("broadcast");
	dcf->add_keyword("clrecv");
	dcf->add_keyword("clsend");
	dcf->add_keyword("ownsend");
	dcf->add_keyword("ownrecv");
	dcf->add_keyword("airecv");
	vector<string> dc_file_names = dc_files.get_val();
	for(auto it = dc_file_names.begin(); it != dc_file_names.end(); ++it)
	{
		bool ok = dclass::append(dcf, *it);
		if(!ok)
		{
			mainlog.fatal() << "Could not read DC file " << *it << endl;
			return 1;
		}
	}
	g_dcf = dcf;

	// Initialize configured MessageDirector
	MessageDirector::singleton.init_network();
	g_eventsender.init(eventlogger_addr.get_val());

	// Load uberdog metadata from configuration
	ConfigNode udnodes = g_config->copy_node()["uberdogs"];
	if(!udnodes.IsNull())
	{
		for(auto it = udnodes.begin(); it != udnodes.end(); ++it)
		{
			ConfigNode udnode = *it;
			Uberdog ud;

			// Get the uberdog's class
			const Class* dcc = g_dcf->get_class_by_name(udnode["class"].as<std::string>());
			if(!dcc)
			{
				// Make sure it exists
				mainlog.fatal() << "For uberdog " << udnode["id"].as<doid_t>()
								<< " Distributed class " << udnode["class"].as<std::string>()
				                << " does not exist!" << std::endl;
				exit(1);
			}

			// Setup uberdog
			ud.dcc = dcc;
			ud.anonymous = udnode["anonymous"].as<bool>();
			g_uberdogs[udnode["id"].as<doid_t>()] = ud;
		}
	}

	// Initialize configured roles
	ConfigNode node = g_config->copy_node();
	node = node["roles"];
	for(auto it = node.begin(); it != node.end(); ++it)
	{
		RoleFactory::singleton().instantiate_role((*it)["type"].as<std::string>(), *it);
	}

	try
	{
		io_service.run();
	}
	catch(exception &e)
	{
		mainlog.fatal() << "Exception from the network io service: "
		                << e.what() << endl;
	}

	return 0;
}

// printHelp outputs the cli help-text to the given stream.
void printHelp(ostream &s)
{
	s << "Usage:    astrond [options]... [CONFIG_FILE]\n"
	     "\n"
	     "Astrond is a distributed server daemon.\n"
	     "By default Astron looks for a configuration file in the current\n"
	     "working directory as \"astrond.yml\".  A different config file path\n"
	     "can be specified as a positional argument.\n"
	     "\n"
	     "-h, --help      Print this help dialog.\n"
         "-v, --version   Print Version, Module and Compilation Information\n"
	     "-L, --log       Specify a file to write log messages to.\n"
	     "-l, --loglevel  Specify the minimum log level that should be logged;\n"
	     "                  Security, Error, and Fatal will always be logged;\n"
#ifdef ASTRON_DEBUG_MESSAGES
	     "                (available): packet, trace, debug, info, warning, security\n"
#else
	     "                (available): info, warning, security\n"
	     "                (unavailable): packet, trace, debug\n"
	     "                        [build with -DCMAKE_BUILD_TYPE=Debug]\n"
#endif
         "\n"
         "Example:\n"
         "    astrond /tmp/my_config_file.yaml\n"
         "\n";
	s.flush();
}

void printCompiledOptions(ostream &s)
{
    s << "Compilation options: "

//If on, datagrams and dclass fields will use 32-bit length tags instead of 16-bit.
#ifdef ASTRON_32BIT_DATAGRAMS
    "32-bit length tag Datagrams, "
#else
    "16-bit length tag Datagrams, "
#endif

//If on, channels will be 128-bit and doids and zones will be 64-bit (instead of 64/32).
#ifdef ASTRON_128BIT_CHANNELS
    "128-bit channel space, 64-bit distributed object id's, 64-bit zones"
#else
    "64-bit channel space, 32-bit distributed object id's, 32-bit zones"
#endif
    <<"\n";

    //Now print what parts are compiled in.
    s << "Components: "
#ifdef BUILD_STATESERVER
    "State Server "
    #ifdef BUILD_STATESERVER_DBSS
        "(With DBSS capablities)"
    #endif //End DBSS
    ","
#endif //End SS

#ifdef BUILD_EVENTLOGGER
    "Event Logger,"
#endif

#ifdef BUILD_CLIENTAGENT
    "Client Agent,"
#endif

#ifdef BUILD_DBSERVER
    "Database "

    #ifdef BUILD_DB_YAML
        "(With YAML Support) "
    #endif //End DB_YAML

    #ifdef BUILD_DB_SQL
        "(With SQL DB Support) "
    #endif //End DB_SQL

#endif //End DBSERVER
    "\n";

}
<commit_msg>Add missing spaces in output.<commit_after>#include "global.h"
#include "RoleFactory.h"
#include "config/constraints.h"
#include "dclass/file/read.h"
#include "dclass/dc/Class.h"
using dclass::Class;

#include <boost/filesystem.hpp>
#include <cstring>
#include <string>  // std::string
#include <vector>  // std::vector
#include <fstream> // std::ifstream
using namespace std;

static LogCategory mainlog("main", "Main");

static ConfigGroup general_config("general");
static ConfigVariable<vector<string> > dc_files("dc_files", vector<string>(), general_config);
static ConfigVariable<string> eventlogger_addr("eventlogger", "", general_config);
static ValidAddressConstraint valid_eventlogger_addr(eventlogger_addr);

static ConfigList uberdogs_config("uberdogs");
static ConfigVariable<doid_t> uberdog_id("id", INVALID_DO_ID, uberdogs_config);
static ConfigVariable<string> uberdog_class("class", "", uberdogs_config);
static ConfigVariable<bool> uberdog_anon("anonymous", false, uberdogs_config);
static InvalidDoidConstraint id_not_invalid(uberdog_id);
static ReservedDoidConstraint id_not_reserved(uberdog_id);
static BooleanValueConstraint anonymous_is_boolean(uberdog_anon);

static void printHelp(ostream &s);
static void printCompiledOptions(ostream &s);

int main(int argc, char *argv[])
{
	string cfg_file;

	int config_arg_index = -1;
	cfg_file = "astrond.yml";
	LogSeverity sev = g_logger->get_min_severity();
	for(int i = 1; i < argc; i++)
	{
		if((strcmp(argv[i], "--log") == 0 || strcmp(argv[i], "-L") == 0) && i + 1 < argc)
		{
			delete g_logger;
			g_logger = new Logger(argv[++i], sev);
		}
		else if((strcmp(argv[i], "--loglevel") == 0 || strcmp(argv[i], "-l") == 0) && i + 1 < argc)
		{
			string llstr(argv[++i]);
			if(llstr == "packet")
			{
				sev = LSEVERITY_PACKET;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "trace")
			{
				sev = LSEVERITY_TRACE;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "debug")
			{
				sev = LSEVERITY_DEBUG;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "info")
			{
				sev = LSEVERITY_INFO;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "warning")
			{
				sev = LSEVERITY_INFO;
				g_logger->set_min_severity(sev);
			}
			else if(llstr == "security")
			{
				sev = LSEVERITY_SECURITY;
				g_logger->set_min_severity(sev);
			}
			else if(llstr != "error" && llstr != "fatal")
			{
				cerr << "Unknown log-level \"" << llstr << "\"." << endl;
				printHelp(cerr);
				exit(1);
			}
		}
		else if(strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
		{
			printHelp(cout);
			exit(0);
		}
        else if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0)
        {
             cout << "A Server Technology for Realtime Object Networking (Astron)\n"
                     "http://github.com/astron/astron\n"

#ifdef GIT_SHA1
            "Revision: " << GIT_SHA1 << "\n"
#else
            "Revision: NOT-IN-GIT\n"
#endif
            "Compiled at " << __TIME__ << " on " << __DATE__ << endl;

            printCompiledOptions(cout);

            exit(0);
        }
		else if(argv[i][0] == '-')
		{
			cerr << "Unrecognized option \"" << string(argv[i]) << "\".\n";
			printHelp(cerr);
			exit(1);
		}
		else
		{
			if(config_arg_index != -1)
			{
				cerr << "Recieved additional positional argument \""
				     << string(argv[i]) << "\" but can only accept one."
				     << "\n  First positional: \""
				     << string(argv[config_arg_index]) << "\".\n";
			}
			else
			{
				config_arg_index = i;
			}
		}
	}

	if(config_arg_index != -1)
	{
		string filename = "";
		cfg_file = argv[config_arg_index];

		try
		{
			// seperate path
			boost::filesystem::path p(cfg_file);
			boost::filesystem::path dir = p.parent_path();
			filename = p.filename().string();
			string dir_str = dir.string();

			// change directory
			if(!dir_str.empty())
			{
				boost::filesystem::current_path(dir_str);
			}
		}
		catch(const exception&)
		{
			mainlog.fatal() << "Could not change working directory to config directory.\n";
			exit(1);
		}

		cfg_file = filename;
	}

	mainlog.info() << "Loading configuration file...\n";

	ifstream file(cfg_file.c_str());
	if(!file.is_open())
	{
		mainlog.fatal() << "Failed to open configuration file \"" << cfg_file << "\".\n";
		return 1;
	}

	if(!g_config->load(file))
	{
		mainlog.fatal() << "Errors parsing YAML configuration file \"" << cfg_file << "\"!\n";
		return 1;
	}
	file.close();

	if(!ConfigGroup::root().validate(g_config->copy_node()))
	{
		mainlog.fatal() << "Configuration file contains errors.\n";
		return 1;
	}

	dclass::File* dcf = new dclass::File();
	dcf->add_keyword("required");
	dcf->add_keyword("ram");
	dcf->add_keyword("db");
	dcf->add_keyword("broadcast");
	dcf->add_keyword("clrecv");
	dcf->add_keyword("clsend");
	dcf->add_keyword("ownsend");
	dcf->add_keyword("ownrecv");
	dcf->add_keyword("airecv");
	vector<string> dc_file_names = dc_files.get_val();
	for(auto it = dc_file_names.begin(); it != dc_file_names.end(); ++it)
	{
		bool ok = dclass::append(dcf, *it);
		if(!ok)
		{
			mainlog.fatal() << "Could not read DC file " << *it << endl;
			return 1;
		}
	}
	g_dcf = dcf;

	// Initialize configured MessageDirector
	MessageDirector::singleton.init_network();
	g_eventsender.init(eventlogger_addr.get_val());

	// Load uberdog metadata from configuration
	ConfigNode udnodes = g_config->copy_node()["uberdogs"];
	if(!udnodes.IsNull())
	{
		for(auto it = udnodes.begin(); it != udnodes.end(); ++it)
		{
			ConfigNode udnode = *it;
			Uberdog ud;

			// Get the uberdog's class
			const Class* dcc = g_dcf->get_class_by_name(udnode["class"].as<std::string>());
			if(!dcc)
			{
				// Make sure it exists
				mainlog.fatal() << "For uberdog " << udnode["id"].as<doid_t>()
								<< " Distributed class " << udnode["class"].as<std::string>()
				                << " does not exist!" << std::endl;
				exit(1);
			}

			// Setup uberdog
			ud.dcc = dcc;
			ud.anonymous = udnode["anonymous"].as<bool>();
			g_uberdogs[udnode["id"].as<doid_t>()] = ud;
		}
	}

	// Initialize configured roles
	ConfigNode node = g_config->copy_node();
	node = node["roles"];
	for(auto it = node.begin(); it != node.end(); ++it)
	{
		RoleFactory::singleton().instantiate_role((*it)["type"].as<std::string>(), *it);
	}

	try
	{
		io_service.run();
	}
	catch(exception &e)
	{
		mainlog.fatal() << "Exception from the network io service: "
		                << e.what() << endl;
	}

	return 0;
}

// printHelp outputs the cli help-text to the given stream.
void printHelp(ostream &s)
{
	s << "Usage:    astrond [options]... [CONFIG_FILE]\n"
	     "\n"
	     "Astrond is a distributed server daemon.\n"
	     "By default Astron looks for a configuration file in the current\n"
	     "working directory as \"astrond.yml\".  A different config file path\n"
	     "can be specified as a positional argument.\n"
	     "\n"
	     "-h, --help      Print this help dialog.\n"
         "-v, --version   Print Version, Module and Compilation Information\n"
	     "-L, --log       Specify a file to write log messages to.\n"
	     "-l, --loglevel  Specify the minimum log level that should be logged;\n"
	     "                  Security, Error, and Fatal will always be logged;\n"
#ifdef ASTRON_DEBUG_MESSAGES
	     "                (available): packet, trace, debug, info, warning, security\n"
#else
	     "                (available): info, warning, security\n"
	     "                (unavailable): packet, trace, debug\n"
	     "                        [build with -DCMAKE_BUILD_TYPE=Debug]\n"
#endif
         "\n"
         "Example:\n"
         "    astrond /tmp/my_config_file.yaml\n"
         "\n";
	s.flush();
}

void printCompiledOptions(ostream &s)
{
    s << "Compilation options: "

//If on, datagrams and dclass fields will use 32-bit length tags instead of 16-bit.
#ifdef ASTRON_32BIT_DATAGRAMS
    "32-bit length tag Datagrams, "
#else
    "16-bit length tag Datagrams, "
#endif

//If on, channels will be 128-bit and doids and zones will be 64-bit (instead of 64/32).
#ifdef ASTRON_128BIT_CHANNELS
    "128-bit channel space, 64-bit distributed object id's, 64-bit zones"
#else
    "64-bit channel space, 32-bit distributed object id's, 32-bit zones"
#endif
    <<"\n";

    //Now print what parts are compiled in.
    s << "Components: "
#ifdef BUILD_STATESERVER
    "State Server "
    #ifdef BUILD_STATESERVER_DBSS
        "(With DBSS capablities)"
    #endif //End DBSS
    ", "
#endif //End SS

#ifdef BUILD_EVENTLOGGER
    "Event Logger, "
#endif

#ifdef BUILD_CLIENTAGENT
    "Client Agent, "
#endif

#ifdef BUILD_DBSERVER
    "Database "

    #ifdef BUILD_DB_YAML
        "(With YAML Support) "
    #endif //End DB_YAML

    #ifdef BUILD_DB_SQL
        "(With SQL DB Support) "
    #endif //End DB_SQL

#endif //End DBSERVER
    "\n";

}
<|endoftext|>


<commit_before>
#include <vector>
#include "core_io.h"
#include "core.h"
#include "serialize.h"
#include "script.h"

#include <boost/assign/list_of.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/replace.hpp>

using namespace std;
using namespace boost;
using namespace boost::algorithm;

CScript ParseScript(std::string s)
{
    CScript result;

    static map<string, opcodetype> mapOpNames;

    if (mapOpNames.size() == 0)
    {
        for (int op = 0; op <= OP_NOP10; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            const char* name = GetOpName((opcodetype)op);
            if (strcmp(name, "OP_UNKNOWN") == 0)
                continue;
            string strName(name);
            mapOpNames[strName] = (opcodetype)op;
            // Convenience: OP_ADD and just ADD are both recognized:
            replace_first(strName, "OP_", "");
            mapOpNames[strName] = (opcodetype)op;
        }
    }

    vector<string> words;
    split(words, s, is_any_of(" \t\n"), token_compress_on);

    BOOST_FOREACH(string w, words)
    {
        if (w.size() == 0)
        {
            // Empty string, ignore. (boost::split given '' will return one word)
        }
        else if (all(w, is_digit()) ||
            (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit())))
        {
            // Number
            int64_t n = atoi64(w);
            result << n;
        }
        else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'"))
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w.begin()+1, w.end()-1);
            result << value;
        }
        else if (mapOpNames.count(w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[w];
        }
        else
        {
            throw runtime_error("script parse error");
        }
    }

    return result;
}

bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
{
    if (!IsHex(strHexTx))
        return false;

    vector<unsigned char> txData(ParseHex(strHexTx));
    CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssData >> tx;
    }
    catch (std::exception &e) {
        return false;
    }

    return true;
}

<commit_msg>core_read's ParseScript(): minor cleanups<commit_after>
#include <vector>
#include "core_io.h"
#include "core.h"
#include "serialize.h"
#include "script.h"

#include <boost/assign/list_of.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/replace.hpp>

using namespace std;
using namespace boost;
using namespace boost::algorithm;

CScript ParseScript(std::string s)
{
    CScript result;

    static map<string, opcodetype> mapOpNames;

    if (mapOpNames.empty())
    {
        for (int op = 0; op <= OP_NOP10; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            const char* name = GetOpName((opcodetype)op);
            if (strcmp(name, "OP_UNKNOWN") == 0)
                continue;
            string strName(name);
            mapOpNames[strName] = (opcodetype)op;
            // Convenience: OP_ADD and just ADD are both recognized:
            replace_first(strName, "OP_", "");
            mapOpNames[strName] = (opcodetype)op;
        }
    }

    vector<string> words;
    split(words, s, is_any_of(" \t\n"), token_compress_on);

    for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
    {
        if (w->empty())
        {
            // Empty string, ignore. (boost::split given '' will return one word)
        }
        else if (all(*w, is_digit()) ||
            (starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
        {
            // Number
            int64_t n = atoi64(*w);
            result << n;
        }
        else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w->begin()+1, w->end()-1);
            result << value;
        }
        else if (mapOpNames.count(*w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[*w];
        }
        else
        {
            throw runtime_error("script parse error");
        }
    }

    return result;
}

bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
{
    if (!IsHex(strHexTx))
        return false;

    vector<unsigned char> txData(ParseHex(strHexTx));
    CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssData >> tx;
    }
    catch (std::exception &e) {
        return false;
    }

    return true;
}

<|endoftext|>


<commit_before>
#include <vector>
#include "core_io.h"
#include "core.h"
#include "serialize.h"
#include "script.h"
#include "util.h"

#include <boost/assign/list_of.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/replace.hpp>
#include "univalue/univalue.h"

using namespace std;
using namespace boost;
using namespace boost::algorithm;

CScript ParseScript(std::string s)
{
    CScript result;

    static map<string, opcodetype> mapOpNames;

    if (mapOpNames.size() == 0)
    {
        for (int op = 0; op <= OP_NOP10; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            const char* name = GetOpName((opcodetype)op);
            if (strcmp(name, "OP_UNKNOWN") == 0)
                continue;
            string strName(name);
            mapOpNames[strName] = (opcodetype)op;
            // Convenience: OP_ADD and just ADD are both recognized:
            replace_first(strName, "OP_", "");
            mapOpNames[strName] = (opcodetype)op;
        }
    }

    vector<string> words;
    split(words, s, is_any_of(" \t\n"), token_compress_on);

    BOOST_FOREACH(string w, words)
    {
        if (w.size() == 0)
        {
            // Empty string, ignore. (boost::split given '' will return one word)
        }
        else if (all(w, is_digit()) ||
            (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit())))
        {
            // Number
            int64_t n = atoi64(w);
            result << n;
        }
        else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'"))
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w.begin()+1, w.end()-1);
            result << value;
        }
        else if (mapOpNames.count(w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[w];
        }
        else
        {
            throw runtime_error("script parse error");
        }
    }

    return result;
}

bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
{
    if (!IsHex(strHexTx))
        return false;

    vector<unsigned char> txData(ParseHex(strHexTx));
    CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssData >> tx;
    }
    catch (std::exception &e) {
        return false;
    }

    return true;
}

uint256 ParseHashUV(const UniValue& v, const string& strName)
{
    string strHex;
    if (v.isStr())
        strHex = v.getValStr();
    if (!IsHex(strHex)) // Note: IsHex("") is false
        throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");

    uint256 result;
    result.SetHex(strHex);
    return result;
}

vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName)
{
    string strHex;
    if (v.isStr())
        strHex = v.getValStr();
    if (!IsHex(strHex))
        throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
    return ParseHex(strHex);
}

<commit_msg>core_read's ParseScript(): minor cleanups<commit_after>
#include <vector>
#include "core_io.h"
#include "core.h"
#include "serialize.h"
#include "script.h"
#include "util.h"

#include <boost/assign/list_of.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/replace.hpp>
#include "univalue/univalue.h"

using namespace std;
using namespace boost;
using namespace boost::algorithm;

CScript ParseScript(std::string s)
{
    CScript result;

    static map<string, opcodetype> mapOpNames;

    if (mapOpNames.empty())
    {
        for (int op = 0; op <= OP_NOP10; op++)
        {
            // Allow OP_RESERVED to get into mapOpNames
            if (op < OP_NOP && op != OP_RESERVED)
                continue;

            const char* name = GetOpName((opcodetype)op);
            if (strcmp(name, "OP_UNKNOWN") == 0)
                continue;
            string strName(name);
            mapOpNames[strName] = (opcodetype)op;
            // Convenience: OP_ADD and just ADD are both recognized:
            replace_first(strName, "OP_", "");
            mapOpNames[strName] = (opcodetype)op;
        }
    }

    vector<string> words;
    split(words, s, is_any_of(" \t\n"), token_compress_on);

    for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
    {
        if (w->empty())
        {
            // Empty string, ignore. (boost::split given '' will return one word)
        }
        else if (all(*w, is_digit()) ||
            (starts_with(*w, "-") && all(string(w->begin()+1, w->end()), is_digit())))
        {
            // Number
            int64_t n = atoi64(*w);
            result << n;
        }
        else if (starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
        {
            // Raw hex data, inserted NOT pushed onto stack:
            std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
            result.insert(result.end(), raw.begin(), raw.end());
        }
        else if (w->size() >= 2 && starts_with(*w, "'") && ends_with(*w, "'"))
        {
            // Single-quoted string, pushed as data. NOTE: this is poor-man's
            // parsing, spaces/tabs/newlines in single-quoted strings won't work.
            std::vector<unsigned char> value(w->begin()+1, w->end()-1);
            result << value;
        }
        else if (mapOpNames.count(*w))
        {
            // opcode, e.g. OP_ADD or ADD:
            result << mapOpNames[*w];
        }
        else
        {
            throw runtime_error("script parse error");
        }
    }

    return result;
}

bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
{
    if (!IsHex(strHexTx))
        return false;

    vector<unsigned char> txData(ParseHex(strHexTx));
    CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
    try {
        ssData >> tx;
    }
    catch (std::exception &e) {
        return false;
    }

    return true;
}

uint256 ParseHashUV(const UniValue& v, const string& strName)
{
    string strHex;
    if (v.isStr())
        strHex = v.getValStr();
    if (!IsHex(strHex)) // Note: IsHex("") is false
        throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");

    uint256 result;
    result.SetHex(strHex);
    return result;
}

vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName)
{
    string strHex;
    if (v.isStr())
        strHex = v.getValStr();
    if (!IsHex(strHex))
        throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
    return ParseHex(strHex);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#include "precompiled_toolkit.hxx"

#include <toolkit/awt/vclxtabpagecontainer.hxx>
#include <com/sun/star/awt/tab/XTabPageModel.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <vcl/tabpage.hxx>
#include <vcl/tabctrl.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/tkresmgr.hxx>
#include <cppuhelper/typeprovider.hxx>

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::view;
//  ----------------------------------------------------
//  class VCLXTabPageContainer
//  ----------------------------------------------------
void VCLXTabPageContainer::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXTabPageContainer::VCLXTabPageContainer() :
    m_aTabPageListeners( *this )
{
}

VCLXTabPageContainer::~VCLXTabPageContainer()
{
#ifndef __SUNPRO_CC
    OSL_TRACE ("%s", __FUNCTION__);
#endif
}

void SAL_CALL VCLXTabPageContainer::draw( sal_Int32 nX, sal_Int32 nY ) throw(RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    TabControl* pTabControl = (TabControl*)GetWindow();
    if ( pTabControl )
    {
        TabPage *pTabPage = pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >(  pTabControl->GetCurPageId( ) ) );
        if ( pTabPage )
        {
            ::Point aPos( nX, nY );
            ::Size  aSize = pTabPage->GetSizePixel();

            OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
            aPos  = pDev->PixelToLogic( aPos );
            aSize = pDev->PixelToLogic( aSize );

            pTabPage->Draw( pDev, aPos, aSize, 0 );
        }
    }

    VCLXWindow::draw( nX, nY );
/*
    if ( pWindow )
    {
        OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
        if ( !pDev )
            pDev = pWindow->GetParent();

        Size aSize = pDev->PixelToLogic( pWindow->GetSizePixel() );
        Point aPos = pDev->PixelToLogic( Point( nX, nY ) );

        pWindow->Draw( pDev, aPos, aSize, WINDOW_DRAW_NOCONTROLS );
    }
*/
}

::com::sun::star::awt::DeviceInfo VCLXTabPageContainer::getInfo() throw(RuntimeException)
{
    ::com::sun::star::awt::DeviceInfo aInfo = VCLXDevice::getInfo();
    return aInfo;
}

void SAL_CALL VCLXTabPageContainer::setProperty(const ::rtl::OUString& PropertyName,   const Any& Value ) throw(RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    TabControl* pTabPage = (TabControl*)GetWindow();
    if ( pTabPage )
    {
        VCLXWindow::setProperty( PropertyName, Value );
    }
}
::sal_Int16 SAL_CALL VCLXTabPageContainer::getActiveTabPageID() throw (RuntimeException)
{
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    return pTabCtrl != NULL ? pTabCtrl->GetCurPageId( ) : 0;
}
void SAL_CALL VCLXTabPageContainer::setActiveTabPageID( ::sal_Int16 _activetabpageid ) throw (RuntimeException)
{
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    if ( pTabCtrl )
        pTabCtrl->SelectTabPage(_activetabpageid);
}
::sal_Int32 SAL_CALL VCLXTabPageContainer::getTabPageCount(  ) throw (RuntimeException)
{
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    return pTabCtrl != NULL ? pTabCtrl->GetPageCount() : 0;
}
::sal_Bool SAL_CALL VCLXTabPageContainer::isTabPageActive( ::sal_Int16 tabPageIndex ) throw (RuntimeException)
{
    return (getActiveTabPageID() == tabPageIndex);
}
Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer::getTabPage( ::sal_Int16 tabPageIndex ) throw (RuntimeException)
{
    return (tabPageIndex >= 0 && tabPageIndex < static_cast<sal_Int16>(m_aTabPages.size())) ? m_aTabPages[tabPageIndex] : NULL;
}
Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer::getTabPageByID( ::sal_Int16 tabPageID ) throw (RuntimeException)
{
    ::vos::OClearableGuard aGuard( GetMutex() );
    Reference< ::com::sun::star::awt::tab::XTabPage > xTabPage;
    ::std::vector< Reference< ::com::sun::star::awt::tab::XTabPage > >::iterator aIter = m_aTabPages.begin();
    ::std::vector< Reference< ::com::sun::star::awt::tab::XTabPage > >::iterator aEnd = m_aTabPages.end();
    for(;aIter != aEnd;++aIter)
    {
        Reference< awt::XControl > xControl(*aIter,UNO_QUERY );
        Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY );
        if ( tabPageID == xP->getTabPageID() )
        {
            xTabPage = *aIter;
            break;
        }
    }
    return xTabPage;
}
void SAL_CALL VCLXTabPageContainer::addTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
    m_aTabPageListeners.addInterface( listener );
}
void SAL_CALL VCLXTabPageContainer::removeTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
    m_aTabPageListeners.removeInterface( listener );
}

void VCLXTabPageContainer::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
{
    ::vos::OClearableGuard aGuard( GetMutex() );
    TabControl* pTabControl = static_cast< TabControl* >( GetWindow() );
    if ( pTabControl )
    {
        switch ( _rVclWindowEvent.GetId() )
        {
            case VCLEVENT_TABPAGE_ACTIVATE:
            {
//                allocateArea( maAllocation );
                sal_Int32 page = (sal_Int32) _rVclWindowEvent.GetData();
                awt::tab::TabPageActivatedEvent aEvent(NULL,page);
                m_aTabPageListeners.tabPageActivated(aEvent);
                break;
            }
            default:
                aGuard.clear();
                VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
                break;
        }
    }
}
void SAL_CALL VCLXTabPageContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
{
}
void SAL_CALL VCLXTabPageContainer::elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    Reference< ::com::sun::star::awt::tab::XTabPage > xTabPage(Event.Element,uno::UNO_QUERY);
    if ( pTabCtrl && xTabPage.is() )
    {
        Reference< awt::XControl > xControl(xTabPage,UNO_QUERY );
        Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY );
        sal_Int16 nPageID = xP->getTabPageID();

        Window* pWindow = VCLUnoHelper::GetWindow(xControl->getPeer());
        TabPage* pPage = (TabPage*)pWindow;
        pTabCtrl->InsertPage(nPageID,pPage->GetText());

        pPage->Hide();
        pTabCtrl->SetTabPage(nPageID,pPage);
        pTabCtrl->SetHelpText(nPageID,xP->getTooltip());
        pTabCtrl->SetPageImage(nPageID,TkResMgr::getImageFromURL(xP->getImageURL()));
        pTabCtrl->SelectTabPage(nPageID);
        m_aTabPages.push_back(xTabPage);
    }
}
void SAL_CALL VCLXTabPageContainer::elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    Reference< ::com::sun::star::awt::tab::XTabPage > xTabPage(Event.Element,uno::UNO_QUERY);
    if ( pTabCtrl && xTabPage.is() )
    {
        Reference< awt::XControl > xControl(xTabPage,UNO_QUERY );
        Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY );
        pTabCtrl->RemovePage(xP->getTabPageID());
        m_aTabPages.erase(::std::remove(m_aTabPages.begin(),m_aTabPages.end(),xTabPage));
    }
}
void SAL_CALL VCLXTabPageContainer::elementReplaced( const ::com::sun::star::container::ContainerEvent& /*Event*/ ) throw (::com::sun::star::uno::RuntimeException)
{
}
<commit_msg>tabcontrol: compile fix<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#include "precompiled_toolkit.hxx"

#include <toolkit/awt/vclxtabpagecontainer.hxx>
#include <com/sun/star/awt/tab/XTabPageModel.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <vcl/tabpage.hxx>
#include <vcl/tabctrl.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/tkresmgr.hxx>
#include <cppuhelper/typeprovider.hxx>

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::view;
//  ----------------------------------------------------
//  class VCLXTabPageContainer
//  ----------------------------------------------------
void VCLXTabPageContainer::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
{
    VCLXWindow::ImplGetPropertyIds( rIds );
}

VCLXTabPageContainer::VCLXTabPageContainer() :
    m_aTabPageListeners( *this )
{
}

VCLXTabPageContainer::~VCLXTabPageContainer()
{
#ifndef __SUNPRO_CC
    OSL_TRACE ("%s", __FUNCTION__);
#endif
}

void SAL_CALL VCLXTabPageContainer::draw( sal_Int32 nX, sal_Int32 nY ) throw(RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    TabControl* pTabControl = (TabControl*)GetWindow();
    if ( pTabControl )
    {
        TabPage *pTabPage = pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >(  pTabControl->GetCurPageId( ) ) );
        if ( pTabPage )
        {
            ::Point aPos( nX, nY );
            ::Size  aSize = pTabPage->GetSizePixel();

            OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
            aPos  = pDev->PixelToLogic( aPos );
            aSize = pDev->PixelToLogic( aSize );

            pTabPage->Draw( pDev, aPos, aSize, 0 );
        }
    }

    VCLXWindow::draw( nX, nY );
/*
    if ( pWindow )
    {
        OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
        if ( !pDev )
            pDev = pWindow->GetParent();

        Size aSize = pDev->PixelToLogic( pWindow->GetSizePixel() );
        Point aPos = pDev->PixelToLogic( Point( nX, nY ) );

        pWindow->Draw( pDev, aPos, aSize, WINDOW_DRAW_NOCONTROLS );
    }
*/
}

::com::sun::star::awt::DeviceInfo VCLXTabPageContainer::getInfo() throw(RuntimeException)
{
    ::com::sun::star::awt::DeviceInfo aInfo = VCLXDevice::getInfo();
    return aInfo;
}

void SAL_CALL VCLXTabPageContainer::setProperty(const ::rtl::OUString& PropertyName,   const Any& Value ) throw(RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    TabControl* pTabPage = (TabControl*)GetWindow();
    if ( pTabPage )
    {
        VCLXWindow::setProperty( PropertyName, Value );
    }
}
::sal_Int16 SAL_CALL VCLXTabPageContainer::getActiveTabPageID() throw (RuntimeException)
{
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    return pTabCtrl != NULL ? pTabCtrl->GetCurPageId( ) : 0;
}
void SAL_CALL VCLXTabPageContainer::setActiveTabPageID( ::sal_Int16 _activetabpageid ) throw (RuntimeException)
{
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    if ( pTabCtrl )
        pTabCtrl->SelectTabPage(_activetabpageid);
}
::sal_Int32 SAL_CALL VCLXTabPageContainer::getTabPageCount(  ) throw (RuntimeException)
{
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    return pTabCtrl != NULL ? pTabCtrl->GetPageCount() : 0;
}
::sal_Bool SAL_CALL VCLXTabPageContainer::isTabPageActive( ::sal_Int16 tabPageIndex ) throw (RuntimeException)
{
    return (getActiveTabPageID() == tabPageIndex);
}
Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer::getTabPage( ::sal_Int16 tabPageIndex ) throw (RuntimeException)
{
    return (tabPageIndex >= 0 && tabPageIndex < static_cast<sal_Int16>(m_aTabPages.size())) ? m_aTabPages[tabPageIndex] : NULL;
}
Reference< ::com::sun::star::awt::tab::XTabPage > SAL_CALL VCLXTabPageContainer::getTabPageByID( ::sal_Int16 tabPageID ) throw (RuntimeException)
{
    ::vos::OClearableGuard aGuard( GetMutex() );
    Reference< ::com::sun::star::awt::tab::XTabPage > xTabPage;
    ::std::vector< Reference< ::com::sun::star::awt::tab::XTabPage > >::iterator aIter = m_aTabPages.begin();
    ::std::vector< Reference< ::com::sun::star::awt::tab::XTabPage > >::iterator aEnd = m_aTabPages.end();
    for(;aIter != aEnd;++aIter)
    {
        Reference< awt::XControl > xControl(*aIter,UNO_QUERY );
        Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY );
        if ( tabPageID == xP->getTabPageID() )
        {
            xTabPage = *aIter;
            break;
        }
    }
    return xTabPage;
}
void SAL_CALL VCLXTabPageContainer::addTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
    m_aTabPageListeners.addInterface( listener );
}
void SAL_CALL VCLXTabPageContainer::removeTabPageListener( const Reference< ::com::sun::star::awt::tab::XTabPageContainerListener >& listener ) throw (RuntimeException)
{
    m_aTabPageListeners.removeInterface( listener );
}

void VCLXTabPageContainer::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
{
    ::vos::OClearableGuard aGuard( GetMutex() );
    TabControl* pTabControl = static_cast< TabControl* >( GetWindow() );
    if ( pTabControl )
    {
        switch ( _rVclWindowEvent.GetId() )
        {
            case VCLEVENT_TABPAGE_ACTIVATE:
            {
//                allocateArea( maAllocation );
                ULONG page = (ULONG)_rVclWindowEvent.GetData();
                awt::tab::TabPageActivatedEvent aEvent(NULL,page);
                m_aTabPageListeners.tabPageActivated(aEvent);
                break;
            }
            default:
                aGuard.clear();
                VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
                break;
        }
    }
}
void SAL_CALL VCLXTabPageContainer::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
{
}
void SAL_CALL VCLXTabPageContainer::elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    Reference< ::com::sun::star::awt::tab::XTabPage > xTabPage(Event.Element,uno::UNO_QUERY);
    if ( pTabCtrl && xTabPage.is() )
    {
        Reference< awt::XControl > xControl(xTabPage,UNO_QUERY );
        Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY );
        sal_Int16 nPageID = xP->getTabPageID();

        Window* pWindow = VCLUnoHelper::GetWindow(xControl->getPeer());
        TabPage* pPage = (TabPage*)pWindow;
        pTabCtrl->InsertPage(nPageID,pPage->GetText());

        pPage->Hide();
        pTabCtrl->SetTabPage(nPageID,pPage);
        pTabCtrl->SetHelpText(nPageID,xP->getTooltip());
        pTabCtrl->SetPageImage(nPageID,TkResMgr::getImageFromURL(xP->getImageURL()));
        pTabCtrl->SelectTabPage(nPageID);
        m_aTabPages.push_back(xTabPage);
    }
}
void SAL_CALL VCLXTabPageContainer::elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );
    TabControl* pTabCtrl = (TabControl*)GetWindow();
    Reference< ::com::sun::star::awt::tab::XTabPage > xTabPage(Event.Element,uno::UNO_QUERY);
    if ( pTabCtrl && xTabPage.is() )
    {
        Reference< awt::XControl > xControl(xTabPage,UNO_QUERY );
        Reference< awt::tab::XTabPageModel > xP( xControl->getModel(), UNO_QUERY );
        pTabCtrl->RemovePage(xP->getTabPageID());
        m_aTabPages.erase(::std::remove(m_aTabPages.begin(),m_aTabPages.end(),xTabPage));
    }
}
void SAL_CALL VCLXTabPageContainer::elementReplaced( const ::com::sun::star::container::ContainerEvent& /*Event*/ ) throw (::com::sun::star::uno::RuntimeException)
{
}
<|endoftext|>