<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it 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.
**
****************************************************************************/

#include <QCoreApplication>
#include <QTextCodec>
#include <MLocale>
#include <unicode/uversion.h>

#include "pt_mcalendar.h"

void Pt_MCalendar::initTestCase()
{
    static int argc = 0;
    static char *argv[1] = { (char *) "" };
    qap = new QCoreApplication(argc, argv);
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QProcess process;
    process.start("sh -c \"dpkg -s libicu44 | grep Version | perl -pe 's/^Version:[[:space:]]*([^[[:space:]]+)$/$1/g'\"");
    if (!process.waitForFinished()) {
        qDebug() << "cannot run process to check libicu44 package version , exiting ...";
        exit(1);
    }
    icuPackageVersion = process.readAllStandardOutput();
    icuPackageVersion.replace("\n", "");
    qDebug() << "libicu44 package version is:" << icuPackageVersion;
}

void Pt_MCalendar::cleanupTestCase()
{
    delete qap;
}

void Pt_MCalendar::init()
{
}

void Pt_MCalendar::cleanup()
{
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_U_QDateTime()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%U");
    QString result("٢٩");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(datetime, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_U_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%U");
    QString result("٢٩");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_V_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%V");
    QString result("٣٠");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_r_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%r");
    QString result("٢:٣١ م");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_R_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%R");
    QString result("١٤:٣١");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_t_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%t");
    QString result("\t");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkIcuFormatString()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("fi_FI");     // this overrides language
    QString lcNumeric("en_US");  // should not matter, no localized numbers involved
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::IslamicCalendar); // should not matter
    QCOMPARE(locale.icuFormatString(
                 MLocale::DateFull,
                 MLocale::TimeFull,
                 MLocale::GregorianCalendar),
             QString("cccc d. MMMM y H:mm:ss zzzz"));

    QBENCHMARK {
        locale.icuFormatString(
                 MLocale::DateFull,
                 MLocale::TimeFull,
                 MLocale::GregorianCalendar);
    }
}

void Pt_MCalendar::benchmarkFormatDateTime()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("fi_FI");     // this overrides language
    QString lcNumeric("en_US");  // should not matter, no localized numbers involved
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    MCalendar calendar;
    calendar.setDateTime(QDateTime(QDate(2010, 7, 13),
                                   QTime(14, 51, 07, 0),
                                   Qt::LocalTime));

    QCOMPARE(locale.formatDateTime(
                 calendar, MLocale::DateFull, MLocale::TimeFull),
             QString("tiistai 13. heinäkuuta 2010 14:51:07 Itä-Euroopan kesäaika"));

    QBENCHMARK {
        locale.formatDateTime(
            calendar, MLocale::DateFull, MLocale::TimeFull);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimeICU()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("fi_FI");     // this overrides language
    QString lcNumeric("en_US");  // should not matter
    QString formatString("cccc d. MMMM y H:mm:ss zzzz");
    QString formattedResult("tiistai 13. heinäkuuta 2010 14:51:07 Itä-Euroopan kesäaika");
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    MCalendar calendar;
    calendar.setDateTime(QDateTime(QDate(2010, 7, 13),
                                   QTime(14, 51, 07, 0),
                                   Qt::LocalTime));

    QCOMPARE(locale.formatDateTimeICU(calendar, formatString), formattedResult);

    QBENCHMARK {
        locale.formatDateTimeICU(calendar, formatString);
    }
}

QTEST_APPLESS_MAIN(Pt_MCalendar);

<commit_msg>Changes: fix Pt_MCalendar<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it 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.
**
****************************************************************************/

#include <QCoreApplication>
#include <QTextCodec>
#include <MLocale>
#include <unicode/uversion.h>

#include "pt_mcalendar.h"

void Pt_MCalendar::initTestCase()
{
    static int argc = 0;
    static char *argv[1] = { (char *) "" };
    qap = new QCoreApplication(argc, argv);
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QProcess process;
    process.start("sh -c \"dpkg -s libicu44 | grep Version | perl -pe 's/^Version:[[:space:]]*([^[[:space:]]+)$/$1/g'\"");
    if (!process.waitForFinished()) {
        qDebug() << "cannot run process to check libicu44 package version , exiting ...";
        exit(1);
    }
    icuPackageVersion = process.readAllStandardOutput();
    icuPackageVersion.replace("\n", "");
    qDebug() << "libicu44 package version is:" << icuPackageVersion;
}

void Pt_MCalendar::cleanupTestCase()
{
    delete qap;
}

void Pt_MCalendar::init()
{
}

void Pt_MCalendar::cleanup()
{
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_U_QDateTime()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%U");
    QString result("٢٩");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(datetime, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_U_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%U");
    QString result("٢٩");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_V_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%V");
    QString result("٣٠");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_r_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA@mix-time-and-language=no");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%r");
    QString result("٢:٣١ م");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_R_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%R");
    QString result("١٤:٣١");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimePosixFormatString_t_MCalendar()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("ar_SA");     // this overrides language
    QString lcNumeric("ar_SA");  // does matter, overrides localized numbers in dates
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::GregorianCalendar);
    MCalendar mcal(locale);
    int year = 2008;
    int month = 7;
    int day = 21;
    int hour = 14;
    int minute = 31;
    int second = 3;
    mcal.setDate(year, month, day);
    mcal.setTime(hour, minute, second);
    QDate date(year, month, day);
    QTime time(hour, minute, second);
    QDateTime datetime(date, time, Qt::LocalTime);
    QLocale qlocale(language);
    QString format("%t");
    QString result("\t");
    QCOMPARE(locale.formatDateTime(mcal, format), result);
    QCOMPARE(locale.formatDateTime(datetime, format), result);

    QBENCHMARK {
        locale.formatDateTime(mcal, format);
    }
}

void Pt_MCalendar::benchmarkIcuFormatString()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("fi_FI");     // this overrides language
    QString lcNumeric("en_US");  // should not matter, no localized numbers involved
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    locale.setCalendarType(MLocale::IslamicCalendar); // should not matter
    QCOMPARE(locale.icuFormatString(
                 MLocale::DateFull,
                 MLocale::TimeFull,
                 MLocale::GregorianCalendar),
             QString("cccc d. MMMM y H:mm:ss zzzz"));

    QBENCHMARK {
        locale.icuFormatString(
                 MLocale::DateFull,
                 MLocale::TimeFull,
                 MLocale::GregorianCalendar);
    }
}

void Pt_MCalendar::benchmarkFormatDateTime()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("fi_FI@mix-time-and-language=no");     // this overrides language
    QString lcNumeric("en_US");  // should not matter, no localized numbers involved
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    MCalendar calendar;
    calendar.setDateTime(QDateTime(QDate(2010, 7, 13),
                                   QTime(14, 51, 07, 0),
                                   Qt::LocalTime));

    QCOMPARE(locale.formatDateTime(
                 calendar, MLocale::DateFull, MLocale::TimeFull),
             QString("tiistai 13. heinäkuuta 2010 14:51:07 Itä-Euroopan kesäaika"));

    QBENCHMARK {
        locale.formatDateTime(
            calendar, MLocale::DateFull, MLocale::TimeFull);
    }
}

