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

#include "qmediaplayer.h"

#include "qabstractmediaobject_p.h"
#include "qmediaplayerservice.h"
#include "qmediaplayercontrol.h"
#include "qmediaserviceprovider.h"
#include "qmediaplaylist.h"

/*!
    \class QMediaPlayer
    \ingroup multimedia

    \preliminary
    \brief

    \sa
*/

class QMediaPlayerPrivate : public QAbstractMediaObjectPrivate
{
public:
    QMediaPlayerService* service;
    QMediaPlayerControl* control;
};

/*!
    Construct a QMediaPlayer to operate on the QMediaPlayerService \a service, parented to \a parent.
*/

QMediaPlayer::QMediaPlayer(QMediaPlayerService *service, QObject *parent):
    QAbstractMediaObject(*new QMediaPlayerPrivate, parent)
{
    Q_ASSERT(service != 0);

    Q_D(QMediaPlayer);

    d->service = service;
    d->control = qobject_cast<QMediaPlayerControl *>(service->control("com.nokia.qt.MediaPlayerControl"));
    d->control->setNotifyObject(this);
//    d->control->setNotifyInterval(250);
//    d->control->addPropertyWatch("position");

    connect(d->control, SIGNAL(bufferingChanged(bool)), SIGNAL(bufferingChanged(bool)));
    connect(d->control, SIGNAL(playlistPositionChanged(int)),SIGNAL(playlistPositionChanged(int)));
    connect(d->control, SIGNAL(positionChanged(qint64)), SIGNAL(positionChanged(qint64)));
    connect(d->control, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
    connect(d->control, SIGNAL(videoAvailabilityChanged(bool)), SIGNAL(videoAvailabilityChanged(bool)));
    connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int)));
    connect(d->control, SIGNAL(mutingChanged(bool)), SIGNAL(mutingChanged(bool)));
}

/*!
    Destroys the player object.
*/

QMediaPlayer::~QMediaPlayer()
{
    Q_D(QMediaPlayer);

    delete d->service;
}

QMediaPlayer::State QMediaPlayer::state() const
{
    return QMediaPlayer::State(d_func()->control->state());
}

QMediaPlaylist* QMediaPlayer::mediaPlaylist() const
{
    return d_func()->control->mediaPlaylist();
}

bool QMediaPlayer::setMediaPlaylist(QMediaPlaylist *mediaPlaylist)
{
    return d_func()->control->setMediaPlaylist(mediaPlaylist);
}

int QMediaPlayer::playlistPosition() const
{
    return d_func()->control->playlistPosition();
}

QMediaSource QMediaPlayer::currentMediaSource() const
{
    return mediaPlaylist()->itemAt(playlistPosition());
}

qint64 QMediaPlayer::duration() const
{
    return d_func()->control->duration();
}

qint64 QMediaPlayer::position() const
{
    return d_func()->control->position();
}

int QMediaPlayer::volume() const
{
    return d_func()->control->volume();
}

bool QMediaPlayer::isMuted() const
{
    return d_func()->control->isMuted();
}

bool QMediaPlayer::isBuffering() const
{
    return d_func()->control->isBuffering();
}

int QMediaPlayer::bufferStatus() const
{
    return d_func()->control->bufferStatus();
}

bool QMediaPlayer::isVideoAvailable() const
{
    return d_func()->control->isVideoAvailable();
}

/*!
    Returns the session object being controlled by this Player.
*/

QAbstractMediaService* QMediaPlayer::service() const
{
    return d_func()->service;
}

//public Q_SLOTS:
/*!
    Start or resume playing the current source.
*/

void QMediaPlayer::play()
{
    d_func()->control->play();
}

/*!
    Pause playing the current source.
*/

void QMediaPlayer::pause()
{
    d_func()->control->pause();
}

/*!
    Stop playing, and reset the play position to the beginning.
*/

void QMediaPlayer::stop()
{
    d_func()->control->stop();
}

/*!
    Set the current play position to \a position, relative to the beginning.
    This method is not guaranteed to be synchronous.
*/

void QMediaPlayer::setPosition(qint64 position)
{
    d_func()->control->setPosition(position);
}

/*!
    Set the current volume [ 0 - 100 ] to  \a volume.
    This method is not guaranteed to be synchronous.
*/

void QMediaPlayer::setVolume(int volume)
{
    d_func()->control->setVolume(volume);
}

/*!
    Set the mute state of the playback folume to \a muted. True to mute the
    playback volume, false to unmute.  This method is not guaranteed to be
    synchronous.
*/

void QMediaPlayer::setMuted(bool muted)
{
    d_func()->control->setMuted(muted);
}

/*!
    Advance to the next media source in playlist.
*/

void QMediaPlayer::advance()
{
    d_func()->control->advance();
}

/*!
    Return to the previous media source in playlist.
*/

void QMediaPlayer::back()
{
    d_func()->control->back();
}

/*!
    Activate media source from playlist at position \a playlistPosition.
*/

void QMediaPlayer::setPlaylistPosition(int playlistPosition)
{
    d_func()->control->setPlaylistPosition(playlistPosition);
}

QMediaPlayerService* createMediaPlayerService(QMediaServiceProvider *provider)
{
    QObject *object = provider ? provider->createObject("com.nokia.qt.MediaPlayer/1.0") : 0;

    if (object != 0) {
        QMediaPlayerService *service = qobject_cast<QMediaPlayerService*>(object);

        if (service != 0)
            return service;

        delete service;
    }

    return 0;
}

/*!
    \enum QMediaPlayer::State

    Defines the current state of the player object.

    \value LoadingState The player object is loading necessary data or libraries to play the content.
    \value PlayingState The player object is currently playing the content.
    \value PausedState The player object has paused playing the content, position information is, as necessary,
                        retained.
    \value StoppedState The player object has stopped playing the content, with
                        stop being requested by the stop() function, position information is retained but will
                        be reset on next call to play()
    \value SeekingState The player object is currently performing a seek operation.
    \value EndOfStreamState The player object has stopped playing the content
                            as the content has reached a natural end.
    \value ErrorState   The player object is currently in an error condition.
*/

/*!
    \property QMediaPlayer::mediaPlaylist
    \brief The QMediaPlaylist being used for playback.
*/

/*!
    \property QMediaPlayer::mediaSource
    \brief The active QMediaSource.

    \sa playlistPosition()
*/

/*!
    \property QMediaPlayer::playlistPosition
    \brief The position of the current playing item in the playlist.
*/

/*!
    \property QMediaPlayer::duration
    \brief The total playback time in milliseconds of the current source.
*/

/*!
    \property QMediaPlayer::position
    \brief The current playback position in milliseconds from the beginning.
*/

/*!
    \property QMediaPlayer::volume
    \brief The current playback volume. Volume is a linear effect from 0-100.
*/

/*!
    \property QMediaPlayer::muted
    \brief true if the playback volume is muted; otherwise false.
*/

/*!
    \property QMediaPlayer::buffering
    \brief true if the source is being buffered; otherwise false.
*/

/*!
    \property QMediaPlayer::bufferStatus
    \brief When buffering; returns the percent of the local buffer filled.
*/

/*!
    \property QMediaPlayer::videoAvailable
    \brief true if there is visual content available; otherwise false.
*/

/*!
    \property QMediaPlayer::state
    \brief the State of the Player object.
*/

/*!
    \fn void QMediaPlayer::durationChanged(qint64 duration)

    Signal the duration of the content has changed to \a duration, expressed in milliseconds.
*/

/*!
    \fn void QMediaPlayer::positionChanged(qint64 position)

    Signal the position of the content has changed to \a position, expressed in
    milliseconds approximately every 1000milliseconds.
*/

/*!
    \fn void QMediaPlayer::playlistPositionChanged(int playlistPosition)

    Signal the current playing item as being changes to the item at index \a
    playlistPosition, in the players QMediaPlaylist.

    \sa playlistPosition(), setPlaylistPosition()
*/

/*!
    \fn void QMediaPlayer::currentMediaSourceChanged(const QMediaSource &currentSource)

    Signal that \a currentSource is the now active QMediaSource.

    \sa playlistPositionChanged()
*/

/*!
    \fn void QMediaPlayer::stateChanged(State newState)

    Signal the state of the Player object has changed to \a newState.
*/

/*!
    \fn void QMediaPlayer::volumeChanged(int volume)

    Signal the playback volume has changed to \a volume.
*/

/*!
    \fn void QMediaPlayer::mutingChanged(bool muted)

    Signal the mute state has changed to \a muted.
*/

/*!
    \fn void QMediaPlayer::videoAvailabilityChanged(bool videoAvailable)

    Signal the availability of visual cntent has changed to \a videoAvailable.
*/

/*!
    \fn void QMediaPlayer::bufferingChanged(bool buffering)

    Signal the state of buffering has changed to \a buffering. When true some
    amount of the content is being buffered locally; when false local buffering
    has stopped.
*/

/*!
    \fn void QMediaPlayer::bufferStatusChanged(int percentFilled)

    Signal the amount of the local buffer filled as a percentage by \a percentFilled.
*/

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

#include "qmediaplayer.h"