void Pt_MCalendar::benchmarkFormatDateTimeICU()
{
    QString language("en_US");   // will be overridden
    QString lcMessages("en_US"); // should not matter
    QString lcTime("fi_FI@mix-time-and-language=no"); // this overrides language
    QString lcNumeric("en_US");  // should not matter
    QString formatString("cccc d. MMMM y H:mm:ss zzzz");
    QString formattedResult("tiistai 13. heinäkuuta 2010 14:51:07 Itä-Euroopan kesäaika");
    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    MCalendar calendar;
    calendar.setDateTime(QDateTime(QDate(2010, 7, 13),
                                   QTime(14, 51, 07, 0),
                                   Qt::LocalTime));

    QCOMPARE(locale.formatDateTimeICU(calendar, formatString), formattedResult);

    QBENCHMARK {
        locale.formatDateTimeICU(calendar, formatString);
    }
}

QTEST_APPLESS_MAIN(Pt_MCalendar);

<|endoftext|>


<commit_before>#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <chrono>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <unistd.h>

#include "entity.h"
#include "character.h"
#include "monster.h"
#include "spell.h"
#include "item.h"
#include "tile.h"
#include "timetable.h"
#include "mailbox.h"
#include "map.h"

using namespace std;

const int StartingX = 8;
const int StartingY = 8;

//Structure for HTTP form data
struct FormInfo{
	string Key;
	string Value;
};

vector<Enemy> SpawnedEnemies; // []
vector<Character> Players;

//Vector to hold Key / Value pairs after processing
vector<FormInfo> FormData;

void getFormData(string Env);
string GetValueFromKey(string FindKey);
int GetPlayerByBox(string BoxNumber);
string GetNewCharInfo(Character& Character);

int main(){
	//Setup Game state
	TimeTable TimeTable;
	Mailbox Mailbox;
	Map Map;
	bool Done = false;
	string Message;
	string Action;
	string Temp;
	int User;
	string Box;

	//Load maps
	Map.LoadMap("map.csv");

	//Load definitions
	cout << "Beginning main loop\n" << flush;
	cout << "Mailbox: " << Mailbox.SetupSuccessful() << "\n" << flush;
	//Main Loop
	while (!Done){
		FormData.clear();
		Action = "";

		//Check Time table.  Perform function for all expired times

		//Check and Process Messages
		Message = Mailbox.GetNextMessage();
		getFormData(Message);
		Action = GetValueFromKey("Action");
		Box = GetValueFromKey("Box");
		if (Box.length() > 0) User = GetPlayerByBox(Box);

		if (Action == "EnterGame"){
			Character NewChar(GetValueFromKey("u"), GetValueFromKey("c"), stoi(GetValueFromKey("b")));
			Mailbox.OpenUserBox(NewChar.Box);
			NewChar.X = StartingX;
			NewChar.Y = StartingY;
// 			Temp = "&Op=MyPosition&X=" + to_string(StartingX) + "&Y=" + to_string(StartingY);
// 			Mailbox.SendMessageToBox(Temp, NewChar.Box);
			Mailbox.SendMessageToBox("&Op=Con&Message=" + NewChar.Name + " has entered the game.", NewChar.Box);
			Temp = GetNewCharInfo(NewChar);
			Mailbox.BroadcastMessage(GetNewCharInfo(NewChar));
			Mailbox.SendMessageToBox(GetNewCharInfo(NewChar), NewChar.Box);
			for (int i = 0; i < Players.size(); i++){
				Mailbox.SendMessageToBox(GetNewCharInfo(Players[i]), NewChar.Box);
			}
			Players.push_back(NewChar);
		}

		if (Action == "RepeatMessage"){
			//This convoluted mess tests the message passing among objects (It's obv super redundant.)
			string TestString = "&Op=Alert&Message=" + GetValueFromKey("Message") + " Repeated back at ya.";
			int TestBox = Players[GetPlayerByBox(GetValueFromKey("b"))].Box;
			cout << "Test:" << TestString << "\n";
			Mailbox.SendMessageToBox(TestString , TestBox );

		}

		if (Action == "LeaveGame"){
			//Done = true;
			Mailbox.CloseUserBox(stoi(GetValueFromKey("b")));
		}

		if (Action == "GetPlot"){
			int X = stoi(GetValueFromKey("X"));
			int Y = stoi(GetValueFromKey("Y"));
			Temp = "&Op=MapPlot&X=" + GetValueFromKey("X") + "&Y=" + GetValueFromKey("Y") + "&Plot=" + Map.GetPlot(X,Y);
			Mailbox.SendMessageToBox(Temp, Players[User].Box);
		}

		if (Action == "Move"){
			int Who = GetPlayerByBox(GetValueFromKey("b"));
			int X = stoi(GetValueFromKey("XMove"));
			int Y = stoi(GetValueFromKey("YMove"));
			cout << "Move";
			//if (Map.Passable(Players[Who].X + X, Players[Who].Y + Y)){
				string Temp = "&Op=PlayerMove&b=" + GetValueFromKey("b") + "&X=" + GetValueFromKey("XMove") + "&Y=" + GetValueFromKey("YMove");
				Mailbox.BroadcastMessage(Temp);
				//Mailbox.SendMessageToBox(Temp, Players[Who].Box);
			//}
		}

		if (Action == "CastSpell"){
		}

		if (Action == "EquipItem"){
		}

		if (Action == "UseItem"){
		}

		if (Action == "Attack"){
		}
		//Game in progress action

		//Perform a character action

		//Perform an inventory action

		//Perform a world action

		//Perform targetting action

		if (Action != ""){
			cout << "Number of Open Boxes:" << Mailbox.BoxCount() << "\n";
			cout << "Number of Messages:" << Mailbox.MessageCount() << "\n";
		}
	}
}

string GetNewCharInfo(Character& Character){
	string RetVal;
	RetVal += "&Op=UpdateChar&b=" + to_string(Character.Box);
	RetVal += "&cInt=" + to_string(Character.GetStat(Intelligence, false));
	RetVal += "&cStrt=" + to_string(Character.GetStat(Strength, false));
	RetVal += "&cAgi=" + to_string(Character.GetStat(Agility, false));
	RetVal += "&cCon=" + to_string(Character.GetStat(Constitution, false));
	RetVal += "&cSpd=" + to_string(Character.GetStat(Speed, false));
	RetVal += "&cCha=" + to_string(Character.GetStat(Charisma, false));
	RetVal += "&cEnd=" + to_string(Character.GetStat(Endurance, false));
	RetVal += "&cHea=" + to_string(Character.GetStat(Health, false));
	RetVal += "&cMan=" + to_string(Character.GetStat(Mana, false));
	RetVal += "&cAtt=" + to_string(Character.GetStat(Attack, false));
	RetVal += "&cDef=" + to_string(Character.GetStat(Defense, false));
	RetVal += "&cACD=" + to_string(Character.GetStat(ActionCoolDown, false));
	RetVal += "&cMCD=" + to_string(Character.GetStat(MagicCoolDown, false));

	RetVal += "&mInt=" + to_string(Character.GetStat(Intelligence, true));
	RetVal += "&mStrt=" + to_string(Character.GetStat(Strength, true));
	RetVal += "&mAgi=" + to_string(Character.GetStat(Agility, true));
	RetVal += "&mCon=" + to_string(Character.GetStat(Constitution, true));
	RetVal += "&mSpd=" + to_string(Character.GetStat(Speed, true));
	RetVal += "&mCha=" + to_string(Character.GetStat(Charisma, true));
	RetVal += "&mEnd=" + to_string(Character.GetStat(Endurance, true));
	RetVal += "&mHea=" + to_string(Character.GetStat(Health, true));
	RetVal += "&mMan=" + to_string(Character.GetStat(Mana, true));
	RetVal += "&mAtt=" + to_string(Character.GetStat(Attack, true));
	RetVal += "&mDef=" + to_string(Character.GetStat(Defense, true));
	RetVal += "&mACD=" + to_string(Character.GetStat(ActionCoolDown, true));
	RetVal += "&mMCD=" + to_string(Character.GetStat(MagicCoolDown, true));

	RetVal += "&Level=" + Character.GetLevel();
	RetVal += "&Exp=" + Character.GetExp();
	RetVal += "&Gold=" + Character.GetGold();
	RetVal += "&X=" + Character.X;
	RetVal += "&Y=" + Character.Y;
	RetVal += "&Name=" + Character.Name;
	RetVal += "&Race=" + Character.Race;
	RetVal += "&Class=" + Character.Class;
	RetVal += "&Sex=" + Character.Sex;

	return RetVal;
}

int GetPlayerByBox(string BoxNumber){
	int FindBox = stoi(BoxNumber);
	for (int i = 0; i < Players.size(); i++){
		if (Players[i].Box == FindBox) return i;
	}
	return -1;
}

string GetValueFromKey(string FindKey){
	for (int i = 0; i < FormData.size(); i++){
		if (!FormData[i].Key.compare(FindKey)){ return FormData[i].Value; }
	}
	return "";
}

void getFormData(string Env){
	int EnvLen = Env.size();
	int Start = 1;
	int Mid = 0;
	FormInfo NewData;

	//Split Key-Value pairs and place in the FormData structure.
	for (int i = 1; i < EnvLen; i++){
	if (Env[i] == '='){Mid = i + 1;}
		if (Env[i] == '&' || i == EnvLen - 1){
			if (i == EnvLen - 1) i++;  //Get last character
			NewData.Key = Env.substr(Start,Mid-Start-1);
			NewData.Value = Env.substr(Mid, i - Mid);
			FormData.push_back(NewData);
			Start = i + 1;
		}
	}
}

<commit_msg>Work in progress<commit_after>#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <chrono>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <unistd.h>

#include "entity.h"
#include "character.h"
#include "monster.h"
#include "spell.h"
#include "item.h"
#include "tile.h"
#include "timetable.h"
#include "mailbox.h"
#include "map.h"

using namespace std;

const int StartingX = 8;
const int StartingY = 8;

//Structure for HTTP form data
struct FormInfo{
	string Key;
	string Value;
};

vector<Enemy> SpawnedEnemies; // []
vector<Character> Players;

//Vector to hold Key / Value pairs after processing
vector<FormInfo> FormData;

void getFormData(string Env);
string GetValueFromKey(string FindKey);
int GetPlayerByBox(string BoxNumber);
string GetNewCharInfo(Character& Character);