#include "qabstractmediaobject_p.h"
#include "qmediaplayerservice.h"
#include "qmediaplayercontrol.h"
#include "qmediaserviceprovider.h"
#include "qmediaplaylist.h"

/*!
    \class QMediaPlayer
    \ingroup multimedia

    \preliminary
    \brief

    \sa
*/

class QMediaPlayerPrivate : public QAbstractMediaObjectPrivate
{
public:
    QMediaPlayerService* service;
    QMediaPlayerControl* control;
};

/*!
    Construct a QMediaPlayer to operate on the QMediaPlayerService \a service, parented to \a parent.
*/

QMediaPlayer::QMediaPlayer(QMediaPlayerService *service, QObject *parent):
    QAbstractMediaObject(*new QMediaPlayerPrivate, parent)
{
    Q_ASSERT(service != 0);

    Q_D(QMediaPlayer);

    d->service = service;
    d->control = qobject_cast<QMediaPlayerControl *>(service->control("com.nokia.qt.MediaPlayerControl"));
    d->control->setNotifyObject(this);
//    d->control->setNotifyInterval(250);
//    d->control->addPropertyWatch("position");

    connect(d->control, SIGNAL(bufferingChanged(bool)), SIGNAL(bufferingChanged(bool)));
    connect(d->control, SIGNAL(playlistPositionChanged(int)),SIGNAL(playlistPositionChanged(int)));
    connect(d->control, SIGNAL(positionChanged(qint64)), SIGNAL(positionChanged(qint64)));
    connect(d->control, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
    connect(d->control, SIGNAL(videoAvailabilityChanged(bool)), SIGNAL(videoAvailabilityChanged(bool)));
    connect(d->control, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged(int)));
    connect(d->control, SIGNAL(mutingChanged(bool)), SIGNAL(mutingChanged(bool)));
}

/*!
    Destroys the player object.
*/

QMediaPlayer::~QMediaPlayer()
{
    Q_D(QMediaPlayer);

    delete d->service;
}

/*!
  Returns playback state.
*/
QMediaPlayer::State QMediaPlayer::state() const
{
    return QMediaPlayer::State(d_func()->control->state());
}

/*!
  Returns the playlist used by this media player.
*/
QMediaPlaylist* QMediaPlayer::mediaPlaylist() const
{
    return d_func()->control->mediaPlaylist();
}

/*!
  Set the playlist of this media player to \a mediaPlaylist.

  In many cases it is possible just to use the playlist
  constructed by player, but sometimes replacing the whole
  playlist allows to avoid copyting of all the items bettween playlists.

  Returns true if player can use this passed playlist; otherwise returns false.
*/
bool QMediaPlayer::setMediaPlaylist(QMediaPlaylist *mediaPlaylist)
{
    return d_func()->control->setMediaPlaylist(mediaPlaylist);
}

/*!
  Returns position of the current media source in the playlist.
*/
int QMediaPlayer::playlistPosition() const
{
    return d_func()->control->playlistPosition();
}

/*!
  Returns the current media source.
*/
QMediaSource QMediaPlayer::currentMediaSource() const
{
    return mediaPlaylist()->itemAt(playlistPosition());
}

/*!
  Returns duration of currently played source in miliseconds.
*/
qint64 QMediaPlayer::duration() const
{
    return d_func()->control->duration();
}

/*!
  Returns position in miliseconds the current source plays at.
*/
qint64 QMediaPlayer::position() const
{
    return d_func()->control->position();
}

/*!
  Returns playback volume, in range 0..100.
*/
int QMediaPlayer::volume() const
{
    return d_func()->control->volume();
}

/*!
  Returns true is audio is muted; otherwise returns false.
*/
bool QMediaPlayer::isMuted() const
{
    return d_func()->control->isMuted();
}

/*!
  Returns true if the media player is currently buffering the input data.
*/
bool QMediaPlayer::isBuffering() const
{
    return d_func()->control->isBuffering();
}

/*!
  Returns how much the buffer is filled in percent.
*/
int QMediaPlayer::bufferStatus() const
{
    return d_func()->control->bufferStatus();
}

/*!
  Returns true if the current media contains video data; otherwise, returns false.
*/
bool QMediaPlayer::isVideoAvailable() const
{
    return d_func()->control->isVideoAvailable();
}

/*!
    Returns the session object being controlled by this Player.
*/

QAbstractMediaService* QMediaPlayer::service() const
{
    return d_func()->service;
}

//public Q_SLOTS:
/*!
    Start or resume playing the current source.
*/
void QMediaPlayer::play()
{
    d_func()->control->play();
}

/*!
    Pause playing the current source.
*/
void QMediaPlayer::pause()
{
    d_func()->control->pause();
}

/*!
    Stop playing, and reset the play position to the beginning.
*/
void QMediaPlayer::stop()
{
    d_func()->control->stop();
}

/*!
    Set the current play position to \a position, relative to the beginning.
    This method is not guaranteed to be synchronous.
*/
void QMediaPlayer::setPosition(qint64 position)
{
    d_func()->control->setPosition(position);
}

/*!
    Set the current volume [ 0 - 100 ] to  \a volume.
    This method is not guaranteed to be synchronous.
*/
void QMediaPlayer::setVolume(int volume)
{
    d_func()->control->setVolume(volume);
}

/*!
    Set the mute state of the playback folume to \a muted. True to mute the
    playback volume, false to unmute.  This method is not guaranteed to be
    synchronous.
*/
void QMediaPlayer::setMuted(bool muted)
{
    d_func()->control->setMuted(muted);
}

/*!
    Advance to the next media source in playlist.
*/
void QMediaPlayer::advance()
{
    d_func()->control->advance();
}

/*!
    Return to the previous media source in playlist.
*/
void QMediaPlayer::back()
{
    d_func()->control->back();
}

/*!
    Activate media source from playlist at position \a playlistPosition.
*/

void QMediaPlayer::setPlaylistPosition(int playlistPosition)
{
    d_func()->control->setPlaylistPosition(playlistPosition);
}

QMediaPlayerService* createMediaPlayerService(QMediaServiceProvider *provider)
{
    QObject *object = provider ? provider->createObject("com.nokia.qt.MediaPlayer/1.0") : 0;

    if (object != 0) {
        QMediaPlayerService *service = qobject_cast<QMediaPlayerService*>(object);

        if (service != 0)
            return service;

        delete service;
    }

    return 0;
}

/*!
    \enum QMediaPlayer::State

    Defines the current state of the player object.

    \value LoadingState The player object is loading necessary data or libraries to play the content.
    \value PlayingState The player object is currently playing the content.
    \value PausedState The player object has paused playing the content, position information is, as necessary,
                        retained.
    \value StoppedState The player object has stopped playing the content, with
                        stop being requested by the stop() function, position information is retained but will
                        be reset on next call to play()
    \value SeekingState The player object is currently performing a seek operation.
    \value EndOfStreamState The player object has stopped playing the content
                            as the content has reached a natural end.
    \value ErrorState   The player object is currently in an error condition.
*/

/*!
    \property QMediaPlayer::mediaPlaylist
    \brief The QMediaPlaylist being used for playback.
*/

/*!
    \property QMediaPlayer::mediaSource
    \brief The active QMediaSource.

    \sa playlistPosition()
*/

/*!
    \property QMediaPlayer::playlistPosition
    \brief The position of the current playing item in the playlist.
*/

/*!
    \property QMediaPlayer::duration
    \brief The total playback time in milliseconds of the current source.
*/

/*!
    \property QMediaPlayer::position
    \brief The current playback position in milliseconds from the beginning.
*/

/*!
    \property QMediaPlayer::volume
    \brief The current playback volume. Volume is a linear effect from 0-100.
*/

/*!
    \property QMediaPlayer::muted
    \brief true if the playback volume is muted; otherwise false.
*/

/*!
    \property QMediaPlayer::buffering
    \brief true if the source is being buffered; otherwise false.
*/

/*!
    \property QMediaPlayer::bufferStatus
    \brief When buffering; returns the percent of the local buffer filled.
*/

/*!
    \property QMediaPlayer::videoAvailable
    \brief true if there is visual content available; otherwise false.
*/

/*!
    \property QMediaPlayer::state
    \brief the State of the Player object.
*/

/*!
    \fn void QMediaPlayer::durationChanged(qint64 duration)

    Signal the duration of the content has changed to \a duration, expressed in milliseconds.
*/

/*!
    \fn void QMediaPlayer::positionChanged(qint64 position)

    Signal the position of the content has changed to \a position, expressed in
    milliseconds approximately every 1000milliseconds.
*/

/*!
    \fn void QMediaPlayer::playlistPositionChanged(int playlistPosition)

    Signal the current playing item as being changes to the item at index \a
    playlistPosition, in the players QMediaPlaylist.

    \sa playlistPosition(), setPlaylistPosition()
*/

/*!
    \fn void QMediaPlayer::currentMediaSourceChanged(const QMediaSource &currentSource)

    Signal that \a currentSource is the now active QMediaSource.

    \sa playlistPositionChanged()
*/

/*!
    \fn void QMediaPlayer::stateChanged(State newState)

    Signal the state of the Player object has changed to \a newState.
*/