int main(){
	//Setup Game state
	TimeTable TimeTable;
	Mailbox Mailbox;
	Map Map;
	vector<Item> Items;
	vector<Spell> Spells;
	bool Done = false;
	string Message;
	string Action;
	string Temp;
	int User;
	string Box;

	//Load maps
	Map.LoadMap("map.csv");

	//Load definitions
	cout << "Beginning main loop\n" << flush;
	cout << "Mailbox: " << Mailbox.SetupSuccessful() << "\n" << flush;
	//Main Loop
	while (!Done){
		FormData.clear();
		Action = "";

		//Check Time table.  Perform function for all expired times
		TimeTable.SelectNextItem();
		TimeTable.Pop();

		//Check and Process Messages
		Message = Mailbox.GetNextMessage();
		getFormData(Message);
		Action = GetValueFromKey("Action");
		Box = GetValueFromKey("Box");
		if (Box.length() > 0) User = GetPlayerByBox(Box);

		if (Action == "EnterGame"){
			Character NewChar(GetValueFromKey("u"), GetValueFromKey("c"), stoi(GetValueFromKey("b")));
			Mailbox.OpenUserBox(NewChar.Box);
			NewChar.X = StartingX;
			NewChar.Y = StartingY;
// 			Temp = "&Op=MyPosition&X=" + to_string(StartingX) + "&Y=" + to_string(StartingY);
// 			Mailbox.SendMessageToBox(Temp, NewChar.Box);
			Mailbox.SendMessageToBox("&Op=Con&Message=" + NewChar.Name + " has entered the game.", NewChar.Box);
			Temp = GetNewCharInfo(NewChar);
			Mailbox.BroadcastMessage(GetNewCharInfo(NewChar));
			Mailbox.SendMessageToBox(GetNewCharInfo(NewChar), NewChar.Box);
			for (int i = 0; i < Players.size(); i++){
				Mailbox.SendMessageToBox(GetNewCharInfo(Players[i]), NewChar.Box);
			}
			Players.push_back(NewChar);
		}

		if (Action == "RepeatMessage"){
			//This convoluted mess tests the message passing among objects (It's obv super redundant.)
			string TestString = "&Op=Alert&Message=" + GetValueFromKey("Message") + " Repeated back at ya.";
			int TestBox = Players[GetPlayerByBox(GetValueFromKey("b"))].Box;
			cout << "Test:" << TestString << "\n";
			Mailbox.SendMessageToBox(TestString , TestBox );

		}

		if (Action == "LeaveGame"){
			//Done = true;
			Mailbox.CloseUserBox(stoi(GetValueFromKey("b")));
		}

		if (Action == "GetPlot"){
			int X = stoi(GetValueFromKey("X"));
			int Y = stoi(GetValueFromKey("Y"));
			Temp = "&Op=MapPlot&X=" + GetValueFromKey("X") + "&Y=" + GetValueFromKey("Y") + "&Plot=" + Map.GetPlot(X,Y);
			Mailbox.SendMessageToBox(Temp, Players[User].Box);
		}

		if (Action == "Move"){
			int Who = GetPlayerByBox(GetValueFromKey("b"));
			int X = stoi(GetValueFromKey("XMove"));
			int Y = stoi(GetValueFromKey("YMove"));
			cout << "Move";
			if (Map.Passable(Players[Who].X + X, Players[Who].Y + Y)){
				string Temp = "&Op=PlayerMove&b=" + GetValueFromKey("b") + "&X=" + GetValueFromKey("XMove") + "&Y=" + GetValueFromKey("YMove");
				Mailbox.BroadcastMessage(Temp);
				Mailbox.SendMessageToBox(Temp, Players[Who].Box);
			}
		}

		if (Action == "CastSpell"){
			if (GetValueFromKey("enemyID") != "Not Found"){
				Spells[stoi(GetValueFromKey("SpellID"))].cast_spell(Players[stoi(GetPlayerByBox("b"))], SpawnedEnemies[stoi(GetValueFromKey("enemyID"))]);
			} else {

				Spells[stoi(GetValueFromKey("SpellID"))].cast_spell(Players[stoi(GetPlayerByBox("b"))], Players[stoi(GetPlayerByBox(GetValueFromKey("targetB"))]);
			}
		}

		if (Action == "EquipItem"){
			Players[GetPlayerByBox(GetValueFromKey("b"))].EquipItem(stoi(GetValueFromKey("ItemID")));
		}

		if (Action == "UseItem"){
			Items[stoi(GetValueFromKey("ItemID"))].Use(Players[stoi(GetValueFromKey("b"))], Players[stoi(GetValueFromKey("targetB"))];
		}

		if (Action == "Attack"){
			Players[stoi(GetValueFromKey("b"))].Damage(SpawnedEnemies[stoi(GetValueFromKey("enemyID"))]);
		}

		if (Action != ""){
			cout << "Number of Open Boxes:" << Mailbox.BoxCount() << "\n";
			cout << "Number of Messages:" << Mailbox.MessageCount() << "\n";
		}

	}
}

string GetNewCharInfo(Character& Character){
	string RetVal;
	RetVal += "&Op=UpdateChar&b=" + to_string(Character.Box);
	RetVal += "&cInt=" + to_string(Character.GetStat(Intelligence, false));
	RetVal += "&cStrt=" + to_string(Character.GetStat(Strength, false));
	RetVal += "&cAgi=" + to_string(Character.GetStat(Agility, false));
	RetVal += "&cCon=" + to_string(Character.GetStat(Constitution, false));
	RetVal += "&cSpd=" + to_string(Character.GetStat(Speed, false));
	RetVal += "&cCha=" + to_string(Character.GetStat(Charisma, false));
	RetVal += "&cEnd=" + to_string(Character.GetStat(Endurance, false));
	RetVal += "&cHea=" + to_string(Character.GetStat(Health, false));
	RetVal += "&cMan=" + to_string(Character.GetStat(Mana, false));
	RetVal += "&cAtt=" + to_string(Character.GetStat(Attack, false));
	RetVal += "&cDef=" + to_string(Character.GetStat(Defense, false));
	RetVal += "&cACD=" + to_string(Character.GetStat(ActionCoolDown, false));
	RetVal += "&cMCD=" + to_string(Character.GetStat(MagicCoolDown, false));

	RetVal += "&mInt=" + to_string(Character.GetStat(Intelligence, true));
	RetVal += "&mStrt=" + to_string(Character.GetStat(Strength, true));
	RetVal += "&mAgi=" + to_string(Character.GetStat(Agility, true));
	RetVal += "&mCon=" + to_string(Character.GetStat(Constitution, true));
	RetVal += "&mSpd=" + to_string(Character.GetStat(Speed, true));
	RetVal += "&mCha=" + to_string(Character.GetStat(Charisma, true));
	RetVal += "&mEnd=" + to_string(Character.GetStat(Endurance, true));
	RetVal += "&mHea=" + to_string(Character.GetStat(Health, true));
	RetVal += "&mMan=" + to_string(Character.GetStat(Mana, true));
	RetVal += "&mAtt=" + to_string(Character.GetStat(Attack, true));
	RetVal += "&mDef=" + to_string(Character.GetStat(Defense, true));
	RetVal += "&mACD=" + to_string(Character.GetStat(ActionCoolDown, true));
	RetVal += "&mMCD=" + to_string(Character.GetStat(MagicCoolDown, true));

	RetVal += "&Level=" + Character.GetLevel();
	RetVal += "&Exp=" + Character.GetExp();
	RetVal += "&Gold=" + Character.GetGold();
	RetVal += "&X=" + Character.X;
	RetVal += "&Y=" + Character.Y;
	RetVal += "&Name=" + Character.Name;
	RetVal += "&Race=" + Character.Race;
	RetVal += "&Class=" + Character.Class;
	RetVal += "&Sex=" + Character.Sex;

	return RetVal;
}

int GetPlayerByBox(string BoxNumber){
	int FindBox = stoi(BoxNumber);
	for (int i = 0; i < Players.size(); i++){
		if (Players[i].Box == FindBox) return i;
	}
	return -1;
}

string GetValueFromKey(string FindKey){
	for (int i = 0; i < FormData.size(); i++){
		if (!FormData[i].Key.compare(FindKey)){ return FormData[i].Value; }
	}
	return "";
}

void getFormData(string Env){
	int EnvLen = Env.size();
	int Start = 1;
	int Mid = 0;
	FormInfo NewData;

	//Split Key-Value pairs and place in the FormData structure.
	for (int i = 1; i < EnvLen; i++){
	if (Env[i] == '='){Mid = i + 1;}
		if (Env[i] == '&' || i == EnvLen - 1){
			if (i == EnvLen - 1) i++;  //Get last character
			NewData.Key = Env.substr(Start,Mid-Start-1);
			NewData.Value = Env.substr(Mid, i - Mid);
			FormData.push_back(NewData);
			Start = i + 1;
		}
	}
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/sql/mysql/MySqlRow.h"
#include "db/sql/mysql/MySqlStatement.h"
#include "db/sql/mysql/MySqlConnection.h"

using namespace std;
using namespace db::rt;
using namespace db::sql;
using namespace db::sql::mysql;

MySqlRow::MySqlRow(MySqlStatement* s) : Row(s)
{
   mFields = NULL;
   mFieldCount = 0;
   mBindings = NULL;
}

MySqlRow::~MySqlRow()
{
}

MYSQL_STMT* MySqlRow::getStatementHandle()
{
   return ((MySqlStatement*)mStatement)->mHandle;
}

long long MySqlRow::getColumnIndex(const char* name)
{
   // use 64-bit signed int to cover all values + error (negative 1)
   long long rval = -1;

   for(unsigned int i = 0; i < mFieldCount; i++)
   {
      if(strcmp(name, mFields[i].name) == 0)
      {
         rval = i;
         break;
      }
   }

   if(rval == -1)
   {
      // set exception
      int length = 100 + strlen(name);
      char msg[length];
      snprintf(msg, length,
         "Could not get column value, invalid column name!, name='%s'", name);
      ExceptionRef e = new SqlException(msg);
      Exception::setLast(e, false);
   }

   return rval;
}

void MySqlRow::setFields(
   MYSQL_FIELD* fields, unsigned int count, MYSQL_BIND* bindings)
{
   mFields = fields;
   mFieldCount = count;
   mBindings = bindings;
}

bool MySqlRow::getType(unsigned int column, int& type)
{
   bool rval = false;

   if(column >= mFieldCount)
   {
      char temp[100];
      snprintf(temp, 100,
         "Could not get column type, invalid column index!,index=%i", column);
      ExceptionRef e = new SqlException(temp);
      Exception::setLast(e, false);
   }
   else
   {
      type = mFields[column].type;
      rval = true;
   }

   return rval;
}

bool MySqlRow::getInt32(unsigned int column, int& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 4;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getUInt32(unsigned int column, unsigned int& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 4;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getInt64(unsigned int column, long long& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONGLONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 8;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getUInt64(unsigned int column, unsigned long long& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONGLONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 8;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getText(unsigned int column, string& str)
{
   mBindings[column].buffer_type = MYSQL_TYPE_BLOB;
   char temp[mBindings[column].buffer_length + 1];
   mBindings[column].buffer = temp;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   memset(temp + mBindings[column].buffer_length, 0, 1);
   str.assign(temp);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getType(const char* column, int& type)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getType(index, type);
   }

   return rval;
}

bool MySqlRow::getInt32(const char* column, int& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getInt32(index, i);
   }

   return rval;
}

bool MySqlRow::getUInt32(const char* column, unsigned int& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getUInt32(index, i);
   }

   return rval;
}

bool MySqlRow::getInt64(const char* column, long long& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getInt64(index, i);
   }

   return rval;
}

bool MySqlRow::getUInt64(const char* column, unsigned long long& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getUInt64(index, i);
   }

   return rval;
}

bool MySqlRow::getText(const char* column, std::string& str)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getText(index, str);
   }

   return rval;
}
<commit_msg>Dave added code to handle null text data.<commit_after>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/sql/mysql/MySqlRow.h"
#include "db/sql/mysql/MySqlStatement.h"
#include "db/sql/mysql/MySqlConnection.h"

using namespace std;
using namespace db::rt;
using namespace db::sql;
using namespace db::sql::mysql;

MySqlRow::MySqlRow(MySqlStatement* s) : Row(s)
{
   mFields = NULL;
   mFieldCount = 0;
   mBindings = NULL;
}

MySqlRow::~MySqlRow()
{
}

MYSQL_STMT* MySqlRow::getStatementHandle()
{
   return ((MySqlStatement*)mStatement)->mHandle;
}

long long MySqlRow::getColumnIndex(const char* name)
{
   // use 64-bit signed int to cover all values + error (negative 1)
   long long rval = -1;

   for(unsigned int i = 0; i < mFieldCount; i++)
   {
      if(strcmp(name, mFields[i].name) == 0)
      {
         rval = i;
         break;
      }
   }

   if(rval == -1)
   {
      // set exception
      int length = 100 + strlen(name);
      char msg[length];
      snprintf(msg, length,
         "Could not get column value, invalid column name!, name='%s'", name);
      ExceptionRef e = new SqlException(msg);
      Exception::setLast(e, false);
   }

   return rval;
}

void MySqlRow::setFields(
   MYSQL_FIELD* fields, unsigned int count, MYSQL_BIND* bindings)
{
   mFields = fields;
   mFieldCount = count;
   mBindings = bindings;
}

bool MySqlRow::getType(unsigned int column, int& type)
{
   bool rval = false;

   if(column >= mFieldCount)
   {
      char temp[100];
      snprintf(temp, 100,
         "Could not get column type, invalid column index!,index=%i", column);
      ExceptionRef e = new SqlException(temp);
      Exception::setLast(e, false);
   }
   else
   {
      type = mFields[column].type;
      rval = true;
   }

   return rval;
}

bool MySqlRow::getInt32(unsigned int column, int& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 4;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getUInt32(unsigned int column, unsigned int& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 4;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getInt64(unsigned int column, long long& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONGLONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 8;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getUInt64(unsigned int column, unsigned long long& i)
{
   mBindings[column].buffer_type = MYSQL_TYPE_LONGLONG;
   mBindings[column].buffer = (char*)&i;
   mBindings[column].buffer_length = 8;
   mBindings[column].length = &mBindings[column].buffer_length;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getText(unsigned int column, string& str)
{
   my_bool isNull;
   mBindings[column].buffer_type = MYSQL_TYPE_BLOB;
   char temp[mBindings[column].buffer_length + 1];
   mBindings[column].buffer = temp;
   mBindings[column].length = &mBindings[column].buffer_length;
   mBindings[column].is_null = &isNull;
   mysql_stmt_fetch_column(getStatementHandle(), &mBindings[column], column, 0);

   if(isNull)
   {
      str.erase();
   }
   else
   {
      temp[mBindings[column].buffer_length] = 0;
      str.assign(temp);
   }

   // FIXME: check exceptions, etc
   return true;
}

bool MySqlRow::getType(const char* column, int& type)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getType(index, type);
   }

   return rval;
}

bool MySqlRow::getInt32(const char* column, int& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getInt32(index, i);
   }

   return rval;
}

bool MySqlRow::getUInt32(const char* column, unsigned int& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getUInt32(index, i);
   }

   return rval;
}

bool MySqlRow::getInt64(const char* column, long long& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getInt64(index, i);
   }

   return rval;
}

bool MySqlRow::getUInt64(const char* column, unsigned long long& i)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getUInt64(index, i);
   }

   return rval;
}

bool MySqlRow::getText(const char* column, std::string& str)
{
   bool rval = false;

   // get column index for name
   long long index = getColumnIndex(column);
   if(index != -1)
   {
      rval = getText(index, str);
   }

   return rval;
}
<|endoftext|>


<commit_before>//Created by Daniel May

#ifndef GRAPHICSNODE_H
#define GRAPHICSNODE_H

#include <Graphics.hpp>
#include <vector>

using namespace std;
using namespace sf;

class renderList
{
	//Member variables
	private:

	//A reference to the window where everything will be drawn
	RenderWindow &window;

	//Vector to store all objects to be drawn
	vector<Drawable*> list;

	public:

	//Declare member functions and constructor/destructor

	renderList(sf::RenderWindow& win);
	~renderList();

	void addObject(Drawable& drawable);
	void addList(vector<Drawable*> drawableList);

	void removeObject(Drawable& drawable);
	void removeList(vector<Drawable*> drawableList);

	void removeAll();

	void render(Color background);

};

#endif
<commit_msg>Delete renderList.hpp<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/extensions/extension_popup.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_toggle_action.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "third_party/skia/include/core/SkColor.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"

#if defined(OS_LINUX)
#include "views/widget/widget_gtk.h"
#endif

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/wm_ipc.h"
#include "cros/chromeos_wm_ipc_enums.h"
#endif

using views::Widget;

// The minimum/maximum dimensions of the popup.
// The minimum is just a little larger than the size of the button itself.
// The maximum is an arbitrary number that should be smaller than most screens.
const int ExtensionPopup::kMinWidth = 25;
const int ExtensionPopup::kMinHeight = 25;
const int ExtensionPopup::kMaxWidth = 800;
const int ExtensionPopup::kMaxHeight = 600;

namespace {

// The width, in pixels, of the black-border on a popup.
const int kPopupBorderWidth = 1;

const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2;

}  // namespace

ExtensionPopup::ExtensionPopup(ExtensionHost* host,
                               views::Widget* frame,
                               const gfx::Rect& relative_to,
                               BubbleBorder::ArrowLocation arrow_location,
                               bool activate_on_show,
                               bool inspect_with_devtools,
                               PopupChrome chrome,
                               Observer* observer)
    : BrowserBubble(host->view(),
                    frame,
                    gfx::Point(),
                    RECTANGLE_CHROME == chrome),  // If no bubble chrome is to
                                                  // be displayed, then enable a
                                                  // drop-shadow on the bubble
                                                  // widget.
      relative_to_(relative_to),
      extension_host_(host),
      activate_on_show_(activate_on_show),
      inspect_with_devtools_(inspect_with_devtools),
      close_on_lost_focus_(true),
      closing_(false),
      border_widget_(NULL),
      border_(NULL),
      border_view_(NULL),
      popup_chrome_(chrome),
      observer_(observer),
      anchor_position_(arrow_location),
      instance_lifetime_(new InternalRefCounter()){
  AddRef();  // Balanced in Close();
  set_delegate(this);
  host->view()->SetContainer(this);

  // We wait to show the popup until the contained host finishes loading.
  registrar_.Add(this,
                 NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
                 Source<Profile>(host->profile()));

  // Listen for the containing view calling window.close();
  registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 Source<Profile>(host->profile()));

  // TODO(erikkay) Some of this border code is derived from InfoBubble.
  // We should see if we can unify these classes.

  // Keep relative_to_ in frame-relative coordinates to aid in drag
  // positioning.
  gfx::Point origin = relative_to_.origin();
  views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin);
  relative_to_.set_origin(origin);

  // The bubble chrome requires a separate window, so construct it here.
  if (BUBBLE_CHROME == popup_chrome_) {
    gfx::NativeView native_window = frame->GetNativeView();
#if defined(OS_LINUX)
    border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
    static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent();
    static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent();
#else
    border_widget_ = Widget::CreatePopupWidget(Widget::Transparent,
                                               Widget::NotAcceptEvents,
                                               Widget::DeleteOnDestroy,
                                               Widget::MirrorOriginInRTL);
#endif
    border_widget_->Init(native_window, bounds());
#if defined(OS_CHROMEOS)
    chromeos::WmIpc::instance()->SetWindowType(
        border_widget_->GetNativeView(),
        chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE,
        NULL);
#endif
    border_ = new BubbleBorder(arrow_location);
    border_view_ = new views::View;
    border_view_->set_background(new BubbleBackground(border_));

    border_view_->set_border(border_);
    border_widget_->SetContentsView(border_view_);
    // Ensure that the popup contents are always displayed ontop of the border
    // widget.
    border_widget_->MoveAbove(popup_);
  } else {
    // Otherwise simply set a black-border on the view containing the popup
    // extension view.
    views::Border* border = views::Border::CreateSolidBorder(kPopupBorderWidth,
                                                             SK_ColorBLACK);
    view()->set_border(border);
  }
}