/*!
    \fn void QMediaPlayer::volumeChanged(int volume)

    Signal the playback volume has changed to \a volume.
*/

/*!
    \fn void QMediaPlayer::mutingChanged(bool muted)

    Signal the mute state has changed to \a muted.
*/

/*!
    \fn void QMediaPlayer::videoAvailabilityChanged(bool videoAvailable)

    Signal the availability of visual cntent has changed to \a videoAvailable.
*/

/*!
    \fn void QMediaPlayer::bufferingChanged(bool buffering)

    Signal the state of buffering has changed to \a buffering. When true some
    amount of the content is being buffered locally; when false local buffering
    has stopped.
*/

/*!
    \fn void QMediaPlayer::bufferStatusChanged(int percentFilled)

    Signal the amount of the local buffer filled as a percentage by \a percentFilled.
*/

<|endoftext|>


<commit_before>// Copyright (c) 2010 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/chromeos/cros_settings_provider_user.h"

#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/chromeos/cros_settings_names.h"

namespace chromeos {

UserCrosSettingsProvider::UserCrosSettingsProvider()
    : dict_(new DictionaryValue) {
  Set(kAccountsPrefAllowBWSI, Value::CreateBooleanValue(true));
  Set(kAccountsPrefAllowGuest, Value::CreateBooleanValue(true));
  Set(kAccountsPrefShowUserNamesOnSignIn, Value::CreateBooleanValue(true));

  ListValue* user_list = new ListValue;

  DictionaryValue* mock_user = new DictionaryValue;
  mock_user->SetString(L"email", L"mock_user_1@gmail.com");
  mock_user->SetString(L"name", L"Mock User One");
  mock_user->SetBoolean(L"owner", true);
  user_list->Append(mock_user);

  mock_user = new DictionaryValue;
  mock_user->SetString(L"email", L"mock_user_2@gmail.com");
  mock_user->SetString(L"name", L"Mock User Two");
  mock_user->SetBoolean(L"owner", false);
  user_list->Append(mock_user);

  Set(kAccountsPrefUsers, user_list);
}

void UserCrosSettingsProvider::Set(const std::string& path, Value* in_value) {
  dict_->Set(path, in_value);
}

bool UserCrosSettingsProvider::Get(const std::string& path,
                                   Value** out_value) const {
  return dict_->Get(path, out_value);
}

bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) {
  return ::StartsWithASCII(path, "cros.accounts", true);
}

}  // namespace chromeos
<commit_msg>Remove a few more wide strings from Chrome OS.<commit_after>// Copyright (c) 2010 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/chromeos/cros_settings_provider_user.h"

#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/chromeos/cros_settings_names.h"

namespace chromeos {

UserCrosSettingsProvider::UserCrosSettingsProvider()
    : dict_(new DictionaryValue) {
  Set(kAccountsPrefAllowBWSI, Value::CreateBooleanValue(true));
  Set(kAccountsPrefAllowGuest, Value::CreateBooleanValue(true));
  Set(kAccountsPrefShowUserNamesOnSignIn, Value::CreateBooleanValue(true));

  ListValue* user_list = new ListValue;

  DictionaryValue* mock_user = new DictionaryValue;
  mock_user->SetString("email", "mock_user_1@gmail.com");
  mock_user->SetString("name", "Mock User One");
  mock_user->SetBoolean("owner", true);
  user_list->Append(mock_user);

  mock_user = new DictionaryValue;
  mock_user->SetString("email", "mock_user_2@gmail.com");
  mock_user->SetString("name", "Mock User Two");
  mock_user->SetBoolean("owner", false);
  user_list->Append(mock_user);

  Set(kAccountsPrefUsers, user_list);
}

void UserCrosSettingsProvider::Set(const std::string& path, Value* in_value) {
  dict_->Set(path, in_value);
}

bool UserCrosSettingsProvider::Get(const std::string& path,
                                   Value** out_value) const {
  return dict_->Get(path, out_value);
}

bool UserCrosSettingsProvider::HandlesSetting(const std::string& path) {
  return ::StartsWithASCII(path, "cros.accounts", true);
}

}  // namespace chromeos
<|endoftext|>


<commit_before>// Copyright (c) 2010 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/sync/glue/extension_change_processor.h"

#include <sstream>
#include <string>

#include "base/logging.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/extension_model_associator.h"
#include "chrome/browser/sync/glue/extension_util.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"

typedef sync_api::SyncManager::ExtraExtensionChangeRecordData
    ExtraExtensionChangeRecordData;

namespace browser_sync {

ExtensionChangeProcessor::ExtensionChangeProcessor(
    UnrecoverableErrorHandler* error_handler,
    ExtensionModelAssociator* extension_model_associator)
    : ChangeProcessor(error_handler),
      extension_model_associator_(extension_model_associator),
      profile_(NULL) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(error_handler);
  DCHECK(extension_model_associator_);
}

ExtensionChangeProcessor::~ExtensionChangeProcessor() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
}

// TODO(akalin): We need to make sure events we receive from either
// the browser or the syncapi are done in order; this is tricky since
// some events (e.g., extension installation) are done asynchronously.

void ExtensionChangeProcessor::Observe(NotificationType type,
                                       const NotificationSource& source,
                                       const NotificationDetails& details) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(running());
  DCHECK(profile_);
  switch (type.value) {
    case NotificationType::EXTENSION_LOADED:
    case NotificationType::EXTENSION_UNLOADED: {
      DCHECK_EQ(Source<Profile>(source).ptr(), profile_);
      Extension* extension = Details<Extension>(details).ptr();
      CHECK(extension);
      if (!IsExtensionSyncable(*extension)) {
        return;
      }
      const std::string& id = extension->id();
      LOG(INFO) << "Got change notification of type " << type.value
                << " for extension " << id;
      if (!extension_model_associator_->OnClientUpdate(id)) {
        std::string error = std::string("Client update failed for ") + id;
        error_handler()->OnUnrecoverableError(FROM_HERE, error);
        return;
      }
      break;
    }
    default:
      LOG(DFATAL) << "Received unexpected notification of type "
                  << type.value;
      break;
  }
}

void ExtensionChangeProcessor::ApplyChangesFromSyncModel(
    const sync_api::BaseTransaction* trans,
    const sync_api::SyncManager::ChangeRecord* changes,
    int change_count) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  if (!running()) {
    return;
  }
  for (int i = 0; i < change_count; ++i) {
    const sync_api::SyncManager::ChangeRecord& change = changes[i];
    switch (change.action) {
      case sync_api::SyncManager::ChangeRecord::ACTION_ADD:
      case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
        sync_api::ReadNode node(trans);
        if (!node.InitByIdLookup(change.id)) {
          std::stringstream error;
          error << "Extension node lookup failed for change " << change.id
                << " of action type " << change.action;
          error_handler()->OnUnrecoverableError(FROM_HERE, error.str());
          return;
        }
        DCHECK_EQ(node.GetModelType(), syncable::EXTENSIONS);
        const sync_pb::ExtensionSpecifics& specifics =
            node.GetExtensionSpecifics();
        if (!IsExtensionSpecificsValid(specifics)) {
          std::string error =
              std::string("Invalid server specifics: ") +
              ExtensionSpecificsToString(specifics);
          error_handler()->OnUnrecoverableError(FROM_HERE, error);
          return;
        }
        StopObserving();
        extension_model_associator_->OnServerUpdate(specifics);
        StartObserving();
        break;
      }
      case sync_api::SyncManager::ChangeRecord::ACTION_DELETE: {
        StopObserving();
        scoped_ptr<ExtraExtensionChangeRecordData>
            data(static_cast<ExtraExtensionChangeRecordData*>(change.extra));
        if (data.get()) {
          extension_model_associator_->OnServerRemove(data->extension_id);
        } else {
          std::stringstream error;
          error << "Could not get extension ID for deleted node "
                << change.id;
          error_handler()->OnUnrecoverableError(FROM_HERE, error.str());
          LOG(DFATAL) << error.str();
        }
        StartObserving();
        break;
      }
    }
  }
}

void ExtensionChangeProcessor::StartImpl(Profile* profile) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(profile);
  profile_ = profile;
  StartObserving();
}

void ExtensionChangeProcessor::StopImpl() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  StopObserving();
  profile_ = NULL;
}

void ExtensionChangeProcessor::StartObserving() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(profile_);
  LOG(INFO) << "Observing EXTENSION_LOADED and EXTENSION_UNLOADED";
  // TODO(akalin): We miss notifications when we uninstall a disabled
  // extension since EXTENSION_UNLOADED isn't sent in that case.  Add
  // an EXTENSION_UNINSTALLED notification and listen to it.
  notification_registrar_.Add(
      this, NotificationType::EXTENSION_LOADED,
      Source<Profile>(profile_));
  notification_registrar_.Add(
      this, NotificationType::EXTENSION_UNLOADED,
      Source<Profile>(profile_));
}

void ExtensionChangeProcessor::StopObserving() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(profile_);
  LOG(INFO) << "Unobserving all notifications";
  notification_registrar_.RemoveAll();
}

}  // namespace browser_sync
<commit_msg>Make extension sync change processor listen to events for disabled extensions.<commit_after>// Copyright (c) 2010 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/sync/glue/extension_change_processor.h"