ExtensionPopup::~ExtensionPopup() {
  // The widget is set to delete on destroy, so no leak here.
  if (border_widget_)
    border_widget_->Close();
}

void ExtensionPopup::SetArrowPosition(
    BubbleBorder::ArrowLocation arrow_location) {
  DCHECK_NE(BubbleBorder::NONE, arrow_location) <<
    "Extension popups must be positioned relative to an arrow.";

  anchor_position_ = arrow_location;
  if (border_)
    border_->set_arrow_location(anchor_position_);
}

void ExtensionPopup::Hide() {
  BrowserBubble::Hide();
  if (border_widget_)
    border_widget_->Hide();
}

void ExtensionPopup::Show(bool activate) {
  if (visible())
    return;

#if defined(OS_WIN)
  if (frame_->GetWindow())
    frame_->GetWindow()->DisableInactiveRendering();
#endif

  ResizeToView();

  // Show the border first, then the popup overlaid on top.
  if (border_widget_)
    border_widget_->Show();
  BrowserBubble::Show(activate);
}

void ExtensionPopup::ResizeToView() {
  if (observer_)
    observer_->ExtensionPopupResized(this);

  gfx::Rect rect = GetOuterBounds();

  gfx::Point origin = rect.origin();
  views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin);

  if (border_widget_) {
    // Set the bubble-chrome widget according to the outer bounds of the entire
    // popup.
    border_widget_->SetBounds(rect);

    // Now calculate the inner bounds.  This is a bit more convoluted than
    // it should be because BrowserBubble coordinates are in Browser coordinates
    // while |rect| is in screen coordinates.
    gfx::Insets border_insets;
    border_->GetInsets(&border_insets);

    origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius);
    origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius);

    gfx::Size new_size = view()->size();
    SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height());
  } else {
    SetBounds(origin.x(), origin.y(), rect.width(), rect.height());
  }
}

void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) {
  ResizeToView();
}

void ExtensionPopup::BubbleBrowserWindowClosing(BrowserBubble* bubble) {
  if (!closing_)
    Close();
}

void ExtensionPopup::BubbleGotFocus(BrowserBubble* bubble) {
  // Forward the focus to the renderer.
  host()->render_view_host()->view()->Focus();
}

void ExtensionPopup::BubbleLostFocus(BrowserBubble* bubble,
    bool lost_focus_to_child) {
  if (closing_ ||                // We are already closing.
      inspect_with_devtools_ ||  // The popup is being inspected.
      !close_on_lost_focus_ ||   // Our client is handling focus listening.
      lost_focus_to_child)       // A child of this view got focus.
    return;

  // When we do close on BubbleLostFocus, we do it in the next event loop
  // because a subsequent event in this loop may also want to close this popup
  // and if so, we want to allow that. Example: Clicking the same browser
  // action button that opened the popup. If we closed immediately, the
  // browser action container would fail to discover that the same button
  // was pressed.
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
      &ExtensionPopup::Close));
}

void ExtensionPopup::Observe(NotificationType type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::EXTENSION_HOST_DID_STOP_LOADING:
      // Once we receive did stop loading, the content will be complete and
      // the width will have been computed.  Now it's safe to show.
      if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) {
        Show(activate_on_show_);

        if (inspect_with_devtools_) {
          // Listen for the the devtools window closing.
          registrar_.Add(this, NotificationType::DEVTOOLS_WINDOW_CLOSING,
              Source<Profile>(extension_host_->profile()));
          DevToolsManager::GetInstance()->ToggleDevToolsWindow(
              extension_host_->render_view_host(),
              DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
        }
      }
      break;
    case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE:
      // If we aren't the host of the popup, then disregard the notification.
      if (Details<ExtensionHost>(host()) != details)
        return;
      Close();

      break;
    case NotificationType::DEVTOOLS_WINDOW_CLOSING:
      // Make sure its the devtools window that inspecting our popup.
      if (Details<RenderViewHost>(extension_host_->render_view_host()) !=
          details)
        return;

      // If the devtools window is closing, we post a task to ourselves to
      // close the popup. This gives the devtools window a chance to finish
      // detaching from the inspected RenderViewHost.
      MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
          &ExtensionPopup::Close));

      break;
    default:
      NOTREACHED() << L"Received unexpected notification";
  }
}

void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) {
  // Constrain the size to popup min/max.
  gfx::Size sz = view->GetPreferredSize();
  view->SetBounds(view->x(), view->y(),
      std::max(kMinWidth, std::min(kMaxWidth, sz.width())),
      std::max(kMinHeight, std::min(kMaxHeight, sz.height())));

  // If popup_chrome_ == RECTANGLE_CHROME, the border is drawn in the client
  // area of the ExtensionView, rather than in a window which sits behind it.
  // In this case, the actual size of the view must be enlarged so that the
  // web contents portion of the view gets its full PreferredSize area.
  if (view->border()) {
    gfx::Insets border_insets;
    view->border()->GetInsets(&border_insets);

    gfx::Rect bounds(view->bounds());
    gfx::Size size(bounds.size());
    size.Enlarge(border_insets.width(), border_insets.height());
    view->SetBounds(bounds.x(), bounds.y(), size.width(), size.height());
  }

  ResizeToView();
}

gfx::Rect ExtensionPopup::GetOuterBounds() const {
  gfx::Rect relative_rect = relative_to_;
  gfx::Point origin = relative_rect.origin();
  views::View::ConvertPointToScreen(frame_->GetRootView(), &origin);
  relative_rect.set_origin(origin);

  gfx::Size contents_size = view()->size();

  // If the popup has a bubble-chrome, then let the BubbleBorder compute
  // the bounds.
  if (BUBBLE_CHROME == popup_chrome_) {
    // The rounded corners cut off more of the view than the border insets
    // claim. Since we can't clip the ExtensionView's corners, we need to
    // increase the inset by half the corner radius as well as lying about the
    // size of the contents size to compensate.
    contents_size.Enlarge(2 * kPopupBubbleCornerRadius,
                          2 * kPopupBubbleCornerRadius);
    return border_->GetBounds(relative_rect, contents_size);
  }

  // Position the bounds according to the location of the |anchor_position_|.
  int y;
  if (BubbleBorder::is_arrow_on_top(anchor_position_))
    y = relative_rect.bottom();
  else
    y = relative_rect.y() - contents_size.height();

  int x;
  if (BubbleBorder::is_arrow_on_left(anchor_position_))
    x = relative_rect.x();
  else
    // Note that if the arrow is on the right, that the x position of the popup
    // is assigned so that the rightmost edge of the popup is aligned with the
    // rightmost edge of the relative region.
    x = relative_rect.right() - contents_size.width();

  return gfx::Rect(x, y, contents_size.width(), contents_size.height());
}