#include <sstream>
#include <string>

#include "base/logging.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/glue/extension_model_associator.h"
#include "chrome/browser/sync/glue/extension_util.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"

typedef sync_api::SyncManager::ExtraExtensionChangeRecordData
    ExtraExtensionChangeRecordData;

namespace browser_sync {

ExtensionChangeProcessor::ExtensionChangeProcessor(
    UnrecoverableErrorHandler* error_handler,
    ExtensionModelAssociator* extension_model_associator)
    : ChangeProcessor(error_handler),
      extension_model_associator_(extension_model_associator),
      profile_(NULL) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(error_handler);
  DCHECK(extension_model_associator_);
}

ExtensionChangeProcessor::~ExtensionChangeProcessor() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
}

// TODO(akalin): We need to make sure events we receive from either
// the browser or the syncapi are done in order; this is tricky since
// some events (e.g., extension installation) are done asynchronously.

void ExtensionChangeProcessor::Observe(NotificationType type,
                                       const NotificationSource& source,
                                       const NotificationDetails& details) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(running());
  DCHECK(profile_);
  switch (type.value) {
    case NotificationType::EXTENSION_LOADED:
    case NotificationType::EXTENSION_UPDATE_DISABLED:
    case NotificationType::EXTENSION_UNLOADED:
    case NotificationType::EXTENSION_UNLOADED_DISABLED: {
      DCHECK_EQ(Source<Profile>(source).ptr(), profile_);
      Extension* extension = Details<Extension>(details).ptr();
      CHECK(extension);
      if (!IsExtensionSyncable(*extension)) {
        return;
      }
      const std::string& id = extension->id();
      LOG(INFO) << "Got change notification of type " << type.value
                << " for extension " << id;
      if (!extension_model_associator_->OnClientUpdate(id)) {
        std::string error = std::string("Client update failed for ") + id;
        error_handler()->OnUnrecoverableError(FROM_HERE, error);
        return;
      }
      break;
    }
    default:
      LOG(DFATAL) << "Received unexpected notification of type "
                  << type.value;
      break;
  }
}

void ExtensionChangeProcessor::ApplyChangesFromSyncModel(
    const sync_api::BaseTransaction* trans,
    const sync_api::SyncManager::ChangeRecord* changes,
    int change_count) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  if (!running()) {
    return;
  }
  for (int i = 0; i < change_count; ++i) {
    const sync_api::SyncManager::ChangeRecord& change = changes[i];
    switch (change.action) {
      case sync_api::SyncManager::ChangeRecord::ACTION_ADD:
      case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
        sync_api::ReadNode node(trans);
        if (!node.InitByIdLookup(change.id)) {
          std::stringstream error;
          error << "Extension node lookup failed for change " << change.id
                << " of action type " << change.action;
          error_handler()->OnUnrecoverableError(FROM_HERE, error.str());
          return;
        }
        DCHECK_EQ(node.GetModelType(), syncable::EXTENSIONS);
        const sync_pb::ExtensionSpecifics& specifics =
            node.GetExtensionSpecifics();
        if (!IsExtensionSpecificsValid(specifics)) {
          std::string error =
              std::string("Invalid server specifics: ") +
              ExtensionSpecificsToString(specifics);
          error_handler()->OnUnrecoverableError(FROM_HERE, error);
          return;
        }
        StopObserving();
        extension_model_associator_->OnServerUpdate(specifics);
        StartObserving();
        break;
      }
      case sync_api::SyncManager::ChangeRecord::ACTION_DELETE: {
        StopObserving();
        scoped_ptr<ExtraExtensionChangeRecordData>
            data(static_cast<ExtraExtensionChangeRecordData*>(change.extra));
        if (data.get()) {
          extension_model_associator_->OnServerRemove(data->extension_id);
        } else {
          std::stringstream error;
          error << "Could not get extension ID for deleted node "
                << change.id;
          error_handler()->OnUnrecoverableError(FROM_HERE, error.str());
          LOG(DFATAL) << error.str();
        }
        StartObserving();
        break;
      }
    }
  }
}

void ExtensionChangeProcessor::StartImpl(Profile* profile) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(profile);
  profile_ = profile;
  StartObserving();
}

void ExtensionChangeProcessor::StopImpl() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  StopObserving();
  profile_ = NULL;
}

void ExtensionChangeProcessor::StartObserving() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(profile_);
  LOG(INFO) << "Observing EXTENSION_LOADED, EXTENSION_UPDATE_DISABLED, "
            << "EXTENSION_UNLOADED, and EXTENSION_UNLOADED_DISABLED";
  notification_registrar_.Add(
      this, NotificationType::EXTENSION_LOADED,
      Source<Profile>(profile_));
  // Despite the name, this notification is exactly like
  // EXTENSION_LOADED but with an initial state of DISABLED.
  //
  // TODO(akalin): See if the themes change processor needs to listen
  // to any of these, too.
  notification_registrar_.Add(
      this, NotificationType::EXTENSION_UPDATE_DISABLED,
      Source<Profile>(profile_));
  notification_registrar_.Add(
      this, NotificationType::EXTENSION_UNLOADED,
      Source<Profile>(profile_));
  notification_registrar_.Add(
      this, NotificationType::EXTENSION_UNLOADED_DISABLED,
      Source<Profile>(profile_));
}

void ExtensionChangeProcessor::StopObserving() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(profile_);
  LOG(INFO) << "Unobserving all notifications";
  notification_registrar_.RemoveAll();
}

}  // namespace browser_sync
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010, Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "chrome/browser/ui/meegotouch/back_forward_button_qt.h"
#include "chrome/browser/ui/meegotouch/browser_window_qt.h"
#include "chrome/browser/ui/meegotouch/browser_toolbar_qt.h"
#include "base/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "base/string_number_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/navigation_entry.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/base/registry_controlled_domain.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"

#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QVector>
#include <QList>
#include <QTimer>
#include <algorithm>
#include <QGraphicsSceneResizeEvent>
#include <QGraphicsWidget>
#include <QEvent>
#include <QDebug>
//#include <QTapAndHoldGesture>

#include <QDeclarativeEngine>
#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QDeclarativeItem>
#include <QDeclarativeImageProvider>
#include <QAbstractListModel>

// Image provider, managing to provide image to QML
// for history view
// Due to qml limitation, the id of image is suffixed with
// a static increaser, which forces using new image source
// each time
class HistoryImageProvider : public QDeclarativeImageProvider
{
public:
    HistoryImageProvider()
        : QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
    {}

    // clear all images in image hashmap
    void clear()
    {
        imageList_.clear();
    }

    // overrided function, inherited from QDeclarativeImageProvider
    virtual QImage requestImage(const QString& id,
                                QSize* size,
                                const QSize& requestedSize)
    {
        DLOG(INFO) << "requesting image id: " << id.toStdString();
        int finded = id.indexOf("_");
        if (finded != -1) {
            QImage& image = imageList_[id.left(finded)];
            if (!image.isNull()) {
                //QImage scaled = image.scaled(requestedSize);
                *size = image.size();
                return image;
            }
        }
        *size = QSize(0, 0);
        return QImage();
    }

    // add a new image
    void addImage(const QString& id, const QImage &image)
    {
        imageList_.insert(id, image);
    }

private:
    QMap<QString, QImage> imageList_;
};

class HistoryStackModel;

// history entry to represent one history data
class HistoryEntry
{
public:

    // constructor
    // @param index the index in history stack
    // @param hiProvider image provider for history stack
    // @param entry representation of navigation entry in browser
    // @param controller current navigation controller in browser
    // @param model history stack model
    HistoryEntry(const int index,
                 HistoryImageProvider& hiProvider,
                 NavigationEntry* entry,
                 NavigationController* controller,
                 HistoryStackModel* model)
        : index_(index), hiProvider_(hiProvider), entry_(entry), model_(model)
    {
        // get image
        getThumbnailData(controller);
        std::wstring title_str = UTF16ToWide(entry->title());
        title_ = QString::fromStdWString(title_str);
    }

    void imgURLGen()
    {
        static QString prefix("image://historystack/");
        imageSrc_ = prefix + QString::number(index_) + "_" + QString::number(reloadNumber_);
    }

    void getThumbnailData(NavigationController *controller);

    NavigationEntry* entry() { return entry_; }
    QString image() { return imageSrc_; }
    QString title() { return title_; }

    static void incReloadNumber() { reloadNumber_++; }
    static unsigned long reloadNumber() { return reloadNumber_; }

private:
    // static increaser to generate unique image source
    static unsigned long reloadNumber_;

    int index_;
    HistoryImageProvider& hiProvider_;
    NavigationEntry* entry_;
    HistoryStackModel* model_;
    // image source
    QString imageSrc_;
    // history title
    QString title_;
    CancelableRequestConsumer consumer_;
};

unsigned long HistoryEntry::reloadNumber_ = 0;

// represent list model used in QML to store history data
class HistoryStackModel: public QAbstractListModel
{
    Q_OBJECT
    enum HistoryRole {
        IMAGE_ROLE = Qt::UserRole + 1,
        TITLE_ROLE
    };

public:
    HistoryStackModel(BackForwardButtonQtImpl* backForward)
        : back_forward_(backForward), returnedImages_(0)
    {
        QHash<int, QByteArray> roles;
        roles[IMAGE_ROLE] = "thumbSrc";
        roles[TITLE_ROLE] = "title";
        setRoleNames(roles);
    }

    ~HistoryStackModel()
    {
        clear();
    }

    // clear saved data
    void clear()
    {
        returnedImages_ = 0;
        beginResetModel();
        for(int i = 0; i < entryList_.count(); i++) {
            delete entryList_[i];
        }
        entryList_.clear();
        hiProvider_.clear();
        endResetModel();
    }

    int rowCount(const QModelIndex& parent = QModelIndex()) const
    {
        return entryList_.count();
    }

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
    {
        DLOG(INFO) << "read list model data: row = " << index.row() << ", column = " << index.column();
        if(index.row() < 0 || index.row() > entryList_.count())
            return QVariant();
        HistoryEntry* entry = entryList_[index.row()];
        switch(role) {
            case IMAGE_ROLE:
                return entry->image();
            case TITLE_ROLE:
                return entry->title();
            default:
                return QVariant();
        }
    }

    void appendEntry(NavigationController* controller, NavigationEntry *entry)
    {
        HistoryEntry* historyEntry
                                = new HistoryEntry(entryList_.count(),
                                                   hiProvider_,
                                                   entry,
                                                   controller,
                                                   this);
        historyEntry->imgURLGen();
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        entryList_.push_back(historyEntry);
        endInsertRows();
    }

    // emit a showHistory signal to QML
    void show() { emit showHistory(); }

    // emit a hideHistory signal to QML
    void hide() { emit hideHistory(); }

    // emit a current selected(focused) history entry
    void setCurrent(int index) { emit current(index); }

    HistoryImageProvider* hiProvider() { return &hiProvider_; }

Q_SIGNALS:
    // three signals used to notify QML
    void showHistory();
    void hideHistory();
    void current(int index);

public Q_SLOTS:
    // open specific page, called by QML element
    // It's called by QML element when user clicks one history entry in QML view
    void openPage(const int index);

private:
    BackForwardButtonQtImpl* back_forward_;
    // list to hold entries
    QList<HistoryEntry*> entryList_;
    HistoryImageProvider hiProvider_;
    // count of returned images from browser
    int returnedImages_;
};

class BackForwardButtonQtImpl
{
public:
    enum NaviState {
        ONLY_BACK = 0,
        ONLY_FORWARD,
        BACK_FORWARD
    };

    // constructor
    BackForwardButtonQtImpl(BrowserToolbarQt* toolbar, Browser* browser, BrowserWindowQt* window)
        :toolbar_(toolbar), browser_(browser), model_(this),
        state_(ONLY_BACK), active_(false)
    {
        QDeclarativeView* view = window->DeclarativeView();
        QDeclarativeContext *context = view->rootContext();
        context->setContextProperty("historyStackModel", &model_);
        context->engine()->addImageProvider(QLatin1String("historystack"), model_.hiProvider());
    }

    NavigationController* currentController()
    {
        return &(browser_->GetSelectedTabContents()->controller());
    }

    void openPage(NavigationEntry *entry)
    {
        currentController()->GoToIndex(currentController()->GetIndexOfEntry(entry));
        updateStatus();
    }

    void updateStatus()
    {
        if(currentController()->GetCurrentEntryIndex() == currentController()->entry_count() - 1)
        {
            state_ = ONLY_BACK;
            if (currentController()->entry_count() > 1) {
                active_ = true;
            } else {
                active_ = false;
            }
        } else if (currentController()->GetCurrentEntryIndex() == 0
                   && currentController()->entry_count() > 0) {
            state_ = ONLY_FORWARD;
        } else if (currentController()->CanGoBack() && currentController()->CanGoForward()) {
            state_ = BACK_FORWARD;
        } else {
            state_ = ONLY_BACK;
            active_ = false;
        }
        // update button status in qml
        updateButton();
        DLOG(INFO) << "In C++, updateStatus is invoked\n";
    }

    // update back-forward button icon
    void updateButton() { toolbar_->updateBfButton((int)state_, active_); }

    void tap()
    {
        DLOG(INFO) << "In C++, tap is invoked";
        switch(state_) {
        case ONLY_BACK:
            if (currentController()->CanGoBack()) {
                currentController()->GoBack();
            }
            break;
        case ONLY_FORWARD:
            if (currentController()->entry_count() == 2) {
                if (currentController()->CanGoForward()) {
                    currentController()->GoForward();
                }
            } else {
                prepareAndShowHistory();
            }
            break;
        case BACK_FORWARD:
            prepareAndShowHistory();
            break;
        default:
            break;
        }
    }

    void tapAndHold()
    {
        switch(state_) {
        case ONLY_BACK:
            prepareAndShowHistory();
            break;
        case ONLY_FORWARD:
            if (currentController()->entry_count() == 2) {
                if (currentController()->CanGoForward()) {
                    currentController()->GoForward();
                }
            } else {
                prepareAndShowHistory();
            }
            break;
        case BACK_FORWARD:
                prepareAndShowHistory();
            break;
        default:
            break;
        }
        updateStatus();
    }

    //prepare c++ list model and emit signal to QML to show it
    void prepareAndShowHistory()
    {
        model_.clear();
        int count = currentController()->entry_count();
        int curr = -1;
        HistoryEntry::incReloadNumber();
        for(int i = count - 1; i >= 0; i--)
        {
            DLOG(INFO) << "page index: ---" << i << "---\n";
            NavigationEntry* navEntry = currentController()->GetEntryAtIndex(i);
            // don't skip 'newtab' now, if yes, we do not only skip newtab here
            // but also skip count calculation for 'updateStatus'
            /*
            if (navEntry->url().HostNoBrackets() == "newtab") {
                // skip 'newtab'
                continue;
            }*/
            model_.appendEntry(currentController(), navEntry);
            curr++;
            if(currentController()->GetCurrentEntryIndex() == i) {
                model_.setCurrent(curr);
            }
        }
        model_.show();
        toolbar_->showHistory();
    }

private:
    BrowserToolbarQt* toolbar_;
    Browser* browser_;
    HistoryStackModel model_;

    // current navigation state
    NaviState state_;
    // whether the backward/forward button is active
    bool active_;
};

BackForwardButtonQt::BackForwardButtonQt(BrowserToolbarQt* toolbar, Browser* browser, BrowserWindowQt* window)
{
  impl_ = new BackForwardButtonQtImpl(toolbar, browser, window);
}

BackForwardButtonQt::~BackForwardButtonQt()
{
  delete impl_;
}

void BackForwardButtonQt::tap()
{
  impl_->tap();
}

void BackForwardButtonQt::tapAndHold()
{
  impl_->tapAndHold();
}

void BackForwardButtonQt::updateStatus()
{
  impl_->updateStatus();
}

void HistoryEntry::getThumbnailData(NavigationController *controller)
{
  history::TopSites* ts = controller->profile()->GetTopSites();
  if (ts) {
    scoped_refptr<RefCountedBytes> thumbnail_data;
    ts->GetPageThumbnail(entry_->url(), &thumbnail_data);
    if (thumbnail_data.get()) {
      std::vector <unsigned char> jpeg;
      std::copy(thumbnail_data->data.begin(),
                thumbnail_data->data.end(),
                std::back_inserter(jpeg));
      QImage image = QImage::fromData(jpeg.data(), jpeg.size());
      DLOG(INFO) << "image size ===== " << jpeg.size();
      hiProvider_.addImage(QString::number(index_), image);
    }
  }
}

void HistoryStackModel::openPage(const int index)
{
    back_forward_->openPage(entryList_[index]->entry());
    hide();
}