// static
ExtensionPopup* ExtensionPopup::Show(
    const GURL& url,
    Browser* browser,
    Profile* profile,
    gfx::NativeWindow frame_window,
    const gfx::Rect& relative_to,
    BubbleBorder::ArrowLocation arrow_location,
    bool activate_on_show,
    bool inspect_with_devtools,
    PopupChrome chrome,
    Observer* observer) {
  DCHECK(profile);
  DCHECK(frame_window);
  ExtensionProcessManager* manager = profile->GetExtensionProcessManager();
  DCHECK(manager);
  if (!manager)
    return NULL;

  // If no Browser instance was given, attempt to look up one matching the given
  // profile.
  if (!browser)
    browser = BrowserList::FindBrowserWithProfile(profile);

  Widget* frame_widget = Widget::GetWidgetFromNativeWindow(frame_window);
  DCHECK(frame_widget);
  if (!frame_widget)
    return NULL;

  ExtensionHost* host = manager->CreatePopup(url, browser);
  if (observer)
    observer->ExtensionHostCreated(host);

  ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to,
                                             arrow_location, activate_on_show,
                                             inspect_with_devtools, chrome,
                                             observer);

  // If the host had somehow finished loading, then we'd miss the notification
  // and not show.  This seems to happen in single-process mode.
  if (host->did_stop_loading())
    popup->Show(activate_on_show);

  return popup;
}

void ExtensionPopup::Close() {
  if (closing_)
    return;
  closing_ = true;
  DetachFromBrowser();

  if (observer_)
    observer_->ExtensionPopupIsClosing(this);

  Release();  // Balanced in ctor.
}

void ExtensionPopup::Release() {
  bool final_release = instance_lifetime_->HasOneRef();
  instance_lifetime_->Release();
  if (final_release) {
    DCHECK(closing_) << "ExtensionPopup to be destroyed before being closed.";
    ExtensionPopup::Observer* observer = observer_;
    delete this;

    if (observer)
      observer->ExtensionPopupClosed(this);
  }
}
<commit_msg>Explain in a comment what was explained in the review, so that people who look at the code don't cringe.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/views/extensions/extension_popup.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_toggle_action.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "third_party/skia/include/core/SkColor.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"

#if defined(OS_LINUX)
#include "views/widget/widget_gtk.h"
#endif

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/wm_ipc.h"
#include "cros/chromeos_wm_ipc_enums.h"
#endif

using views::Widget;

// The minimum/maximum dimensions of the popup.
// The minimum is just a little larger than the size of the button itself.
// The maximum is an arbitrary number that should be smaller than most screens.
const int ExtensionPopup::kMinWidth = 25;
const int ExtensionPopup::kMinHeight = 25;
const int ExtensionPopup::kMaxWidth = 800;
const int ExtensionPopup::kMaxHeight = 600;

namespace {

// The width, in pixels, of the black-border on a popup.
const int kPopupBorderWidth = 1;

const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2;

}  // namespace

ExtensionPopup::ExtensionPopup(ExtensionHost* host,
                               views::Widget* frame,
                               const gfx::Rect& relative_to,
                               BubbleBorder::ArrowLocation arrow_location,
                               bool activate_on_show,
                               bool inspect_with_devtools,
                               PopupChrome chrome,
                               Observer* observer)
    : BrowserBubble(host->view(),
                    frame,
                    gfx::Point(),
                    RECTANGLE_CHROME == chrome),  // If no bubble chrome is to
                                                  // be displayed, then enable a
                                                  // drop-shadow on the bubble
                                                  // widget.
      relative_to_(relative_to),
      extension_host_(host),
      activate_on_show_(activate_on_show),
      inspect_with_devtools_(inspect_with_devtools),
      close_on_lost_focus_(true),
      closing_(false),
      border_widget_(NULL),
      border_(NULL),
      border_view_(NULL),
      popup_chrome_(chrome),
      observer_(observer),
      anchor_position_(arrow_location),
      instance_lifetime_(new InternalRefCounter()){
  AddRef();  // Balanced in Close();
  set_delegate(this);
  host->view()->SetContainer(this);

  // We wait to show the popup until the contained host finishes loading.
  registrar_.Add(this,
                 NotificationType::EXTENSION_HOST_DID_STOP_LOADING,
                 Source<Profile>(host->profile()));

  // Listen for the containing view calling window.close();
  registrar_.Add(this, NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE,
                 Source<Profile>(host->profile()));

  // TODO(erikkay) Some of this border code is derived from InfoBubble.
  // We should see if we can unify these classes.

  // Keep relative_to_ in frame-relative coordinates to aid in drag
  // positioning.
  gfx::Point origin = relative_to_.origin();
  views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin);
  relative_to_.set_origin(origin);

  // The bubble chrome requires a separate window, so construct it here.
  if (BUBBLE_CHROME == popup_chrome_) {
    gfx::NativeView native_window = frame->GetNativeView();
#if defined(OS_LINUX)
    border_widget_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
    static_cast<views::WidgetGtk*>(border_widget_)->MakeTransparent();
    static_cast<views::WidgetGtk*>(border_widget_)->make_transient_to_parent();
#else
    border_widget_ = Widget::CreatePopupWidget(Widget::Transparent,
                                               Widget::NotAcceptEvents,
                                               Widget::DeleteOnDestroy,
                                               Widget::MirrorOriginInRTL);
#endif
    border_widget_->Init(native_window, bounds());
#if defined(OS_CHROMEOS)
    chromeos::WmIpc::instance()->SetWindowType(
        border_widget_->GetNativeView(),
        chromeos::WM_IPC_WINDOW_CHROME_INFO_BUBBLE,
        NULL);
#endif
    border_ = new BubbleBorder(arrow_location);
    border_view_ = new views::View;
    border_view_->set_background(new BubbleBackground(border_));

    border_view_->set_border(border_);
    border_widget_->SetContentsView(border_view_);
    // Ensure that the popup contents are always displayed ontop of the border
    // widget.
    border_widget_->MoveAbove(popup_);
  } else {
    // Otherwise simply set a black-border on the view containing the popup
    // extension view.
    views::Border* border = views::Border::CreateSolidBorder(kPopupBorderWidth,
                                                             SK_ColorBLACK);
    view()->set_border(border);
  }
}

ExtensionPopup::~ExtensionPopup() {
  // The widget is set to delete on destroy, so no leak here.
  if (border_widget_)
    border_widget_->Close();
}

void ExtensionPopup::SetArrowPosition(
    BubbleBorder::ArrowLocation arrow_location) {
  DCHECK_NE(BubbleBorder::NONE, arrow_location) <<
    "Extension popups must be positioned relative to an arrow.";

  anchor_position_ = arrow_location;
  if (border_)
    border_->set_arrow_location(anchor_position_);
}

void ExtensionPopup::Hide() {
  BrowserBubble::Hide();
  if (border_widget_)
    border_widget_->Hide();
}

void ExtensionPopup::Show(bool activate) {
  if (visible())
    return;

#if defined(OS_WIN)
  if (frame_->GetWindow())
    frame_->GetWindow()->DisableInactiveRendering();
#endif

  ResizeToView();

  // Show the border first, then the popup overlaid on top.
  if (border_widget_)
    border_widget_->Show();
  BrowserBubble::Show(activate);
}

void ExtensionPopup::ResizeToView() {
  if (observer_)
    observer_->ExtensionPopupResized(this);

  gfx::Rect rect = GetOuterBounds();

  gfx::Point origin = rect.origin();
  views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin);

  if (border_widget_) {
    // Set the bubble-chrome widget according to the outer bounds of the entire
    // popup.
    border_widget_->SetBounds(rect);

    // Now calculate the inner bounds.  This is a bit more convoluted than
    // it should be because BrowserBubble coordinates are in Browser coordinates
    // while |rect| is in screen coordinates.
    gfx::Insets border_insets;
    border_->GetInsets(&border_insets);

    origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius);
    origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius);

    gfx::Size new_size = view()->size();
    SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height());
  } else {
    SetBounds(origin.x(), origin.y(), rect.width(), rect.height());
  }
}