#include "moc_back_forward_button_qt.cc"
<commit_msg>History: also keep previous implementation for backward compatibility<commit_after>/*
 * Copyright (c) 2010, Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "chrome/browser/ui/meegotouch/back_forward_button_qt.h"
#include "chrome/browser/ui/meegotouch/browser_window_qt.h"
#include "chrome/browser/ui/meegotouch/browser_toolbar_qt.h"
#include "base/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "base/string_number_conversions.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/navigation_entry.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/base/registry_controlled_domain.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"

#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QVector>
#include <QList>
#include <QTimer>
#include <algorithm>
#include <QGraphicsSceneResizeEvent>
#include <QGraphicsWidget>
#include <QEvent>
#include <QDebug>
//#include <QTapAndHoldGesture>

#include <QDeclarativeEngine>
#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QDeclarativeItem>
#include <QDeclarativeImageProvider>
#include <QAbstractListModel>

// Image provider, managing to provide image to QML
// for history view
// Due to qml limitation, the id of image is suffixed with
// a static increaser, which forces using new image source
// each time
class HistoryImageProvider : public QDeclarativeImageProvider
{
public:
    HistoryImageProvider()
        : QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
    {}

    // clear all images in image hashmap
    void clear()
    {
        imageList_.clear();
    }

    // overrided function, inherited from QDeclarativeImageProvider
    virtual QImage requestImage(const QString& id,
                                QSize* size,
                                const QSize& requestedSize)
    {
        DLOG(INFO) << "requesting image id: " << id.toStdString();
        int finded = id.indexOf("_");
        if (finded != -1) {
            QImage& image = imageList_[id.left(finded)];
            if (!image.isNull()) {
                //QImage scaled = image.scaled(requestedSize);
                *size = image.size();
                return image;
            }
        }
        *size = QSize(0, 0);
        return QImage();
    }

    // add a new image
    void addImage(const QString& id, const QImage &image)
    {
        imageList_.insert(id, image);
    }

private:
    QMap<QString, QImage> imageList_;
};

class HistoryStackModel;

// history entry to represent one history data
class HistoryEntry
{
public:

    // constructor
    // @param index the index in history stack
    // @param hiProvider image provider for history stack
    // @param entry representation of navigation entry in browser
    // @param controller current navigation controller in browser
    // @param model history stack model
    HistoryEntry(const int index,
                 HistoryImageProvider& hiProvider,
                 NavigationEntry* entry,
                 NavigationController* controller,
                 HistoryStackModel* model)
        : index_(index), hiProvider_(hiProvider), entry_(entry), model_(model)
    {
        // get image
        getThumbnailData(controller);
        std::wstring title_str = UTF16ToWide(entry->title());
        title_ = QString::fromStdWString(title_str);
    }

    void imgURLGen()
    {
        static QString prefix("image://historystack/");
        imageSrc_ = prefix + QString::number(index_) + "_" + QString::number(reloadNumber_);
    }

    // get thumbnail
    void getThumbnailData(NavigationController *controller);

    // callback to get the image data from browser
    void onThumbnailDataAvailable(HistoryService::Handle request_handle,
                                  scoped_refptr<RefCountedBytes> jpeg_data);

    NavigationEntry* entry() { return entry_; }
    QString image() { return imageSrc_; }
    QString title() { return title_; }

    static void incReloadNumber() { reloadNumber_++; }
    static unsigned long reloadNumber() { return reloadNumber_; }

private:
    // static increaser to generate unique image source
    static unsigned long reloadNumber_;

    int index_;
    HistoryImageProvider& hiProvider_;
    NavigationEntry* entry_;
    HistoryStackModel* model_;
    // image source
    QString imageSrc_;
    // history title
    QString title_;
    CancelableRequestConsumer consumer_;
};

unsigned long HistoryEntry::reloadNumber_ = 0;

// represent list model used in QML to store history data
class HistoryStackModel: public QAbstractListModel
{
    Q_OBJECT
    enum HistoryRole {
        IMAGE_ROLE = Qt::UserRole + 1,
        TITLE_ROLE
    };

public:
    HistoryStackModel(BackForwardButtonQtImpl* backForward)
        : back_forward_(backForward), returnedImages_(0)
    {
        QHash<int, QByteArray> roles;
        roles[IMAGE_ROLE] = "thumbSrc";
        roles[TITLE_ROLE] = "title";
        setRoleNames(roles);
    }

    ~HistoryStackModel()
    {
        clear();
    }

    // clear saved data
    void clear()
    {
        returnedImages_ = 0;
        beginResetModel();
        for(int i = 0; i < entryList_.count(); i++) {
            delete entryList_[i];
        }
        entryList_.clear();
        hiProvider_.clear();
        endResetModel();
    }

    // wrapper to check whether browser returns all images of history
    // so we can reset model to avoid resetting model many times
    void beginReset()
    {
        // begin reset if necessary
        returnedImages_++;
        if (returnedImages_ == rowCount()) {
            DLOG(INFO) << "begin reset history stack model";
            // generate new number to create new image url
            HistoryEntry::incReloadNumber();
            for(int i = 0; i < entryList_.count(); i++) {
                HistoryEntry* entry = entryList_[i];
                entry->imgURLGen();
            }
            beginResetModel();
        }
    }

    void endReset()
    {
        // end reset if necessary
        if (returnedImages_ == rowCount()) {
            DLOG(INFO) << "end reset history stack model";
            endResetModel();
        }
    }

    int rowCount(const QModelIndex& parent = QModelIndex()) const
    {
        return entryList_.count();
    }

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
    {
        DLOG(INFO) << "read list model data: row = " << index.row() << ", column = " << index.column();
        if(index.row() < 0 || index.row() > entryList_.count())
            return QVariant();
        HistoryEntry* entry = entryList_[index.row()];
        switch(role) {
            case IMAGE_ROLE:
                return entry->image();
            case TITLE_ROLE:
                return entry->title();
            default:
                return QVariant();
        }
    }

    void appendEntry(NavigationController* controller, NavigationEntry *entry)
    {
        HistoryEntry* historyEntry
                                = new HistoryEntry(entryList_.count(),
                                                   hiProvider_,
                                                   entry,
                                                   controller,
                                                   this);
        historyEntry->imgURLGen();
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        entryList_.push_back(historyEntry);
        endInsertRows();
    }

    // emit a showHistory signal to QML
    void show() { emit showHistory(); }

    // emit a hideHistory signal to QML
    void hide() { emit hideHistory(); }

    // emit a current selected(focused) history entry
    void setCurrent(int index) { emit current(index); }

    HistoryImageProvider* hiProvider() { return &hiProvider_; }

Q_SIGNALS:
    // three signals used to notify QML
    void showHistory();
    void hideHistory();
    void current(int index);

public Q_SLOTS:
    // open specific page, called by QML element
    // It's called by QML element when user clicks one history entry in QML view
    void openPage(const int index);

private:
    BackForwardButtonQtImpl* back_forward_;
    // list to hold entries
    QList<HistoryEntry*> entryList_;
    HistoryImageProvider hiProvider_;
    // count of returned images from browser
    int returnedImages_;
};

class BackForwardButtonQtImpl
{
public:
    enum NaviState {
        ONLY_BACK = 0,
        ONLY_FORWARD,
        BACK_FORWARD
    };

    // constructor
    BackForwardButtonQtImpl(BrowserToolbarQt* toolbar, Browser* browser, BrowserWindowQt* window)
        :toolbar_(toolbar), browser_(browser), model_(this),
        state_(ONLY_BACK), active_(false)
    {
        QDeclarativeView* view = window->DeclarativeView();
        QDeclarativeContext *context = view->rootContext();
        context->setContextProperty("historyStackModel", &model_);
        context->engine()->addImageProvider(QLatin1String("historystack"), model_.hiProvider());
    }

    NavigationController* currentController()
    {
        return &(browser_->GetSelectedTabContents()->controller());
    }

    void openPage(NavigationEntry *entry)
    {
        currentController()->GoToIndex(currentController()->GetIndexOfEntry(entry));
        updateStatus();
    }

    void updateStatus()
    {
        if(currentController()->GetCurrentEntryIndex() == currentController()->entry_count() - 1)
        {
            state_ = ONLY_BACK;
            if (currentController()->entry_count() > 1) {
                active_ = true;
            } else {
                active_ = false;
            }
        } else if (currentController()->GetCurrentEntryIndex() == 0
                   && currentController()->entry_count() > 0) {
            state_ = ONLY_FORWARD;
        } else if (currentController()->CanGoBack() && currentController()->CanGoForward()) {
            state_ = BACK_FORWARD;
        } else {
            state_ = ONLY_BACK;
            active_ = false;
        }
        // update button status in qml
        updateButton();
        DLOG(INFO) << "In C++, updateStatus is invoked\n";
    }

    // update back-forward button icon
    void updateButton() { toolbar_->updateBfButton((int)state_, active_); }

    void tap()
    {
        DLOG(INFO) << "In C++, tap is invoked";
        switch(state_) {
        case ONLY_BACK:
            if (currentController()->CanGoBack()) {
                currentController()->GoBack();
            }
            break;
        case ONLY_FORWARD:
            if (currentController()->entry_count() == 2) {
                if (currentController()->CanGoForward()) {
                    currentController()->GoForward();
                }
            } else {
                prepareAndShowHistory();
            }
            break;
        case BACK_FORWARD:
            prepareAndShowHistory();
            break;
        default:
            break;
        }
    }

    void tapAndHold()
    {
        switch(state_) {
        case ONLY_BACK:
            prepareAndShowHistory();
            break;
        case ONLY_FORWARD:
            if (currentController()->entry_count() == 2) {
                if (currentController()->CanGoForward()) {
                    currentController()->GoForward();
                }
            } else {
                prepareAndShowHistory();
            }
            break;
        case BACK_FORWARD:
                prepareAndShowHistory();
            break;
        default:
            break;
        }
        updateStatus();
    }

    //prepare c++ list model and emit signal to QML to show it
    void prepareAndShowHistory()
    {
        model_.clear();
        int count = currentController()->entry_count();
        int curr = -1;
        HistoryEntry::incReloadNumber();
        for(int i = count - 1; i >= 0; i--)
        {
            DLOG(INFO) << "page index: ---" << i << "---\n";
            NavigationEntry* navEntry = currentController()->GetEntryAtIndex(i);
            // don't skip 'newtab' now, if yes, we do not only skip newtab here
            // but also skip count calculation for 'updateStatus'
            /*
            if (navEntry->url().HostNoBrackets() == "newtab") {
                // skip 'newtab'
                continue;
            }*/
            model_.appendEntry(currentController(), navEntry);
            curr++;
            if(currentController()->GetCurrentEntryIndex() == i) {
                model_.setCurrent(curr);
            }
        }
        model_.show();
        toolbar_->showHistory();
    }

private:
    BrowserToolbarQt* toolbar_;
    Browser* browser_;
    HistoryStackModel model_;

    // current navigation state
    NaviState state_;
    // whether the backward/forward button is active
    bool active_;
};

BackForwardButtonQt::BackForwardButtonQt(BrowserToolbarQt* toolbar, Browser* browser, BrowserWindowQt* window)
{
  impl_ = new BackForwardButtonQtImpl(toolbar, browser, window);
}

BackForwardButtonQt::~BackForwardButtonQt()
{
  delete impl_;
}

void BackForwardButtonQt::tap()
{
  impl_->tap();
}

void BackForwardButtonQt::tapAndHold()
{
  impl_->tapAndHold();
}

void BackForwardButtonQt::updateStatus()
{
  impl_->updateStatus();
}

void HistoryEntry::onThumbnailDataAvailable(HistoryService::Handle request_handle,
                                            scoped_refptr<RefCountedBytes> jpeg_data)
{
    model_->beginReset();
    if (jpeg_data.get()) {
        DLOG(INFO) << "get image id: " << index_;
        std::vector<unsigned char> thumbnail_data;
        std::copy(jpeg_data->data.begin(), jpeg_data->data.end(),
                std::back_inserter(thumbnail_data));
        QImage image = QImage::fromData(thumbnail_data.data(), thumbnail_data.size());
        hiProvider_.addImage(QString::number(index_), image);
    }
    model_->endReset();
}

void HistoryEntry::getThumbnailData(NavigationController *controller)
{
  history::TopSites* ts = controller->profile()->GetTopSites();
  if (ts) {
    scoped_refptr<RefCountedBytes> thumbnail_data;
    ts->GetPageThumbnail(entry_->url(), &thumbnail_data);
    if (thumbnail_data.get()) {
      std::vector <unsigned char> jpeg;
      std::copy(thumbnail_data->data.begin(),
                thumbnail_data->data.end(),
                std::back_inserter(jpeg));
      QImage image = QImage::fromData(jpeg.data(), jpeg.size());
      DLOG(INFO) << "image size ===== " << jpeg.size();
      hiProvider_.addImage(QString::number(index_), image);
    }
  } else {
     HistoryService* hs = controller->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
     hs->GetPageThumbnail(entry_->url(),
                          &consumer_,
                          NewCallback(static_cast<HistoryEntry*>(this),
                                      &HistoryEntry::onThumbnailDataAvailable));
  }
}

void HistoryStackModel::openPage(const int index)
{
    back_forward_->openPage(entryList_[index]->entry());
    hide();
}

#include "moc_back_forward_button_qt.cc"
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once

#include <utility>
#include "Exception.hpp"

namespace parameterFramework
{
template <class T>
class FailureWrapper
{
public:
    FailureWrapper(T *wrapped) : mWrapped(*wrapped) {}

protected:
    /** Wrap a const method that may fail to throw an Exception instead of
     * retuning a boolean.
     *
     * @param[in] method (const) that return a boolean to indicate failure.
     * @param[in] args parameters to call method call with. */
    template <class K, class... MArgs, class... Args>
    void mayFailCall(bool (K::*method)(MArgs...) const, Args&&... args) const {
        std::string error;
        if (not (mWrapped.*method)(std::forward<Args>(args)..., error)) {
            throw Exception(std::move(error));
        }
    }

    /** Wrap a method that may fail to throw an Exception instead of retuning a
     * boolean.
     *
     * @param[in] method that return a boolean to indicate failure.
     * @param[in] args parameters to call method call with. */
    template <class K, class... MArgs, class... Args>
    void mayFailCall(bool (K::*method)(MArgs...), Args&&... args) {
        std::string error;
        if (not (mWrapped.*method)(std::forward<Args>(args)..., error)) {
            throw Exception(std::move(error));
        }
    }

    /** Wrap a method that may indicate failure by returning a null pointer to
     * throw an Exception instead of retuning a null pointer.
     *
     * @param[in] method that return a boolean to indicate failure.
     * @param[in] args parameters to call method call with. */
    template <class K, class ReturnType, class... MArgs, class... Args>
    ReturnType *mayFailCall(ReturnType *(K::*method)(MArgs...), Args&&... args) {
        std::string error;
        ReturnType *ret = (mWrapped.*method)(std::forward<Args>(args)..., error);
        if (ret == NULL) {
            throw Exception(std::move(error));
        }
        return ret;
    }

private:
    T& mWrapped;
};
} // parameterFramework
<commit_msg>Functional test: mayFailCall: static_assert incorrect usage<commit_after>/*
 * Copyright (c) 2015, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once

#include <utility>
#include "Exception.hpp"

namespace parameterFramework
{

namespace detail
{
static inline bool successTest(bool res) { return res; }
template <class T>
static inline bool successTest(T *res) { return res != nullptr; }
} // namespace detail

template <class T>
class FailureWrapper
{
public:
    FailureWrapper(T *wrapped) : mWrapped(*wrapped) {}

protected:
    /** Wrap a const method that may fail to throw an Exception instead of
     * retuning a boolean.
     *
     * @param[in] method (const) that return a boolean to indicate failure.
     * @param[in] args parameters to call method call with. */
    template <class K, class... MArgs, class... Args>
    void mayFailCall(bool (K::*method)(MArgs...) const, Args&&... args) const {
        wrapCall<K, bool>(method, std::forward<Args>(args)...);
    }

    /** Wrap a method that may fail to throw an Exception instead of retuning a
     * boolean.
     *
     * @param[in] method that return a boolean to indicate failure.
     * @param[in] args parameters to call method call with. */
    template <class K, class... MArgs, class... Args>
    void mayFailCall(bool (K::*method)(MArgs...), Args&&... args) {
        wrapCall<K, bool>(method, std::forward<Args>(args)...);
    }

    /** Wrap a method that may indicate failure by returning a null pointer to
     * throw an Exception instead of retuning a null pointer.
     *
     * @param[in] method that return a nullprt to indicate failure.
     * @param[in] args parameters to call method call with. */
    template <class K, class ReturnType, class... MArgs, class... Args>
    ReturnType *mayFailCall(ReturnType *(K::*method)(MArgs...), Args&&... args) {
        return wrapCall<K, ReturnType *>(method, std::forward<Args>(args)...);
    }

private:
    template <class K, class Ret, class M, class... Args>
    Ret wrapCall(M method, Args &&... args) const
    {
        static_assert(std::is_base_of<K, T>::value, "Attempt to call a method on an incompatible object.");
        std::string error;
        auto ret = (mWrapped.*method)(std::forward<Args>(args)..., error);
        if (not detail::successTest(ret)) {
            throw Exception(std::move(error));
        }
        return ret;
    }

    T& mWrapped;
};
} // parameterFramework
<|endoftext|>


<commit_before><commit_msg>-Werror,-Wself-assign (Clang)<commit_after><|endoftext|>


<commit_before>#include "spriteStyle.h"

#include "platform.h"
#include "tile/mapTile.h"
#include "util/shaderProgram.h"
#include "util/texture.h"
#include "util/vertexLayout.h"
#include "util/builders.h"
#include "view/view.h"

#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"

SpriteStyle::SpriteStyle(std::string _name, GLenum _drawMode) : Style(_name, _drawMode) {

    m_labels = Labels::GetInstance();
}

SpriteStyle::~SpriteStyle() {}

void SpriteStyle::constructVertexLayout() {

    // 32 bytes, good for memory aligments
    m_vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
        {"a_position", 2, GL_FLOAT, false, 0},
        {"a_uv", 2, GL_FLOAT, false, 0},
        {"a_screenPosition", 2, GL_FLOAT, false, 0},
        {"a_alpha", 1, GL_FLOAT, false, 0},
        {"a_rotation", 1, GL_FLOAT, false, 0},
    }));
}

void SpriteStyle::constructShaderProgram() {

    std::string fragShaderSrcStr = stringFromResource("sprite.fs");
    std::string vertShaderSrcStr = stringFromResource("point.vs");

    m_shaderProgram->setSourceStrings(fragShaderSrcStr, vertShaderSrcStr);

    // TODO : load this from stylesheet
    m_spriteAtlas = std::unique_ptr<SpriteAtlas>(new SpriteAtlas("poi_icons_32.png"));

    m_spriteAtlas->addSpriteNode("plane", {0, 0}, {32, 32});
    m_spriteAtlas->addSpriteNode("tree", {0, 185}, {32, 32});
    m_spriteAtlas->addSpriteNode("sunburst", {0, 629}, {32, 32});
    m_spriteAtlas->addSpriteNode("restaurant", {0, 777}, {32, 32});
    m_spriteAtlas->addSpriteNode("cafe", {0, 814}, {32, 32});
    m_spriteAtlas->addSpriteNode("museum", {0, 518}, {32, 32});
    m_spriteAtlas->addSpriteNode("bar", {0, 887}, {32, 32});
    m_spriteAtlas->addSpriteNode("train", {0, 74}, {32, 32});
    m_spriteAtlas->addSpriteNode("bus", {0, 148}, {32, 32});
    m_spriteAtlas->addSpriteNode("hospital", {0, 444}, {32, 32});
    m_spriteAtlas->addSpriteNode("parking", {0, 1073}, {32, 32});
    m_spriteAtlas->addSpriteNode("info", {0, 1110}, {32, 32});
    m_spriteAtlas->addSpriteNode("hotel", {0, 259}, {32, 32});
    m_spriteAtlas->addSpriteNode("bookstore", {0, 333}, {32, 32});
}