void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) {
  ResizeToView();
}

void ExtensionPopup::BubbleBrowserWindowClosing(BrowserBubble* bubble) {
  if (!closing_)
    Close();
}

void ExtensionPopup::BubbleGotFocus(BrowserBubble* bubble) {
  // Forward the focus to the renderer.
  host()->render_view_host()->view()->Focus();
}

void ExtensionPopup::BubbleLostFocus(BrowserBubble* bubble,
    bool lost_focus_to_child) {
  if (closing_ ||                // We are already closing.
      inspect_with_devtools_ ||  // The popup is being inspected.
      !close_on_lost_focus_ ||   // Our client is handling focus listening.
      lost_focus_to_child)       // A child of this view got focus.
    return;

  // When we do close on BubbleLostFocus, we do it in the next event loop
  // because a subsequent event in this loop may also want to close this popup
  // and if so, we want to allow that. Example: Clicking the same browser
  // action button that opened the popup. If we closed immediately, the
  // browser action container would fail to discover that the same button
  // was pressed.
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
      &ExtensionPopup::Close));
}

void ExtensionPopup::Observe(NotificationType type,
                             const NotificationSource& source,
                             const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::EXTENSION_HOST_DID_STOP_LOADING:
      // Once we receive did stop loading, the content will be complete and
      // the width will have been computed.  Now it's safe to show.
      if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) {
        Show(activate_on_show_);

        if (inspect_with_devtools_) {
          // Listen for the the devtools window closing.
          registrar_.Add(this, NotificationType::DEVTOOLS_WINDOW_CLOSING,
              Source<Profile>(extension_host_->profile()));
          DevToolsManager::GetInstance()->ToggleDevToolsWindow(
              extension_host_->render_view_host(),
              DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
        }
      }
      break;
    case NotificationType::EXTENSION_HOST_VIEW_SHOULD_CLOSE:
      // If we aren't the host of the popup, then disregard the notification.
      if (Details<ExtensionHost>(host()) != details)
        return;
      Close();

      break;
    case NotificationType::DEVTOOLS_WINDOW_CLOSING:
      // Make sure its the devtools window that inspecting our popup.
      if (Details<RenderViewHost>(extension_host_->render_view_host()) !=
          details)
        return;

      // If the devtools window is closing, we post a task to ourselves to
      // close the popup. This gives the devtools window a chance to finish
      // detaching from the inspected RenderViewHost.
      MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(this,
          &ExtensionPopup::Close));

      break;
    default:
      NOTREACHED() << L"Received unexpected notification";
  }
}

void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) {
  // Constrain the size to popup min/max.
  gfx::Size sz = view->GetPreferredSize();
  view->SetBounds(view->x(), view->y(),
      std::max(kMinWidth, std::min(kMaxWidth, sz.width())),
      std::max(kMinHeight, std::min(kMaxHeight, sz.height())));

  // If popup_chrome_ == RECTANGLE_CHROME, the border is drawn in the client
  // area of the ExtensionView, rather than in a window which sits behind it.
  // In this case, the actual size of the view must be enlarged so that the
  // web contents portion of the view gets its full PreferredSize area.
  if (view->border()) {
    gfx::Insets border_insets;
    view->border()->GetInsets(&border_insets);

    gfx::Rect bounds(view->bounds());
    gfx::Size size(bounds.size());
    size.Enlarge(border_insets.width(), border_insets.height());
    view->SetBounds(bounds.x(), bounds.y(), size.width(), size.height());
  }

  ResizeToView();
}

gfx::Rect ExtensionPopup::GetOuterBounds() const {
  gfx::Rect relative_rect = relative_to_;
  gfx::Point origin = relative_rect.origin();
  views::View::ConvertPointToScreen(frame_->GetRootView(), &origin);
  relative_rect.set_origin(origin);

  gfx::Size contents_size = view()->size();

  // If the popup has a bubble-chrome, then let the BubbleBorder compute
  // the bounds.
  if (BUBBLE_CHROME == popup_chrome_) {
    // The rounded corners cut off more of the view than the border insets
    // claim. Since we can't clip the ExtensionView's corners, we need to
    // increase the inset by half the corner radius as well as lying about the
    // size of the contents size to compensate.
    contents_size.Enlarge(2 * kPopupBubbleCornerRadius,
                          2 * kPopupBubbleCornerRadius);
    return border_->GetBounds(relative_rect, contents_size);
  }

  // Position the bounds according to the location of the |anchor_position_|.
  int y;
  if (BubbleBorder::is_arrow_on_top(anchor_position_))
    y = relative_rect.bottom();
  else
    y = relative_rect.y() - contents_size.height();

  int x;
  if (BubbleBorder::is_arrow_on_left(anchor_position_))
    x = relative_rect.x();
  else
    // Note that if the arrow is on the right, that the x position of the popup
    // is assigned so that the rightmost edge of the popup is aligned with the
    // rightmost edge of the relative region.
    x = relative_rect.right() - contents_size.width();

  return gfx::Rect(x, y, contents_size.width(), contents_size.height());
}

// static
ExtensionPopup* ExtensionPopup::Show(
    const GURL& url,
    Browser* browser,
    Profile* profile,
    gfx::NativeWindow frame_window,
    const gfx::Rect& relative_to,
    BubbleBorder::ArrowLocation arrow_location,
    bool activate_on_show,
    bool inspect_with_devtools,
    PopupChrome chrome,
    Observer* observer) {
  DCHECK(profile);
  DCHECK(frame_window);
  ExtensionProcessManager* manager = profile->GetExtensionProcessManager();
  DCHECK(manager);
  if (!manager)
    return NULL;

  // If no Browser instance was given, attempt to look up one matching the given
  // profile.
  if (!browser)
    browser = BrowserList::FindBrowserWithProfile(profile);

  Widget* frame_widget = Widget::GetWidgetFromNativeWindow(frame_window);
  DCHECK(frame_widget);
  if (!frame_widget)
    return NULL;

  ExtensionHost* host = manager->CreatePopup(url, browser);
  if (observer)
    observer->ExtensionHostCreated(host);

  ExtensionPopup* popup = new ExtensionPopup(host, frame_widget, relative_to,
                                             arrow_location, activate_on_show,
                                             inspect_with_devtools, chrome,
                                             observer);

  // If the host had somehow finished loading, then we'd miss the notification
  // and not show.  This seems to happen in single-process mode.
  if (host->did_stop_loading())
    popup->Show(activate_on_show);

  return popup;
}

void ExtensionPopup::Close() {
  if (closing_)
    return;
  closing_ = true;
  DetachFromBrowser();

  if (observer_)
    observer_->ExtensionPopupIsClosing(this);

  Release();  // Balanced in ctor.
}

void ExtensionPopup::Release() {
  bool final_release = instance_lifetime_->HasOneRef();
  instance_lifetime_->Release();
  if (final_release) {
    DCHECK(closing_) << "ExtensionPopup to be destroyed before being closed.";
    ExtensionPopup::Observer* observer = observer_;
    delete this;

    // |this| is passed only as a 'cookie'. The observer API explicitly takes a
    // void* argument to emphasize this.
    if (observer)
      observer->ExtensionPopupClosed(this);
  }
}
<|endoftext|>