void SpriteStyle::buildPoint(Point& _point, const StyleParamMap&, Properties& _props, VboMesh& _mesh, MapTile& _tile) const {
    // TODO : make this configurable
    std::vector<BufferVert> vertices;

    SpriteBuilder builder = {
        [&](const glm::vec2& coord, const glm::vec2& screenPos, const glm::vec2& uv) {
            vertices.push_back({ coord, uv, screenPos, 0.5f, M_PI_2 });
        }
    };

    // TODO : configure this
    float spriteScale = .5f;
    glm::vec2 offset = {0.f, 10.f};

    for (auto prop : _props.stringProps) {
        if (prop.first == "name") {
            auto it = _props.stringProps.find("kind");
            if (it == _props.stringProps.end()) {
                continue;
            }
            std::string& kind = (*it).second;
            if (!m_spriteAtlas->hasSpriteNode(kind)) {
                continue;
            }
            SpriteNode spriteNode = m_spriteAtlas->getSpriteNode(kind);
            Label::Transform t = {glm::vec2(_point), glm::vec2(_point)};

            SpriteLabel::AttributeOffsets attribOffsets = {
                _mesh.numVertices() * m_vertexLayout->getStride(),
                (GLintptr) m_vertexLayout->getOffset("a_screenPosition"),
                (GLintptr) m_vertexLayout->getOffset("a_rotation"),
                (GLintptr) m_vertexLayout->getOffset("a_alpha"),
            };

            auto label = m_labels->addSpriteLabel(_tile, m_name, t, spriteNode.size * spriteScale, offset, attribOffsets);

            if (label) {
                Builders::buildQuadAtPoint(label->getTransform().m_screenPosition + offset, spriteNode.size * spriteScale, spriteNode.uvBL, spriteNode.uvTR, builder);
            }
        }
    }

    auto& mesh = static_cast<SpriteStyle::Mesh&>(_mesh);
    mesh.addVertices(std::move(vertices), std::move(builder.indices));
}

void SpriteStyle::buildLine(Line& _line, const StyleParamMap&, Properties& _props, VboMesh& _mesh, MapTile& _tile) const {
    // NO-OP
}

void SpriteStyle::buildPolygon(Polygon& _polygon, const StyleParamMap&, Properties& _props, VboMesh& _mesh, MapTile& _tile) const {
    // NO-OP
}

void SpriteStyle::onBeginDrawFrame(const std::shared_ptr<View>& _view, const std::shared_ptr<Scene>& _scene) {
    m_spriteAtlas->bind();

    m_shaderProgram->setUniformi("u_tex", 0);
    // top-left screen axis, y pointing down
    m_shaderProgram->setUniformMatrix4f("u_proj", glm::value_ptr(glm::ortho(0.f, _view->getWidth(), _view->getHeight(), 0.f, -1.f, 1.f)));

    RenderState::blending(GL_TRUE);
    RenderState::blendingFunc({GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA});
    RenderState::depthTest(GL_FALSE);
}

<commit_msg>some tweaks on sprite build<commit_after>#include "spriteStyle.h"

#include "platform.h"
#include "tile/mapTile.h"
#include "util/shaderProgram.h"
#include "util/texture.h"
#include "util/vertexLayout.h"
#include "util/builders.h"
#include "view/view.h"

#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"

SpriteStyle::SpriteStyle(std::string _name, GLenum _drawMode) : Style(_name, _drawMode) {

    m_labels = Labels::GetInstance();
}

SpriteStyle::~SpriteStyle() {}

void SpriteStyle::constructVertexLayout() {

    // 32 bytes, good for memory aligments
    m_vertexLayout = std::shared_ptr<VertexLayout>(new VertexLayout({
        {"a_position", 2, GL_FLOAT, false, 0},
        {"a_uv", 2, GL_FLOAT, false, 0},
        {"a_screenPosition", 2, GL_FLOAT, false, 0},
        {"a_alpha", 1, GL_FLOAT, false, 0},
        {"a_rotation", 1, GL_FLOAT, false, 0},
    }));
}

void SpriteStyle::constructShaderProgram() {

    std::string fragShaderSrcStr = stringFromResource("sprite.fs");
    std::string vertShaderSrcStr = stringFromResource("point.vs");

    m_shaderProgram->setSourceStrings(fragShaderSrcStr, vertShaderSrcStr);

    // TODO : load this from stylesheet
    m_spriteAtlas = std::unique_ptr<SpriteAtlas>(new SpriteAtlas("poi_icons_32.png"));

    m_spriteAtlas->addSpriteNode("plane", {0, 0}, {32, 32});
    m_spriteAtlas->addSpriteNode("tree", {0, 185}, {32, 32});
    m_spriteAtlas->addSpriteNode("sunburst", {0, 629}, {32, 32});
    m_spriteAtlas->addSpriteNode("restaurant", {0, 777}, {32, 32});
    m_spriteAtlas->addSpriteNode("cafe", {0, 814}, {32, 32});
    m_spriteAtlas->addSpriteNode("museum", {0, 518}, {32, 32});
    m_spriteAtlas->addSpriteNode("bar", {0, 887}, {32, 32});
    m_spriteAtlas->addSpriteNode("train", {0, 74}, {32, 32});
    m_spriteAtlas->addSpriteNode("bus", {0, 148}, {32, 32});
    m_spriteAtlas->addSpriteNode("hospital", {0, 444}, {32, 32});
    m_spriteAtlas->addSpriteNode("parking", {0, 1073}, {32, 32});
    m_spriteAtlas->addSpriteNode("info", {0, 1110}, {32, 32});
    m_spriteAtlas->addSpriteNode("hotel", {0, 259}, {32, 32});
    m_spriteAtlas->addSpriteNode("bookstore", {0, 333}, {32, 32});
}

void SpriteStyle::buildPoint(Point& _point, const StyleParamMap&, Properties& _props, VboMesh& _mesh, MapTile& _tile) const {
    // TODO : make this configurable
    std::vector<BufferVert> vertices;

    SpriteBuilder builder = {
        [&](const glm::vec2& coord, const glm::vec2& screenPos, const glm::vec2& uv) {
            vertices.push_back({ coord, uv, screenPos, 0.5f, M_PI_2 });
        }
    };

    // TODO : configure this
    float spriteScale = .5f;
    glm::vec2 offset = {0.f, 10.f};

    auto it = _props.stringProps.find("kind");
    if (it == _props.stringProps.end()) {
        return;
    }

    std::string& kind = (*it).second;
    if (!m_spriteAtlas->hasSpriteNode(kind)) {
        return;
    }

    SpriteNode spriteNode = m_spriteAtlas->getSpriteNode(kind);
    Label::Transform t = {glm::vec2(_point), glm::vec2(_point)};

    SpriteLabel::AttributeOffsets attribOffsets = {
        _mesh.numVertices() * m_vertexLayout->getStride(),
        (GLintptr) m_vertexLayout->getOffset("a_screenPosition"),
        (GLintptr) m_vertexLayout->getOffset("a_rotation"),
        (GLintptr) m_vertexLayout->getOffset("a_alpha"),
    };

    auto label = m_labels->addSpriteLabel(_tile, m_name, t, spriteNode.size * spriteScale, offset, attribOffsets);

    if (label) {
        Builders::buildQuadAtPoint(label->getTransform().m_screenPosition + offset, spriteNode.size * spriteScale, spriteNode.uvBL, spriteNode.uvTR, builder);
    }

    auto& mesh = static_cast<SpriteStyle::Mesh&>(_mesh);
    mesh.addVertices(std::move(vertices), std::move(builder.indices));
}

void SpriteStyle::buildLine(Line& _line, const StyleParamMap&, Properties& _props, VboMesh& _mesh, MapTile& _tile) const {
    // NO-OP
}

void SpriteStyle::buildPolygon(Polygon& _polygon, const StyleParamMap&, Properties& _props, VboMesh& _mesh, MapTile& _tile) const {
    // NO-OP
}

void SpriteStyle::onBeginDrawFrame(const std::shared_ptr<View>& _view, const std::shared_ptr<Scene>& _scene) {
    m_spriteAtlas->bind();

    m_shaderProgram->setUniformi("u_tex", 0);
    // top-left screen axis, y pointing down
    m_shaderProgram->setUniformMatrix4f("u_proj", glm::value_ptr(glm::ortho(0.f, _view->getWidth(), _view->getHeight(), 0.f, -1.f, 1.f)));

    RenderState::blending(GL_TRUE);
    RenderState::blendingFunc({GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA});
    RenderState::depthTest(GL_FALSE);
}

<|endoftext|>