<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2010 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ProtocolParameter>

#include <TelepathyQt4/ManagerFile>

namespace Tp
{

struct TELEPATHY_QT4_NO_EXPORT ProtocolParameter::Private : public QSharedData
{
    Private(const QString &name, const QDBusSignature &dbusSignature, QVariant::Type type,
            const QVariant &defaultValue, ConnMgrParamFlag flags)
        : name(name), dbusSignature(dbusSignature), type(type), defaultValue(defaultValue),
          flags(flags) {}

    QString name;
    QDBusSignature dbusSignature;
    QVariant::Type type;
    QVariant defaultValue;
    ConnMgrParamFlag flags;
};

ProtocolParameter::ProtocolParameter()
{
}

ProtocolParameter::ProtocolParameter(const QString &name,
                                     const QDBusSignature &dbusSignature,
                                     QVariant defaultValue,
                                     ConnMgrParamFlag flags)
    : mPriv(new Private(name, dbusSignature,
                ManagerFile::variantTypeFromDBusSignature(dbusSignature.signature()), defaultValue,
                flags))
{
}

ProtocolParameter::ProtocolParameter(const ProtocolParameter &other)
    : mPriv(other.mPriv)
{
}

ProtocolParameter::~ProtocolParameter()
{
}

ProtocolParameter &ProtocolParameter::operator=(const ProtocolParameter &other)
{
    this->mPriv = other.mPriv;
    return *this;
}

bool ProtocolParameter::operator==(const ProtocolParameter &other) const
{
    if (!isValid()) {
        return false;
    }

    return (mPriv->name == other.name());
}

bool ProtocolParameter::operator==(const QString &name) const
{
    if (!isValid()) {
        return false;
    }

    return (mPriv->name == name);
}

QString ProtocolParameter::name() const
{
    if (!isValid()) {
        return QString();
    }

    return mPriv->name;
}

QDBusSignature ProtocolParameter::dbusSignature() const
{
    if (!isValid()) {
        return QDBusSignature();
    }

    return mPriv->dbusSignature;
}

QVariant::Type ProtocolParameter::type() const
{
    if (!isValid()) {
        return QVariant::Invalid;
    }

    return mPriv->type;
}

QVariant ProtocolParameter::defaultValue() const
{
    if (!isValid()) {
        return QVariant();
    }

    return mPriv->defaultValue;
}

bool ProtocolParameter::isRequired() const
{
    if (!isValid()) {
        return false;
    }

    return mPriv->flags & ConnMgrParamFlagRequired;
}

bool ProtocolParameter::isSecret() const
{
    if (!isValid()) {
        return false;
    }

    return mPriv->flags & ConnMgrParamFlagSecret;
}

bool ProtocolParameter::isRequiredForRegistration() const
{
    if (!isValid()) {
        return false;
    }

    return mPriv->flags & ConnMgrParamFlagRegister;
}

} // Tp
<commit_msg>ProtocolParameter: Return true in operator== if both instances are invalid and false if only one of them is.<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2010 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ProtocolParameter>

#include <TelepathyQt4/ManagerFile>

namespace Tp
{

struct TELEPATHY_QT4_NO_EXPORT ProtocolParameter::Private : public QSharedData
{
    Private(const QString &name, const QDBusSignature &dbusSignature, QVariant::Type type,
            const QVariant &defaultValue, ConnMgrParamFlag flags)
        : name(name), dbusSignature(dbusSignature), type(type), defaultValue(defaultValue),
          flags(flags) {}

    QString name;
    QDBusSignature dbusSignature;
    QVariant::Type type;
    QVariant defaultValue;
    ConnMgrParamFlag flags;
};

ProtocolParameter::ProtocolParameter()
{
}

ProtocolParameter::ProtocolParameter(const QString &name,
                                     const QDBusSignature &dbusSignature,
                                     QVariant defaultValue,
                                     ConnMgrParamFlag flags)
    : mPriv(new Private(name, dbusSignature,
                ManagerFile::variantTypeFromDBusSignature(dbusSignature.signature()), defaultValue,
                flags))
{
}

ProtocolParameter::ProtocolParameter(const ProtocolParameter &other)
    : mPriv(other.mPriv)
{
}

ProtocolParameter::~ProtocolParameter()
{
}

ProtocolParameter &ProtocolParameter::operator=(const ProtocolParameter &other)
{
    this->mPriv = other.mPriv;
    return *this;
}

bool ProtocolParameter::operator==(const ProtocolParameter &other) const
{
    if (!isValid() || !other.isValid()) {
        if (!isValid() && !other.isValid()) {
            return true;
        }
        return false;
    }

    return (mPriv->name == other.name());
}

bool ProtocolParameter::operator==(const QString &name) const
{
    if (!isValid()) {
        return false;
    }

    return (mPriv->name == name);
}

QString ProtocolParameter::name() const
{
    if (!isValid()) {
        return QString();
    }

    return mPriv->name;
}

QDBusSignature ProtocolParameter::dbusSignature() const
{
    if (!isValid()) {
        return QDBusSignature();
    }

    return mPriv->dbusSignature;
}

QVariant::Type ProtocolParameter::type() const
{
    if (!isValid()) {
        return QVariant::Invalid;
    }

    return mPriv->type;
}

QVariant ProtocolParameter::defaultValue() const
{
    if (!isValid()) {
        return QVariant();
    }

    return mPriv->defaultValue;
}

bool ProtocolParameter::isRequired() const
{
    if (!isValid()) {
        return false;
    }

    return mPriv->flags & ConnMgrParamFlagRequired;
}

bool ProtocolParameter::isSecret() const
{
    if (!isValid()) {
        return false;
    }

    return mPriv->flags & ConnMgrParamFlagSecret;
}

bool ProtocolParameter::isRequiredForRegistration() const
{
    if (!isValid()) {
        return false;
    }

    return mPriv->flags & ConnMgrParamFlagRegister;
}

} // Tp
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/ui/ash/launcher/browser_launcher_item_controller.h"

#include "ash/launcher/launcher.h"
#include "ash/launcher/launcher_model.h"
#include "ash/shell.h"
#include "ash/wm/window_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/favicon/favicon_tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/web_app.h"
#include "content/public/browser/web_contents.h"
#include "grit/ui_resources.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/widget/widget.h"

using extensions::Extension;

BrowserLauncherItemController::BrowserLauncherItemController(
    Type type,
    aura::Window* window,
    TabStripModel* tab_model,
    ChromeLauncherController* launcher_controller,
    const std::string& app_id)
    : LauncherItemController(type, app_id, launcher_controller),
      window_(window),
      tab_model_(tab_model),
      is_incognito_(tab_model->profile()->GetOriginalProfile() !=
                    tab_model->profile() && !Profile::IsGuestSession()) {
  DCHECK(window_);
  window_->AddObserver(this);
}

BrowserLauncherItemController::~BrowserLauncherItemController() {
  tab_model_->RemoveObserver(this);
  window_->RemoveObserver(this);
  if (launcher_id() > 0)
    launcher_controller()->CloseLauncherItem(launcher_id());
}

void BrowserLauncherItemController::Init() {
  tab_model_->AddObserver(this);
  ash::LauncherItemStatus app_status =
      ash::wm::IsActiveWindow(window_) ?
      ash::STATUS_ACTIVE : ash::STATUS_RUNNING;
  if (type() != TYPE_TABBED) {
    launcher_controller()->CreateAppLauncherItem(this, app_id(), app_status);
  } else {
    launcher_controller()->CreateTabbedLauncherItem(
        this,
        is_incognito_ ? ChromeLauncherController::STATE_INCOGNITO :
                        ChromeLauncherController::STATE_NOT_INCOGNITO,
        app_status);
  }
  // In testing scenarios we can get tab strips with no active contents.
  if (tab_model_->GetActiveTabContents())
    UpdateLauncher(tab_model_->GetActiveTabContents());
}

// static
BrowserLauncherItemController* BrowserLauncherItemController::Create(
    Browser* browser) {
  // Under testing this can be called before the controller is created.
  if (!ChromeLauncherController::instance())
    return NULL;

  Type type;
  std::string app_id;
  if (browser->is_type_tabbed() || browser->is_type_popup()) {
    type = TYPE_TABBED;
  } else if (browser->is_app()) {
    if (browser->is_type_panel()) {
      if (browser->app_type() == Browser::APP_TYPE_CHILD)
        type = TYPE_EXTENSION_PANEL;
      else
        type = TYPE_APP_PANEL;
    } else {
      type = TYPE_TABBED;
    }
    app_id = web_app::GetExtensionIdFromApplicationName(browser->app_name());
  } else {
    return NULL;
  }
  BrowserLauncherItemController* controller =
      new BrowserLauncherItemController(type,
                                        browser->window()->GetNativeWindow(),
                                        browser->tab_strip_model(),
                                        ChromeLauncherController::instance(),
                                        app_id);
  controller->Init();
  return controller;
}

void BrowserLauncherItemController::BrowserActivationStateChanged() {
  if (tab_model_->GetActiveTabContents())
    UpdateAppState(tab_model_->GetActiveTabContents());
  UpdateItemStatus();
}

string16 BrowserLauncherItemController::GetTitle() {
  if (type() == TYPE_TABBED || type() == TYPE_EXTENSION_PANEL) {
    if (tab_model_->GetActiveTabContents()) {
      const content::WebContents* contents =
          tab_model_->GetActiveTabContents()->web_contents();
      if (contents)
        return contents->GetTitle();
    }
  }
  return GetAppTitle();
}

bool BrowserLauncherItemController::HasWindow(aura::Window* window) const {
  return window_ == window;
}

bool BrowserLauncherItemController::IsOpen() const {
  return true;
}

void BrowserLauncherItemController::Launch(int event_flags) {
  DCHECK(!app_id().empty());
  launcher_controller()->LaunchApp(app_id(), event_flags);
}

void BrowserLauncherItemController::Activate() {
  window_->Show();
  ash::wm::ActivateWindow(window_);
}

void BrowserLauncherItemController::Close() {
  views::Widget* widget = views::Widget::GetWidgetForNativeView(window_);
  if (widget)
    widget->Close();
}

void BrowserLauncherItemController::Clicked() {
  views::Widget* widget =
      views::Widget::GetWidgetForNativeView(window_);
  if (widget && widget->IsActive()) {
    widget->Minimize();
  } else {
    Activate();
  }
}

void BrowserLauncherItemController::OnRemoved() {
}

void BrowserLauncherItemController::LauncherItemChanged(
    int index,
    const ash::LauncherItem& old_item) {
  if (launcher_model()->items()[index].status == ash::STATUS_ACTIVE &&
      old_item.status == ash::STATUS_RUNNING) {
    Activate();
  }
}

void BrowserLauncherItemController::ActiveTabChanged(
    TabContents* old_contents,
    TabContents* new_contents,
    int index,
    bool user_gesture) {
  // Update immediately on a tab change.
  if (old_contents)
    UpdateAppState(old_contents);
  UpdateAppState(new_contents);
  UpdateLauncher(new_contents);
}

void BrowserLauncherItemController::TabInsertedAt(TabContents* contents,
                                                  int index,
                                                  bool foreground) {
  UpdateAppState(contents);
}

void BrowserLauncherItemController::TabDetachedAt(TabContents* contents,
                                                  int index) {
  launcher_controller()->UpdateAppState(
      contents, ChromeLauncherController::APP_STATE_REMOVED);
}

void BrowserLauncherItemController::TabChangedAt(
    TabContents* tab,
    int index,
    TabStripModelObserver::TabChangeType change_type) {
  UpdateAppState(tab);
  if (index != tab_model_->active_index() ||
      !(change_type != TabStripModelObserver::LOADING_ONLY &&
        change_type != TabStripModelObserver::TITLE_NOT_LOADING)) {
    return;
  }

  FaviconTabHelper* favicon_tab_helper =
      FaviconTabHelper::FromWebContents(tab->web_contents());
  if (favicon_tab_helper->FaviconIsValid() ||
      !favicon_tab_helper->ShouldDisplayFavicon()) {
    // We have the favicon, update immediately.
    UpdateLauncher(tab);
  } else {
    int item_index = launcher_model()->ItemIndexByID(launcher_id());
    if (item_index == -1)
      return;
    ash::LauncherItem item = launcher_model()->items()[item_index];
    item.image = gfx::ImageSkia();
    launcher_model()->Set(item_index, item);
  }
}

void BrowserLauncherItemController::TabReplacedAt(
    TabStripModel* tab_strip_model,
    TabContents* old_contents,
    TabContents* new_contents,
    int index) {
  launcher_controller()->UpdateAppState(
      old_contents, ChromeLauncherController::APP_STATE_REMOVED);
  UpdateAppState(new_contents);
}

void BrowserLauncherItemController::FaviconUpdated() {
  UpdateLauncher(tab_model_->GetActiveTabContents());
}

void BrowserLauncherItemController::OnWindowPropertyChanged(
    aura::Window* window,
    const void* key,
    intptr_t old) {
  if (key == aura::client::kDrawAttentionKey)
    UpdateItemStatus();
}

void BrowserLauncherItemController::UpdateItemStatus() {
  ash::LauncherItemStatus status;
  if (ash::wm::IsActiveWindow(window_)) {
    // Clear attention state if active.
    if (window_->GetProperty(aura::client::kDrawAttentionKey))
      window_->SetProperty(aura::client::kDrawAttentionKey, false);
    status = ash::STATUS_ACTIVE;
  } else if (window_->GetProperty(aura::client::kDrawAttentionKey)) {
    status = ash::STATUS_ATTENTION;
  } else {
    status = ash::STATUS_RUNNING;
  }
  launcher_controller()->SetItemStatus(launcher_id(), status);
}

void BrowserLauncherItemController::UpdateLauncher(TabContents* tab) {
  if (type() == TYPE_APP_PANEL)
    return;  // Maintained entirely by ChromeLauncherController.

  if (!tab)
    return;  // Assume the window is going to be closed if there are no tabs.

  int item_index = launcher_model()->ItemIndexByID(launcher_id());
  if (item_index == -1)
    return;

  ash::LauncherItem item = launcher_model()->items()[item_index];
  if (type() == TYPE_EXTENSION_PANEL) {
    if (!favicon_loader_.get() ||
        favicon_loader_->web_contents() != tab->web_contents()) {
      favicon_loader_.reset(
          new LauncherFaviconLoader(this, tab->web_contents()));
    }
    // Update the icon for extension panels.
    extensions::TabHelper* extensions_tab_helper =
        extensions::TabHelper::FromWebContents(tab->web_contents());
    gfx::ImageSkia new_image = gfx::ImageSkia(favicon_loader_->GetFavicon());
    if (new_image.isNull() && extensions_tab_helper->GetExtensionAppIcon())
      new_image = gfx::ImageSkia(*extensions_tab_helper->GetExtensionAppIcon());
    // Only update the icon if we have a new image, or none has been set yet.
    // This avoids flickering to an empty image when a pinned app is opened.
    if (!new_image.isNull())
      item.image = new_image;
    else if (item.image.isNull())
      item.image = extensions::Extension::GetDefaultIcon(true);
  } else {
    DCHECK_EQ(TYPE_TABBED, type());
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    FaviconTabHelper* favicon_tab_helper =
        FaviconTabHelper::FromWebContents(tab->web_contents());
    if (favicon_tab_helper->ShouldDisplayFavicon()) {
      item.image = favicon_tab_helper->GetFavicon().AsImageSkia();
      if (item.image.isNull()) {
        item.image = *rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
      }
    } else {
      item.image = *rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
    }
  }
  launcher_model()->Set(item_index, item);
}

void BrowserLauncherItemController::UpdateAppState(TabContents* tab) {
  ChromeLauncherController::AppState app_state;

  if (tab_model_->GetIndexOfTabContents(tab) == TabStripModel::kNoTab) {
    app_state = ChromeLauncherController::APP_STATE_REMOVED;
  } else if (tab_model_->GetActiveTabContents() == tab) {
    if (ash::wm::IsActiveWindow(window_))
      app_state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE;
    else
      app_state = ChromeLauncherController::APP_STATE_ACTIVE;
  } else {
    app_state = ChromeLauncherController::APP_STATE_INACTIVE;
  }
  launcher_controller()->UpdateAppState(tab, app_state);
}

ash::LauncherModel* BrowserLauncherItemController::launcher_model() {
  return launcher_controller()->model();
}
<commit_msg>USE DEFAULT_FAVICON instead of NULL Image<commit_after>// Copyright (c) 2012 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/ui/ash/launcher/browser_launcher_item_controller.h"

#include "ash/launcher/launcher.h"
#include "ash/launcher/launcher_model.h"
#include "ash/shell.h"
#include "ash/wm/window_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/favicon/favicon_tab_helper.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/web_app.h"
#include "content/public/browser/web_contents.h"
#include "grit/ui_resources.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/widget/widget.h"

using extensions::Extension;

BrowserLauncherItemController::BrowserLauncherItemController(
    Type type,
    aura::Window* window,
    TabStripModel* tab_model,
    ChromeLauncherController* launcher_controller,
    const std::string& app_id)
    : LauncherItemController(type, app_id, launcher_controller),
      window_(window),
      tab_model_(tab_model),
      is_incognito_(tab_model->profile()->GetOriginalProfile() !=
                    tab_model->profile() && !Profile::IsGuestSession()) {
  DCHECK(window_);
  window_->AddObserver(this);
}

BrowserLauncherItemController::~BrowserLauncherItemController() {
  tab_model_->RemoveObserver(this);
  window_->RemoveObserver(this);
  if (launcher_id() > 0)
    launcher_controller()->CloseLauncherItem(launcher_id());
}

void BrowserLauncherItemController::Init() {
  tab_model_->AddObserver(this);
  ash::LauncherItemStatus app_status =
      ash::wm::IsActiveWindow(window_) ?
      ash::STATUS_ACTIVE : ash::STATUS_RUNNING;
  if (type() != TYPE_TABBED) {
    launcher_controller()->CreateAppLauncherItem(this, app_id(), app_status);
  } else {
    launcher_controller()->CreateTabbedLauncherItem(
        this,
        is_incognito_ ? ChromeLauncherController::STATE_INCOGNITO :
                        ChromeLauncherController::STATE_NOT_INCOGNITO,
        app_status);
  }
  // In testing scenarios we can get tab strips with no active contents.
  if (tab_model_->GetActiveTabContents())
    UpdateLauncher(tab_model_->GetActiveTabContents());
}

// static
BrowserLauncherItemController* BrowserLauncherItemController::Create(
    Browser* browser) {
  // Under testing this can be called before the controller is created.
  if (!ChromeLauncherController::instance())
    return NULL;

  Type type;
  std::string app_id;
  if (browser->is_type_tabbed() || browser->is_type_popup()) {
    type = TYPE_TABBED;
  } else if (browser->is_app()) {
    if (browser->is_type_panel()) {
      if (browser->app_type() == Browser::APP_TYPE_CHILD)
        type = TYPE_EXTENSION_PANEL;
      else
        type = TYPE_APP_PANEL;
    } else {
      type = TYPE_TABBED;
    }
    app_id = web_app::GetExtensionIdFromApplicationName(browser->app_name());
  } else {
    return NULL;
  }
  BrowserLauncherItemController* controller =
      new BrowserLauncherItemController(type,
                                        browser->window()->GetNativeWindow(),
                                        browser->tab_strip_model(),
                                        ChromeLauncherController::instance(),
                                        app_id);
  controller->Init();
  return controller;
}

void BrowserLauncherItemController::BrowserActivationStateChanged() {
  if (tab_model_->GetActiveTabContents())
    UpdateAppState(tab_model_->GetActiveTabContents());
  UpdateItemStatus();
}

string16 BrowserLauncherItemController::GetTitle() {
  if (type() == TYPE_TABBED || type() == TYPE_EXTENSION_PANEL) {
    if (tab_model_->GetActiveTabContents()) {
      const content::WebContents* contents =
          tab_model_->GetActiveTabContents()->web_contents();
      if (contents)
        return contents->GetTitle();
    }
  }
  return GetAppTitle();
}

bool BrowserLauncherItemController::HasWindow(aura::Window* window) const {
  return window_ == window;
}

bool BrowserLauncherItemController::IsOpen() const {
  return true;
}

void BrowserLauncherItemController::Launch(int event_flags) {
  DCHECK(!app_id().empty());
  launcher_controller()->LaunchApp(app_id(), event_flags);
}

void BrowserLauncherItemController::Activate() {
  window_->Show();
  ash::wm::ActivateWindow(window_);
}

void BrowserLauncherItemController::Close() {
  views::Widget* widget = views::Widget::GetWidgetForNativeView(window_);
  if (widget)
    widget->Close();
}

void BrowserLauncherItemController::Clicked() {
  views::Widget* widget =
      views::Widget::GetWidgetForNativeView(window_);
  if (widget && widget->IsActive()) {
    widget->Minimize();
  } else {
    Activate();
  }
}

void BrowserLauncherItemController::OnRemoved() {
}

void BrowserLauncherItemController::LauncherItemChanged(
    int index,
    const ash::LauncherItem& old_item) {
  if (launcher_model()->items()[index].status == ash::STATUS_ACTIVE &&
      old_item.status == ash::STATUS_RUNNING) {
    Activate();
  }
}

void BrowserLauncherItemController::ActiveTabChanged(
    TabContents* old_contents,
    TabContents* new_contents,
    int index,
    bool user_gesture) {
  // Update immediately on a tab change.
  if (old_contents)
    UpdateAppState(old_contents);
  UpdateAppState(new_contents);
  UpdateLauncher(new_contents);
}

void BrowserLauncherItemController::TabInsertedAt(TabContents* contents,
                                                  int index,
                                                  bool foreground) {
  UpdateAppState(contents);
}

void BrowserLauncherItemController::TabDetachedAt(TabContents* contents,
                                                  int index) {
  launcher_controller()->UpdateAppState(
      contents, ChromeLauncherController::APP_STATE_REMOVED);
}

void BrowserLauncherItemController::TabChangedAt(
    TabContents* tab,
    int index,
    TabStripModelObserver::TabChangeType change_type) {
  UpdateAppState(tab);
  if (index != tab_model_->active_index() ||
      !(change_type != TabStripModelObserver::LOADING_ONLY &&
        change_type != TabStripModelObserver::TITLE_NOT_LOADING)) {
    return;
  }

  UpdateLauncher(tab);
}

void BrowserLauncherItemController::TabReplacedAt(
    TabStripModel* tab_strip_model,
    TabContents* old_contents,
    TabContents* new_contents,
    int index) {
  launcher_controller()->UpdateAppState(
      old_contents, ChromeLauncherController::APP_STATE_REMOVED);
  UpdateAppState(new_contents);
}

void BrowserLauncherItemController::FaviconUpdated() {
  UpdateLauncher(tab_model_->GetActiveTabContents());
}

void BrowserLauncherItemController::OnWindowPropertyChanged(
    aura::Window* window,
    const void* key,
    intptr_t old) {
  if (key == aura::client::kDrawAttentionKey)
    UpdateItemStatus();
}

void BrowserLauncherItemController::UpdateItemStatus() {
  ash::LauncherItemStatus status;
  if (ash::wm::IsActiveWindow(window_)) {
    // Clear attention state if active.
    if (window_->GetProperty(aura::client::kDrawAttentionKey))
      window_->SetProperty(aura::client::kDrawAttentionKey, false);
    status = ash::STATUS_ACTIVE;
  } else if (window_->GetProperty(aura::client::kDrawAttentionKey)) {
    status = ash::STATUS_ATTENTION;
  } else {
    status = ash::STATUS_RUNNING;
  }
  launcher_controller()->SetItemStatus(launcher_id(), status);
}

void BrowserLauncherItemController::UpdateLauncher(TabContents* tab) {
  if (type() == TYPE_APP_PANEL)
    return;  // Maintained entirely by ChromeLauncherController.

  if (!tab)
    return;  // Assume the window is going to be closed if there are no tabs.

  int item_index = launcher_model()->ItemIndexByID(launcher_id());
  if (item_index == -1)
    return;

  ash::LauncherItem item = launcher_model()->items()[item_index];
  if (type() == TYPE_EXTENSION_PANEL) {
    if (!favicon_loader_.get() ||
        favicon_loader_->web_contents() != tab->web_contents()) {
      favicon_loader_.reset(
          new LauncherFaviconLoader(this, tab->web_contents()));
    }
    // Update the icon for extension panels.
    extensions::TabHelper* extensions_tab_helper =
        extensions::TabHelper::FromWebContents(tab->web_contents());
    gfx::ImageSkia new_image = gfx::ImageSkia(favicon_loader_->GetFavicon());
    if (new_image.isNull() && extensions_tab_helper->GetExtensionAppIcon())
      new_image = gfx::ImageSkia(*extensions_tab_helper->GetExtensionAppIcon());
    // Only update the icon if we have a new image, or none has been set yet.
    // This avoids flickering to an empty image when a pinned app is opened.
    if (!new_image.isNull())
      item.image = new_image;
    else if (item.image.isNull())
      item.image = extensions::Extension::GetDefaultIcon(true);
  } else {
    DCHECK_EQ(TYPE_TABBED, type());
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    FaviconTabHelper* favicon_tab_helper =
        FaviconTabHelper::FromWebContents(tab->web_contents());
    if (favicon_tab_helper->ShouldDisplayFavicon()) {
      item.image = favicon_tab_helper->GetFavicon().AsImageSkia();
      if (item.image.isNull()) {
        item.image = *rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
      }
    } else {
      item.image = *rb.GetImageSkiaNamed(IDR_DEFAULT_FAVICON);
    }
  }
  launcher_model()->Set(item_index, item);
}

void BrowserLauncherItemController::UpdateAppState(TabContents* tab) {
  ChromeLauncherController::AppState app_state;

  if (tab_model_->GetIndexOfTabContents(tab) == TabStripModel::kNoTab) {
    app_state = ChromeLauncherController::APP_STATE_REMOVED;
  } else if (tab_model_->GetActiveTabContents() == tab) {
    if (ash::wm::IsActiveWindow(window_))
      app_state = ChromeLauncherController::APP_STATE_WINDOW_ACTIVE;
    else
      app_state = ChromeLauncherController::APP_STATE_ACTIVE;
  } else {
    app_state = ChromeLauncherController::APP_STATE_INACTIVE;
  }
  launcher_controller()->UpdateAppState(tab, app_state);
}

ash::LauncherModel* BrowserLauncherItemController::launcher_model() {
  return launcher_controller()->model();
}
<|endoftext|>


<commit_before>/**
 *
 *  Graph
 *
 *  Undirected, weighted graph
 *  https://github.com/kdzlvaids/algorithm_and_practice-pknu-2016
 *
 */

#ifndef ALGORITHM_GRAPH_HPP_
#define ALGORITHM_GRAPH_HPP_ 1

/** Includes */
#include <cstddef>      /** size_t definition */
#include <vector>       /** Containers */
#include <map>          /** Containers */

namespace algorithm
{

/** Undirected, weighted graph class

    \note   Vertex deletion is not implemented
    \note   Edge deletion is not implemented
    \note   Cannot use double as WeightType
*/
template<
    class       ValueType,                            /**< Vertex value type; operator== should be defined */
    class       WeightType            = unsigned int, /**< Weight type */
    WeightType  WeightDefaultValue    = 0             /**< Default value of weight */
>
class Graph
{
public:
    typedef size_t                              SizeType;
    typedef std::map<const KeyType, WeightType> EdgeType;   /**< Edges of vertex
                                                                \param  KeyType     key_dest
                                                                \param  WeightType  weight
                                                            */

    /** Test if two keys are equal

        \return     Return true if two keys are equal; otherwise return false
        \param[in]  key_first       First key to compare
        \param[in]  key_second      Second key to compare
    */
    bool
    IsKeyEqual(const KeyType & key_first, const KeyType & key_second)
    const
    { return key_first == key_second; }

    /** Vertex class

        Each vertex has an array for its edges as a member.
    */
    struct VertexNode
    {
        const   KeyType             key;        /**< Key of vertex; same with index in graph_ */
                ValueType           value;      /**< Value of vertex */
                EdgeType            edges;
                //SizeType            edges_size; /**< Count of edges; forward_list not support size() function */

        /** Constructor */
        VertexNode(const KeyType & key, const ValueType & value)
        : key(key)
        , value(value)
        { }

        /** Test if two values are equal

            \return     Return true if two values are equal; otherwise return false
            \param[in]  value       Value to compare
        */
        bool
        IsValueEqual(const ValueType & value)
        const
        { return this->value == value; }
    };

private:
    std::vector<VertexNode> graph_; /**< Graph */

public:
    /** Test whether there is an edge from the vertices src to dest

        \return     Return true if the edge exists; otherwise return false
        \param[in]  key_src         Key of source (src)
        \param[in]  key_dest        Key of destination (dest)
    */
    bool
    Adjacent(const KeyType & key_src, const KeyType & key_dest)
    {
        for(auto & edge : graph_.at(key_src)->edges)
        {
            if(IsKeyEqual(edge.first, key_dest) == true) /** Found */
                return true;
        }

        return false; /** Not found */
    }

    /** Add a vertex, if a graph not have the vertex with specified value already

        \return     Return the key of vertex if added successfully; otherwise return -1
        \param[in]  value_of_vertex     Value of vertex
    */
    KeyType
    AddVertex(const ValueType & value_of_vertex)
    {
        KeyType key_of_vertex = GetVertexKey(value_of_vertex);

        if(key_of_vertex == GetVertexCount()) /** Not found */
            graph_.push_back(VertexNode(key_of_vertex, value_of_vertex));

        return key_of_vertex;
    }

    /** Add an edge to connect two vertices

        \param[in]  key_src         Key of source (src)
        \param[in]  key_dest        Key of destination (dest)
        \param[in]  weight          Weight of the edge
    */
    void
    AddEdge(const KeyType & key_src, const KeyType & key_dest, const WeightType & weight = WeightDefaultValue)
    {
        graph_.at(key_src).edges.insert(
            std::make_pair<const KeyType, WeightType> (KeyType(key_dest), WeightType(weight))
        );
    }

    /** Get a key of the vertex with specified value from a graph

        If failed to add, return the size of graph which is an invalid key (maximum key + 1).

        \return     Return the key of vertex if added successfully; otherwise return the size of graph
        \param[in]  value_of_vertex     Value of vertex
    */
    KeyType
    GetVertexKey(const ValueType & value_of_vertex)
    {
        for(const VertexNode & vertex : graph_)
        {
            if(vertex.IsValueEqual(value_of_vertex) == true)
                return vertex.key;
        }

        return GetVertexCount();
    }

    /** Get a value of the vertex with specified key from a graph

        \return     Return the value
        \param[in]  key_of_vertex       Key of vertex
    */
    inline
    ValueType
    GetVertexValue(const KeyType & key_of_vertex)
    const
    { return graph_.at(key_of_vertex).value; }

    /** Set a value of the vertex with specified key from a graph

        \param[in]  key_of_vertex       Key of vertex
        \param[in]  value_of_vertex     Value of vertex
    */
    inline
    void
    SetVertexValue(const KeyType & key_of_vertex, const ValueType & value_of_vertex)
    { graph_.at(key_of_vertex).value = value_of_vertex; }

    /** Get a count of vertices

        \return     Count of vertices
    */
    inline
    SizeType
    GetVertexCount(void)
    const
    { return graph_.size(); }

    /** Get a count of edges

        \return     Count of edges
        \param[in]  key_of_vertex       Key of vertex
    */
    inline
    SizeType
    GetVertexEdgeCount(const KeyType & key_of_vertex)
    const
    { return graph_.at(key_of_vertex).edges.size(); }
};

} /** ns: algorithm */

#endif /** ! ALGORITHM_GRAPH_HPP_ */
<commit_msg>Change the private member to protected<commit_after>/**
 *
 *  Graph
 *
 *  Undirected, weighted graph
 *  https://github.com/kdzlvaids/algorithm_and_practice-pknu-2016
 *
 */

#ifndef ALGORITHM_GRAPH_HPP_
#define ALGORITHM_GRAPH_HPP_ 1

/** Includes */
#include <cstddef>      /** size_t definition */
#include <vector>       /** Containers */
#include <map>          /** Containers */

namespace algorithm
{

/** Undirected, weighted graph class

    \note   Vertex deletion is not implemented
    \note   Edge deletion is not implemented
    \note   Cannot use double as WeightType
*/
template<
    class       ValueType,                            /**< Vertex value type; operator== should be defined */
    class       WeightType            = unsigned int, /**< Weight type */
    WeightType  WeightDefaultValue    = 0             /**< Default value of weight */
>
class Graph
{
public:
    typedef size_t                              SizeType;
    typedef std::map<const KeyType, WeightType> EdgeType;   /**< Edges of vertex
                                                                \param  KeyType     key_dest
                                                                \param  WeightType  weight
                                                            */

    /** Test if two keys are equal

        \return     Return true if two keys are equal; otherwise return false
        \param[in]  key_first       First key to compare
        \param[in]  key_second      Second key to compare
    */
    bool
    IsKeyEqual(const KeyType & key_first, const KeyType & key_second)
    const
    { return key_first == key_second; }

    /** Vertex class

        Each vertex has an array for its edges as a member.
    */
    struct VertexNode
    {
        const   KeyType             key;        /**< Key of vertex; same with index in graph_ */
                ValueType           value;      /**< Value of vertex */
                EdgeType            edges;
                //SizeType            edges_size; /**< Count of edges; forward_list not support size() function */

        /** Constructor */
        VertexNode(const KeyType & key, const ValueType & value)
        : key(key)
        , value(value)
        { }

        /** Test if two values are equal

            \return     Return true if two values are equal; otherwise return false
            \param[in]  value       Value to compare
        */
        bool
        IsValueEqual(const ValueType & value)
        const
        { return this->value == value; }
    };

protected:
    std::vector<VertexNode> graph_; /**< Graph */

public:
    /** Test whether there is an edge from the vertices src to dest

        \return     Return true if the edge exists; otherwise return false
        \param[in]  key_src         Key of source (src)
        \param[in]  key_dest        Key of destination (dest)
    */
    bool
    Adjacent(const KeyType & key_src, const KeyType & key_dest)
    {
        for(auto & edge : graph_.at(key_src)->edges)
        {
            if(IsKeyEqual(edge.first, key_dest) == true) /** Found */
                return true;
        }

        return false; /** Not found */
    }

    /** Add a vertex, if a graph not have the vertex with specified value already

        \return     Return the key of vertex if added successfully; otherwise return -1
        \param[in]  value_of_vertex     Value of vertex
    */
    KeyType
    AddVertex(const ValueType & value_of_vertex)
    {
        KeyType key_of_vertex = GetVertexKey(value_of_vertex);

        if(key_of_vertex == GetVertexCount()) /** Not found */
            graph_.push_back(VertexNode(key_of_vertex, value_of_vertex));

        return key_of_vertex;
    }

    /** Add an edge to connect two vertices

        \param[in]  key_src         Key of source (src)
        \param[in]  key_dest        Key of destination (dest)
        \param[in]  weight          Weight of the edge
    */
    void
    AddEdge(const KeyType & key_src, const KeyType & key_dest, const WeightType & weight = WeightDefaultValue)
    {
        graph_.at(key_src).edges.insert(
            std::make_pair<const KeyType, WeightType> (KeyType(key_dest), WeightType(weight))
        );
    }

    /** Get a key of the vertex with specified value from a graph

        If failed to add, return the size of graph which is an invalid key (maximum key + 1).

        \return     Return the key of vertex if added successfully; otherwise return the size of graph
        \param[in]  value_of_vertex     Value of vertex
    */
    KeyType
    GetVertexKey(const ValueType & value_of_vertex)
    {
        for(const VertexNode & vertex : graph_)
        {
            if(vertex.IsValueEqual(value_of_vertex) == true)
                return vertex.key;
        }

        return GetVertexCount();
    }

    /** Get a value of the vertex with specified key from a graph

        \return     Return the value
        \param[in]  key_of_vertex       Key of vertex
    */
    inline
    ValueType
    GetVertexValue(const KeyType & key_of_vertex)
    const
    { return graph_.at(key_of_vertex).value; }

    /** Set a value of the vertex with specified key from a graph

        \param[in]  key_of_vertex       Key of vertex
        \param[in]  value_of_vertex     Value of vertex
    */
    inline
    void
    SetVertexValue(const KeyType & key_of_vertex, const ValueType & value_of_vertex)
    { graph_.at(key_of_vertex).value = value_of_vertex; }

    /** Get a count of vertices

        \return     Count of vertices
    */
    inline
    SizeType
    GetVertexCount(void)
    const
    { return graph_.size(); }

    /** Get a count of edges

        \return     Count of edges
        \param[in]  key_of_vertex       Key of vertex
    */
    inline
    SizeType
    GetVertexEdgeCount(const KeyType & key_of_vertex)
    const
    { return graph_.at(key_of_vertex).edges.size(); }
};

} /** ns: algorithm */

#endif /** ! ALGORITHM_GRAPH_HPP_ */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: langselect.cxx,v $
 *
 *  $Revision: 1.13 $
 *  last change: $Author: obo $ $Date: 2005-01-27 12:27:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "app.hxx"
#include "langselect.hxx"
#include <stdio.h>

#ifndef _RTL_STRING_HXX
#include <rtl/string.hxx>
#endif
#ifndef _SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif
#ifndef _TOOLS_ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <rtl/locale.hxx>
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif
#include <osl/process.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;

namespace desktop {

sal_Bool LanguageSelection::bFoundLanguage = sal_False;
OUString LanguageSelection::aFoundLanguage;
const OUString LanguageSelection::usFallbackLanguage = OUString::createFromAscii("en-US");

Locale LanguageSelection::IsoStringToLocale(const OUString& str)
{
    Locale l;
    sal_Int32 index=0;
    l.Language = str.getToken(0, '-', index);
    if (index >= 0) l.Country = str.getToken(0, '-', index);
    if (index >= 0) l.Variant = str.getToken(0, '-', index);
    return l;
}

bool LanguageSelection::prepareLanguage()
{
    OUString aLocaleString = getLanguageString();
    if ( aLocaleString.getLength() > 0 )
    {
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        try
        {
            Reference< XLocalizable > theConfigProvider(
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
            Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
            theConfigProvider->setLocale(loc);
            Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
            xProp->setPropertyValue(OUString::createFromAscii("ooLocale"), makeAny(aLocaleString));
            Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
            return true;
        }
        catch (Exception& e)
        {
            OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
            OSL_ENSURE(sal_False, aMsg.getStr());

        }
    }
    return false;
}

OUString LanguageSelection::getLanguageString()
{
    // did we already find a language?
    if (bFoundLanguage)
        return aFoundLanguage;
    // check whether the user has selected a specific language
    OUString aUserLanguage = getUserLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        if (isInstalledLanguage(aUserLanguage))
        {
            // all is well
            bFoundLanguage = sal_True;
            aFoundLanguage = aUserLanguage;
            return aFoundLanguage;
        }
        else
        {
            // selected language is not/no longer installed
            resetUserLanguage();
        }
    }
    // try to use system default
    aUserLanguage = getSystemLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        if (isInstalledLanguage(aUserLanguage, sal_False))
        {
            // great, system default language is available
            bFoundLanguage = sal_True;
            aFoundLanguage = aUserLanguage;
            return aFoundLanguage;
        }
    }
    // fallback 1: en-US
    OUString usFB = usFallbackLanguage;
    if (isInstalledLanguage(usFB))
    {
        bFoundLanguage = sal_True;
        aFoundLanguage = usFallbackLanguage;
        return aFoundLanguage;
    }
    // fallback didn't work use first installed language
    aUserLanguage = getFirstInstalledLanguage();
    bFoundLanguage = sal_True;
    aFoundLanguage = aUserLanguage;
    return aFoundLanguage;
}

Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
{
    Reference< XNameAccess > xNameAccess;
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc;
        if (bUpdate)
            sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
        else
            sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");

        OUString sConfigURL = OUString::createFromAscii(pPath);

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        if (theMSF.is()) {
            Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );

            // access the provider
            Sequence< Any > theArgs(1);
            theArgs[ 0 ] <<= sConfigURL;
            xNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                    sAccessSrvc, theArgs ), UNO_QUERY_THROW );
        }
    } catch (com::sun::star::uno::Exception& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());
    }
    return xNameAccess;
}

Sequence< OUString > LanguageSelection::getInstalledLanguages()
{
    Sequence< OUString > seqLanguages;
    Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
    if (!xAccess.is()) return seqLanguages;
    seqLanguages = xAccess->getElementNames();
    return seqLanguages;
}

sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
{
    sal_Bool bInstalled = sal_False;
    Sequence< OUString > seqLanguages = getInstalledLanguages();
    for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
    {
        if (usLocale.equals(seqLanguages[i]))
        {
            bInstalled = sal_True;
            break;
        }
    }

    if (!bInstalled && !bExact)
    {
        // no exact match was found, well try to find a substitute
        Locale aLocale = IsoStringToLocale(usLocale);
        Locale aInstalledLocale;
        for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
        {
            aInstalledLocale = IsoStringToLocale(seqLanguages[i]);
            if (aLocale.Language.equals(aInstalledLocale.Language))
            {
                bInstalled = sal_True;
                usLocale = seqLanguages[i];
                break;
            }
        }
    }
    return bInstalled;
}

OUString LanguageSelection::getFirstInstalledLanguage()
{
    OUString aLanguage;
    Sequence< OUString > seqLanguages = getInstalledLanguages();
    if (seqLanguages.getLength() > 0)
        aLanguage = seqLanguages[0];
    return aLanguage;
}

OUString LanguageSelection::getUserLanguage()
{
    OUString aUserLanguage;
    Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
    if (xAccess.is())
    {
        try
        {
            xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
        }
        catch ( NoSuchElementException const & )
        {
            return OUString();
        }
        catch ( WrappedTargetException const & )
        {
            return OUString();
        }
    }
    return aUserLanguage;
}

OUString LanguageSelection::getSystemLanguage()
{
    OUString aUserLanguage;
    Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
    if (xAccess.is())
    {
        try
        {
            xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
        }
        catch ( NoSuchElementException const & )
        {
            return OUString();
        }
        catch ( WrappedTargetException const & )
        {
            return OUString();
        }
    }
    return aUserLanguage;
}

void LanguageSelection::resetUserLanguage()
{
    try
    {
        Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
        xProp->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(OUString::createFromAscii("")));
        Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
    }
    catch ( Exception& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());
    }

}

} // namespace desktop
<commit_msg>INTEGRATION: CWS lobeta2 (1.12.14); FILE MERGED 2005/02/07 14:32:48 jl 1.12.14.3: RESYNC: (1.12-1.13); FILE MERGED 2004/12/16 16:35:18 lo 1.12.14.2: #112849# convert file urls to internal form on the command line 2004/12/09 13:36:55 lo 1.12.14.1: #i32939# set CJK and CTL document locale according to user lang, if not yet set<commit_after>/*************************************************************************
 *
 *  $RCSfile: langselect.cxx,v $
 *
 *  $Revision: 1.14 $
 *  last change: $Author: vg $ $Date: 2005-03-11 10:47:45 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "app.hxx"
#include "langselect.hxx"
#include <stdio.h>

#ifndef _RTL_STRING_HXX
#include <rtl/string.hxx>
#endif
#ifndef _SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif
#ifndef _TOOLS_ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <rtl/locale.hxx>
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif
#include <osl/process.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;

namespace desktop {

sal_Bool LanguageSelection::bFoundLanguage = sal_False;
OUString LanguageSelection::aFoundLanguage;
const OUString LanguageSelection::usFallbackLanguage = OUString::createFromAscii("en-US");

Locale LanguageSelection::IsoStringToLocale(const OUString& str)
{
    Locale l;
    sal_Int32 index=0;
    l.Language = str.getToken(0, '-', index);
    if (index >= 0) l.Country = str.getToken(0, '-', index);
    if (index >= 0) l.Variant = str.getToken(0, '-', index);
    return l;
}

bool LanguageSelection::prepareLanguage()
{
    // get the selected UI language as string
    OUString aLocaleString = getLanguageString();
    if ( aLocaleString.getLength() > 0 )
    {
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        try
        {
            // prepare default config provider by localizing it to the selected locale
            // this will ensure localized configuration settings to be selected accoring to the
            // UI language.
            Reference< XLocalizable > theConfigProvider(
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
            Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
            theConfigProvider->setLocale(loc);
            Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
            xProp->setPropertyValue(OUString::createFromAscii("ooLocale"), makeAny(aLocaleString));
            Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();

            // #i32939# setting of default document locale
            setDefaultLocale(aLocaleString);

            return true;
        }
        catch ( PropertyVetoException& )
        {
            // we are not allowed to change this
        }
        catch (Exception& e)
        {
            OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
            OSL_ENSURE(sal_False, aMsg.getStr());

        }
    }
    return false;
}

void LanguageSelection::setDefaultLocale(const OUString& usUILocale)
{
    // #i32939# setting of default document locale
    // org.openoffice.Office.Linguistic/General/DefaultLocale
    // org.openoffice.Office.Linguistic/General/DefaultLocale_CJK
    // org.openoffice.Office.Linguistic/General/DefaultLocale_CTL

    // determine script type of UI locale
    LanguageType ltUILocale = ConvertIsoStringToLanguage(usUILocale);
    sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(ltUILocale);

    Reference< XPropertySet > xProp(getConfigAccess(
        "org.openoffice.Office.Linguistic/General/", sal_True), UNO_QUERY_THROW);
    OUString usName = OUString::createFromAscii("DefaultLocale");
    switch (nScriptType)
    {
        case SCRIPTTYPE_ASIAN:
            usName = OUString::createFromAscii("DefaultLocale_CJK");
            break;
        case SCRIPTTYPE_COMPLEX:
            usName = OUString::createFromAscii("DefaultLocale_CTL");
            break;
    }
    OUString usValue;
    xProp->getPropertyValue(usName) >>= usValue;
    if (usValue.getLength() == 0)
    {
        // there is no document language set, for the script type selected
        // in the UI
        // covert the LanguageType we've got from the LanguageTable back to
        // an iso string and store it
        OUString usDefault = ConvertLanguageToIsoString(ltUILocale);
        try
        {
            xProp->setPropertyValue(usName, makeAny(usDefault));
            Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
        }
        catch ( PropertyVetoException )
        {
            // we are not allowed to change this
        }
    }
}

OUString LanguageSelection::getLanguageString()
{
    // did we already find a language?
    if (bFoundLanguage)
        return aFoundLanguage;
    // check whether the user has selected a specific language
    OUString aUserLanguage = getUserLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        if (isInstalledLanguage(aUserLanguage))
        {
            // all is well
            bFoundLanguage = sal_True;
            aFoundLanguage = aUserLanguage;
            return aFoundLanguage;
        }
        else
        {
            // selected language is not/no longer installed
            resetUserLanguage();
        }
    }
    // try to use system default
    aUserLanguage = getSystemLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        if (isInstalledLanguage(aUserLanguage, sal_False))
        {
            // great, system default language is available
            bFoundLanguage = sal_True;
            aFoundLanguage = aUserLanguage;
            return aFoundLanguage;
        }
    }
    // fallback 1: en-US
    OUString usFB = usFallbackLanguage;
    if (isInstalledLanguage(usFB))
    {
        bFoundLanguage = sal_True;
        aFoundLanguage = usFallbackLanguage;
        return aFoundLanguage;
    }
    // fallback didn't work use first installed language
    aUserLanguage = getFirstInstalledLanguage();
    bFoundLanguage = sal_True;
    aFoundLanguage = aUserLanguage;
    return aFoundLanguage;
}

Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
{
    Reference< XNameAccess > xNameAccess;
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc;
        if (bUpdate)
            sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
        else
            sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");

        OUString sConfigURL = OUString::createFromAscii(pPath);

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        if (theMSF.is()) {
            Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );

            // access the provider
            Sequence< Any > theArgs(1);
            theArgs[ 0 ] <<= sConfigURL;
            xNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                    sAccessSrvc, theArgs ), UNO_QUERY_THROW );
        }
    } catch (com::sun::star::uno::Exception& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());
    }
    return xNameAccess;
}

Sequence< OUString > LanguageSelection::getInstalledLanguages()
{
    Sequence< OUString > seqLanguages;
    Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
    if (!xAccess.is()) return seqLanguages;
    seqLanguages = xAccess->getElementNames();
    return seqLanguages;
}

sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
{
    sal_Bool bInstalled = sal_False;
    Sequence< OUString > seqLanguages = getInstalledLanguages();
    for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
    {
        if (usLocale.equals(seqLanguages[i]))
        {
            bInstalled = sal_True;
            break;
        }
    }

    if (!bInstalled && !bExact)
    {
        // no exact match was found, well try to find a substitute
        Locale aLocale = IsoStringToLocale(usLocale);
        Locale aInstalledLocale;
        for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
        {
            aInstalledLocale = IsoStringToLocale(seqLanguages[i]);
            if (aLocale.Language.equals(aInstalledLocale.Language))
            {
                bInstalled = sal_True;
                usLocale = seqLanguages[i];
                break;
            }
        }
    }
    return bInstalled;
}

OUString LanguageSelection::getFirstInstalledLanguage()
{
    OUString aLanguage;
    Sequence< OUString > seqLanguages = getInstalledLanguages();
    if (seqLanguages.getLength() > 0)
        aLanguage = seqLanguages[0];
    return aLanguage;
}

OUString LanguageSelection::getUserLanguage()
{
    OUString aUserLanguage;
    Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
    if (xAccess.is())
    {
        try
        {
            xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
        }
        catch ( NoSuchElementException const & )
        {
            return OUString();
        }
        catch ( WrappedTargetException const & )
        {
            return OUString();
        }
    }
    return aUserLanguage;
}

OUString LanguageSelection::getSystemLanguage()
{
    OUString aUserLanguage;
    Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
    if (xAccess.is())
    {
        try
        {
            xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
        }
        catch ( NoSuchElementException const & )
        {
            return OUString();
        }
        catch ( WrappedTargetException const & )
        {
            return OUString();
        }
    }
    return aUserLanguage;
}

void LanguageSelection::resetUserLanguage()
{
    try
    {
        Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
        xProp->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(OUString::createFromAscii("")));
        Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
    }
    catch ( PropertyVetoException& )
    {
        // we are not allowed to change this
    }
    catch ( Exception& e)
    {
        OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
        OSL_ENSURE(sal_False, aMsg.getStr());
    }

}

} // namespace desktop
<|endoftext|>


<commit_before>/*
UselessMine
    Copyright (C) 2014 Vladimir "allejo" Jimenez

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

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

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <fstream>
#include <memory>
#include <stdlib.h>
#include <string>

#include "bzfsAPI.h"
#include "bztoolkit/bzToolkitAPI.h"

// Define plugin name
const std::string PLUGIN_NAME = "Useless Mine";

// Define plugin version numbering
const int MAJOR = 1;
const int MINOR = 0;
const int REV = 0;
const int BUILD = 28;

// A function to replace substrings in a string with another substring
std::string ReplaceString(std::string subject, const std::string& search, const std::string& replace)
{
    size_t pos = 0;

    while ((pos = subject.find(search, pos)) != std::string::npos)
    {
        subject.replace(pos, search.length(), replace);
        pos += replace.length();
    }

    return subject;
}

class UselessMine : public bz_Plugin, public bz_CustomSlashCommandHandler
{
public:
    virtual const char* Name ();
    virtual void Init (const char* config);
    virtual void Event (bz_EventData *eventData);
    virtual void Cleanup (void);

    virtual bool SlashCommand (int playerID, bz_ApiString, bz_ApiString, bz_APIStringList*);

    virtual int         getMineCount ();
    virtual void        removeAllMines (int playerID),
                        removeMine (int mineIndex),
                        setMine (int owner, float pos[3], bz_eTeamType team);
    virtual std::string formatDeathMessage (std::string msg, std::string victim, std::string owner);

    // The information each mine will contain
    struct Mine
    {
        int owner;             // The owner of the mine and the victim, respectively

        float x, y, z;         // The coordinates of where the mine was placed

        bz_eTeamType team;     // The team of the owner

        bool detonated;        // Whether or not the mine has been detonated; to prepare it for removal from play

        double detonationTime; // The time the mine was detonated

        Mine (int _owner, float _pos[3], bz_eTeamType _team) :
            owner(_owner),
            x(_pos[0]),
            y(_pos[1]),
            z(_pos[2]),
            team(_team),
            detonated(false)
        {}
    };

    std::vector<Mine>        activeMines;   // A vector that will store all of the mines that are in play
    std::vector<std::string> deathMessages; // A vector that will store all of the witty death messages

    std::string deathMessagesFile;

    double bzdb_SpawnSafetyTime, // The BZDB variable that will store the amount of seconds a player has before a mine is detonated
           playerSpawnTime[256]; // The time of a player's last spawn time used to calculate their safety from detonation
};

BZ_PLUGIN(UselessMine)

const char* UselessMine::Name (void)
{
    static std::string pluginBuild = "";

    if (!pluginBuild.size())
    {
        std::ostringstream pluginBuildStream;

        pluginBuildStream << PLUGIN_NAME << " " << MAJOR << "." << MINOR << "." << REV << " (" << BUILD << ")";
        pluginBuild = pluginBuildStream.str();
    }

    return pluginBuild.c_str();
}

void UselessMine::Init (const char* commandLine)
{
    // Register our events with Register()
    Register(bz_eFlagGrabbedEvent);
    Register(bz_ePlayerDieEvent);
    Register(bz_ePlayerPartEvent);
    Register(bz_ePlayerSpawnEvent);
    Register(bz_ePlayerUpdateEvent);

    // Register our custom slash commands
    bz_registerCustomSlashCommand("mine", this);

    // Set some custom BZDB variables
    bzdb_SpawnSafetyTime = bztk_registerCustomDoubleBZDB("_mineSafetyTime", 5.0);

    // Save the location of the file so we can reload after
    deathMessagesFile = commandLine;

    // Open the file of witty death messages
    std::ifstream file(commandLine);
    std::string currentLine;

    // If the file exists, read each line
    if (file)
    {
        // Push each line into the deathMessages vector
        while (std::getline(file, currentLine))
        {
            deathMessages.push_back(currentLine);
        }

        bz_debugMessagef(2, "DEBUG :: Useless Mine :: %d witty messages were loaded", deathMessages.size());
    }
    else
    {
        bz_debugMessage(2, "WARNING :: Useless Mine :: No witty death messages were loaded");
    }
}

void UselessMine::Cleanup (void)
{
    Flush(); // Clean up all the events

    // Clean up our custom slash commands
    bz_removeCustomSlashCommand("mine");
}

void UselessMine::Event (bz_EventData *eventData)
{
    switch (eventData->eventType)
    {
        case bz_eFlagGrabbedEvent: // This event is called each time a flag is grabbed by a player
        {
            bz_FlagGrabbedEventData_V1* flagGrabData = (bz_FlagGrabbedEventData_V1*)eventData;

            // Data
            // ---
            //    (int)           playerID  - The player that grabbed the flag
            //    (int)           flagID    - The flag ID that was grabbed
            //    (bz_ApiString)  flagType  - The flag abbreviation of the flag that was grabbed
            //    (float[3])      pos       - The position at which the flag was grabbed
            //    (double)        eventTime - This value is the local server time of the event.

            // If the user grabbed the Useless flag, let them know they can place a mine
            if (strcmp(flagGrabData->flagType, "US") == 0)
            {
                bz_sendTextMessage(BZ_SERVER, flagGrabData->playerID, "You grabbed a Useless flag! Type /mine at any time to set a useless mine!");
            }
        }
        break;

        case bz_ePlayerDieEvent: // This event is called each time a tank is killed.
        {
            bz_PlayerDieEventData_V1* dieData = (bz_PlayerDieEventData_V1*)eventData;

            // Data
            // ---
            //   (int)                   playerID       - ID of the player who was killed.
            //   (bz_eTeamType)          team           - The team the killed player was on.
            //   (int)                   killerID       - The owner of the shot that killed the player, or BZ_SERVER for server side kills
            //   (bz_eTeamType)          killerTeam     - The team the owner of the shot was on.
            //   (bz_ApiString)          flagKilledWith - The flag name the owner of the shot had when the shot was fired.
            //   (int)                   shotID         - The shot ID that killed the player, if the player was not killed by a shot, the id will be -1.
            //   (bz_PlayerUpdateState)  state          - The state record for the killed player at the time of the event
            //   (double)                eventTime      - Time of the event on the server.

            int playerID = dieData->playerID;

            // Loop through all the mines in play
            for (int i = 0; i < getMineCount(); i++)
            {
                // Create a local variable for easy access
                Mine &detonatedMine = activeMines.at(i);

                // Check if the mine has already been detonated
                if (detonatedMine.detonated)
                {
                    // If they were killed within the time the shockwave explodes, then we can safely say they were killed by the mine
                    if (detonatedMine.detonationTime + bz_getBZDBDouble("_shockAdLife") > bz_getCurrentTime())
                    {
                        // Check if the player who just died was killed by the server
                        if (dieData->killerID == 253)
                        {
                            // Easy to access variables
                            float  deathPos[3] = {dieData->state.pos[0], dieData->state.pos[1], dieData->state.pos[2]};
                            double shockRange = bz_getBZDBDouble("_shockOutRadius") * 0.75;

                            // Check if the player died inside of the mine radius
                            if ((deathPos[0] > detonatedMine.x - shockRange && deathPos[0] < detonatedMine.x + shockRange) &&
                                (deathPos[1] > detonatedMine.y - shockRange && deathPos[1] < detonatedMine.y + shockRange) &&
                                (deathPos[2] > detonatedMine.z - shockRange && deathPos[2] < detonatedMine.z + shockRange))
                            {
                                // Attribute the kill to the mine owner
                                dieData->killerID = detonatedMine.owner;

                                // Only get a death messages if death messages exist and the player who died is now also the mine owner
                                if (!deathMessages.empty() && playerID != detonatedMine.owner)
                                {
                                    // The random number used to fetch a random taunting death message
                                    int randomNumber = rand() % deathMessages.size();

                                    // Get the callsigns of the players
                                    const char* owner  = bz_getPlayerCallsign(detonatedMine.owner);
                                    const char* victim = bz_getPlayerCallsign(playerID);

                                    // Get a random death message
                                    std::string deathMessage = deathMessages.at(randomNumber);
                                    bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, formatDeathMessage(deathMessage, victim, owner).c_str());
                                }

                                break;
                            }
                        }
                    }
                    else
                    {
                        removeMine(i);
                    }
                }
            }
        }
        break;

        case bz_ePlayerPartEvent: // This event is called each time a player leaves a game
        {
            bz_PlayerJoinPartEventData_V1* partData = (bz_PlayerJoinPartEventData_V1*)eventData;

            // Data
            // ---
            //    (int)                   playerID  - The player ID that is leaving
            //    (bz_BasePlayerRecord*)  record    - The player record for the leaving player
            //    (bz_ApiString)          reason    - The reason for leaving, such as a kick or a ban
            //    (double)                eventTime - Time of event.

            int playerID = partData->playerID;

            // Remove all the mines belonging to the player who just left
            removeAllMines(playerID);
        }
        break;

        case bz_ePlayerSpawnEvent: // This event is called each time a playing tank is being spawned into the world
        {
            bz_PlayerSpawnEventData_V1* spawnData = (bz_PlayerSpawnEventData_V1*)eventData;

            // Data
            // ---
            //    (int)                   playerID  - ID of the player who was added to the world.
            //    (bz_eTeamType)          team      - The team the player is a member of.
            //    (bz_PlayerUpdateState)  state     - The state record for the spawning player
            //    (double)                eventTime - Time local server time for the event.

            int playerID = spawnData->playerID;

            // Save the time the player spawned last
            playerSpawnTime[playerID] = bz_getCurrentTime();
        }
        break;

        case bz_ePlayerUpdateEvent: // This event is called each time a player sends an update to the server
        {
            bz_PlayerUpdateEventData_V1* updateData = (bz_PlayerUpdateEventData_V1*)eventData;

            // Data
            // ---
            //   (int)                   playerID  - ID of the player that sent the update
            //   (bz_PlayerUpdateState)  state     - The original state the tank was in
            //   (bz_PlayerUpdateState)  lastState - The second state the tank is currently in to show there was an update
            //   (double)                stateTime - The time the state was updated
            //   (double)                eventTime - The current server time

            int playerID = updateData->playerID;

            // Loop through all of the players
            for (int i = 0; i < getMineCount(); i++)
            {
                // Make an easy access mine
                Mine &currentMine = activeMines.at(i);

                std::shared_ptr<bz_BasePlayerRecord> pr(bz_getPlayerByIndex(playerID));

                // If the mine owner is not the player triggering the mine (so no self kills) and the player is a rogue or does is an enemy team relative to the mine owner
                if (currentMine.owner != playerID && (pr->team == eRogueTeam || pr->team != currentMine.team) && pr->spawned)
                {
                    // Make easy to access variables
                    float  playerPos[3] = {updateData->state.pos[0], updateData->state.pos[1], updateData->state.pos[2]};
                    double shockRange   = bz_getBZDBDouble("_shockOutRadius") * 0.75;

                    // Check if the player is in the detonation range
                    if ((playerPos[0] > currentMine.x - shockRange && playerPos[0] < currentMine.x + shockRange) &&
                        (playerPos[1] > currentMine.y - shockRange && playerPos[1] < currentMine.y + shockRange) &&
                        (playerPos[2] > currentMine.z - shockRange && playerPos[2] < currentMine.z + shockRange) &&
                        playerSpawnTime[playerID] + bzdb_SpawnSafetyTime <= bz_getCurrentTime())
                    {
                        // Check that the mine owner exists and is not an observer
                        if (bztk_isValidPlayerID(currentMine.owner) && bz_getPlayerTeam(currentMine.owner) != eObservers)
                        {
                            // Get the current mine position
                            float minePos[3] = {currentMine.x, currentMine.y, currentMine.z};

                            // Only detonate a mine once
                            if (!currentMine.detonated)
                            {
                                currentMine.detonated = true;
                                currentMine.detonationTime = bz_getCurrentTime();

                                // BOOM!
                                bz_fireWorldWep("SW", 2.0, BZ_SERVER, minePos, 0, 0, 0, currentMine.team);
                            }
                        }
                        // Just in case the player doesn't exist or is an observer, then remove the mine because it shouldn't be there
                        else
                        {
                            removeMine(i);
                        }

                        break;
                    }
                }
            }
        }
        break;

        default: break;
    }
}

bool UselessMine::SlashCommand(int playerID, bz_ApiString command, bz_ApiString /*message*/, bz_APIStringList *params)
{
    if (command == "mine")
    {
        std::shared_ptr<bz_BasePlayerRecord> playerRecord(bz_getPlayerByIndex(playerID));

        // If the player is not an observer, they let them proceed to the next check
        if (playerRecord->team != eObservers)
        {
            // Check if the player has the Useless flag
            if (playerRecord->currentFlag == "USeless (+US)")
            {
                // Store their current position
                float currentPosition[3] = {playerRecord->lastKnownState.pos[0], playerRecord->lastKnownState.pos[1], playerRecord->lastKnownState.pos[2]};

                setMine(playerID, currentPosition, playerRecord->team);
            }
            else
            {
                bz_sendTextMessage(BZ_SERVER, playerID, "You can't place a mine without the Useless flag!");
            }
        }
        else
        {
            bz_sendTextMessage(BZ_SERVER, playerID, "Silly observer, you can't place a mine.");
        }

        return true;
    }

    return true;
}

// A function to format death messages in order to replace placeholders with callsigns and values
std::string UselessMine::formatDeathMessage(std::string msg, std::string victim, std::string owner)
{
    // Replace the %victim% and %owner% placeholders
    std::string formattedMessage = ReplaceString(ReplaceString(msg, "%victim%", victim), "%owner%", owner);

    // If the message has a %minecount%, then replace it
    if (formattedMessage.find("%minecount%") != std::string::npos)
    {
        // Subtract one from the mine count because the mine we're announcing hasn't beeb removed yet
        int minecount = (getMineCount() == 0) ? 0 : getMineCount() - 1;

        formattedMessage = ReplaceString(formattedMessage, "%minecount%", std::to_string(minecount));
    }

    return formattedMessage;
}

// A shortcut to get the amount of mines that are in play
int UselessMine::getMineCount()
{
    return activeMines.size();
}

// Remove all of the mines belonging to a player
void UselessMine::removeAllMines(int playerID)
{
    // Go through all of the mines
    for (int i = 0; i < getMineCount(); i++)
    {
        // Quick access mine
        Mine &currentMine = activeMines.at(i);

        // If the mine belongs to the player, remove it
        if (currentMine.owner == playerID)
        {
            removeMine(i);
        }
    }
}

// A shortcut to remove a mine from play
void UselessMine::removeMine(int mineIndex)
{
    activeMines.erase(activeMines.begin() + mineIndex);
}

// A shortcut to set a mine
void UselessMine::setMine(int owner, float pos[3], bz_eTeamType team)
{
    // Remove their flag because it's going to be a US flag
    bz_removePlayerFlag(owner);

    // Push the new mine
    Mine newMine(owner, pos, team);
    activeMines.push_back(newMine);
}<commit_msg>Make mine detection less sensitive & OpenFFA support<commit_after>/*
UselessMine
    Copyright (C) 2014 Vladimir "allejo" Jimenez

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

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

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <fstream>
#include <memory>
#include <stdlib.h>
#include <string>

#include "bzfsAPI.h"
#include "bztoolkit/bzToolkitAPI.h"

// Define plugin name
const std::string PLUGIN_NAME = "Useless Mine";

// Define plugin version numbering
const int MAJOR = 1;
const int MINOR = 0;
const int REV = 0;
const int BUILD = 28;

// A function to replace substrings in a string with another substring
std::string ReplaceString(std::string subject, const std::string& search, const std::string& replace)
{
    size_t pos = 0;

    while ((pos = subject.find(search, pos)) != std::string::npos)
    {
        subject.replace(pos, search.length(), replace);
        pos += replace.length();
    }

    return subject;
}

class UselessMine : public bz_Plugin, public bz_CustomSlashCommandHandler
{
public:
    virtual const char* Name ();
    virtual void Init (const char* config);
    virtual void Event (bz_EventData *eventData);
    virtual void Cleanup (void);

    virtual bool SlashCommand (int playerID, bz_ApiString, bz_ApiString, bz_APIStringList*);

    virtual int         getMineCount ();
    virtual void        removeAllMines (int playerID),
                        removeMine (int mineIndex),
                        setMine (int owner, float pos[3], bz_eTeamType team);
    virtual std::string formatDeathMessage (std::string msg, std::string victim, std::string owner);

    // The information each mine will contain
    struct Mine
    {
        int owner;             // The owner of the mine and the victim, respectively

        float x, y, z;         // The coordinates of where the mine was placed

        bz_eTeamType team;     // The team of the owner

        bool detonated;        // Whether or not the mine has been detonated; to prepare it for removal from play

        double detonationTime; // The time the mine was detonated

        Mine (int _owner, float _pos[3], bz_eTeamType _team) :
            owner(_owner),
            x(_pos[0]),
            y(_pos[1]),
            z(_pos[2]),
            team(_team),
            detonated(false)
        {}
    };

    std::vector<Mine>        activeMines;   // A vector that will store all of the mines that are in play
    std::vector<std::string> deathMessages; // A vector that will store all of the witty death messages

    std::string deathMessagesFile;

    double bzdb_SpawnSafetyTime, // The BZDB variable that will store the amount of seconds a player has before a mine is detonated
           playerSpawnTime[256]; // The time of a player's last spawn time used to calculate their safety from detonation

    bool   openFFA;
};

BZ_PLUGIN(UselessMine)

const char* UselessMine::Name (void)
{
    static std::string pluginBuild = "";

    if (!pluginBuild.size())
    {
        std::ostringstream pluginBuildStream;

        pluginBuildStream << PLUGIN_NAME << " " << MAJOR << "." << MINOR << "." << REV << " (" << BUILD << ")";
        pluginBuild = pluginBuildStream.str();
    }

    return pluginBuild.c_str();
}

void UselessMine::Init (const char* commandLine)
{
    // Register our events with Register()
    Register(bz_eFlagGrabbedEvent);
    Register(bz_ePlayerDieEvent);
    Register(bz_ePlayerPartEvent);
    Register(bz_ePlayerSpawnEvent);
    Register(bz_ePlayerUpdateEvent);

    // Register our custom slash commands
    bz_registerCustomSlashCommand("mine", this);

    // Set some custom BZDB variables
    bzdb_SpawnSafetyTime = bztk_registerCustomDoubleBZDB("_mineSafetyTime", 5.0);

    // Save the location of the file so we can reload after
    deathMessagesFile = commandLine;

    // We'll ignore team colors if it's an Open FFA game
    openFFA = (bz_getGameType() == eOpenFFAGame);

    // Open the file of witty death messages
    std::ifstream file(commandLine);
    std::string   currentLine;

    // If the file exists, read each line
    if (file)
    {
        // Push each line into the deathMessages vector
        while (std::getline(file, currentLine))
        {
            deathMessages.push_back(currentLine);
        }

        bz_debugMessagef(2, "DEBUG :: Useless Mine :: %d witty messages were loaded", deathMessages.size());
    }
    else
    {
        bz_debugMessage(2, "WARNING :: Useless Mine :: No witty death messages were loaded");
    }
}

void UselessMine::Cleanup (void)
{
    Flush(); // Clean up all the events

    // Clean up our custom slash commands
    bz_removeCustomSlashCommand("mine");
}

void UselessMine::Event (bz_EventData *eventData)
{
    switch (eventData->eventType)
    {
        case bz_eFlagGrabbedEvent: // This event is called each time a flag is grabbed by a player
        {
            bz_FlagGrabbedEventData_V1* flagGrabData = (bz_FlagGrabbedEventData_V1*)eventData;

            // If the user grabbed the Useless flag, let them know they can place a mine
            if (strcmp(flagGrabData->flagType, "US") == 0)
            {
                bz_sendTextMessage(BZ_SERVER, flagGrabData->playerID, "You grabbed a Useless flag! Type /mine at any time to set a useless mine!");
            }
        }
        break;

        case bz_ePlayerDieEvent: // This event is called each time a tank is killed.
        {
            bz_PlayerDieEventData_V1* dieData = (bz_PlayerDieEventData_V1*)eventData;

            int playerID = dieData->playerID;

            // Loop through all the mines in play
            for (int i = 0; i < getMineCount(); i++)
            {
                // Create a local variable for easy access
                Mine &detonatedMine = activeMines.at(i);

                // Check if the mine has already been detonated
                if (detonatedMine.detonated)
                {
		    // Check if the player who just died was killed by the server
		    if (dieData->killerID == 253)
		    {
			// Easy to access variables
			float  deathPos[3] = {dieData->state.pos[0], dieData->state.pos[1], dieData->state.pos[2]};
			double shockRange = bz_getBZDBDouble("_shockOutRadius") * 0.75;

			// Check if the player died inside of the mine radius
			if ((deathPos[0] > detonatedMine.x - shockRange && deathPos[0] < detonatedMine.x + shockRange) &&
			    (deathPos[1] > detonatedMine.y - shockRange && deathPos[1] < detonatedMine.y + shockRange) &&
			    (deathPos[2] > detonatedMine.z - shockRange && deathPos[2] < detonatedMine.z + shockRange))
			{
			    // Attribute the kill to the mine owner
			    dieData->killerID = detonatedMine.owner;

			    // Only get a death messages if death messages exist and the player who died is now also the mine owner
			    if (!deathMessages.empty() && playerID != detonatedMine.owner)
			    {
				// The random number used to fetch a random taunting death message
				int randomNumber = rand() % deathMessages.size();

				// Get the callsigns of the players
				const char* owner  = bz_getPlayerCallsign(detonatedMine.owner);
				const char* victim = bz_getPlayerCallsign(playerID);

				// Get a random death message
				std::string deathMessage = deathMessages.at(randomNumber);
				bz_sendTextMessage(BZ_SERVER, BZ_ALLUSERS, formatDeathMessage(deathMessage, victim, owner).c_str());
			    }

			    break;
			}
                    }
                    else
                    {
                        removeMine(i);
                    }
                }
            }
        }
        break;

        case bz_ePlayerPartEvent: // This event is called each time a player leaves a game
        {
            bz_PlayerJoinPartEventData_V1* partData = (bz_PlayerJoinPartEventData_V1*)eventData;

            int playerID = partData->playerID;

            // Remove all the mines belonging to the player who just left
            removeAllMines(playerID);
        }
        break;

        case bz_ePlayerSpawnEvent: // This event is called each time a playing tank is being spawned into the world
        {
            bz_PlayerSpawnEventData_V1* spawnData = (bz_PlayerSpawnEventData_V1*)eventData;

            int playerID = spawnData->playerID;

            // Save the time the player spawned last
            playerSpawnTime[playerID] = bz_getCurrentTime();
        }
        break;

        case bz_ePlayerUpdateEvent: // This event is called each time a player sends an update to the server
        {
            bz_PlayerUpdateEventData_V1* updateData = (bz_PlayerUpdateEventData_V1*)eventData;

            int playerID = updateData->playerID;

            // Loop through all of the players
            for (int i = 0; i < getMineCount(); i++)
            {
                // Make an easy access mine
                Mine &currentMine = activeMines.at(i);

                std::unique_ptr<bz_BasePlayerRecord> pr(bz_getPlayerByIndex(playerID));

                // If the mine owner is not the player triggering the mine (so no self kills) and the player is a rogue or does is an enemy team relative to the mine owner
                if (currentMine.owner != playerID && (pr->team == eRogueTeam || pr->team != currentMine.team || openFFA) && pr->spawned)
                {
                    // Make easy to access variables
                    float  playerPos[3] = {updateData->state.pos[0], updateData->state.pos[1], updateData->state.pos[2]};
                    double shockRange   = bz_getBZDBDouble("_shockOutRadius") * 0.75;

                    // Check if the player is in the detonation range
                    if ((playerPos[0] > currentMine.x - shockRange && playerPos[0] < currentMine.x + shockRange) &&
                        (playerPos[1] > currentMine.y - shockRange && playerPos[1] < currentMine.y + shockRange) &&
                        (playerPos[2] > currentMine.z - shockRange && playerPos[2] < currentMine.z + shockRange) &&
                        playerSpawnTime[playerID] + bzdb_SpawnSafetyTime <= bz_getCurrentTime())
                    {
                        // Check that the mine owner exists and is not an observer
                        if (bztk_isValidPlayerID(currentMine.owner) && bz_getPlayerTeam(currentMine.owner) != eObservers)
                        {
                            // Get the current mine position
                            float minePos[3] = {currentMine.x, currentMine.y, currentMine.z};

                            // Only detonate a mine once
                            if (!currentMine.detonated)
                            {
                                currentMine.detonated = true;
                                currentMine.detonationTime = bz_getCurrentTime();

                                // BOOM!
                                bz_fireWorldWep("SW", 2.0, BZ_SERVER, minePos, 0, 0, 0, currentMine.team);
                            }
                        }
                        // Just in case the player doesn't exist or is an observer, then remove the mine because it shouldn't be there
                        else
                        {
                            removeMine(i);
                        }

                        break;
                    }
                }
            }
        }
        break;

        default: break;
    }
}

bool UselessMine::SlashCommand(int playerID, bz_ApiString command, bz_ApiString /*message*/, bz_APIStringList *params)
{
    if (command == "mine")
    {
        std::unique_ptr<bz_BasePlayerRecord> playerRecord(bz_getPlayerByIndex(playerID));

        // If the player is not an observer, they let them proceed to the next check
        if (playerRecord->team != eObservers)
        {
            // Check if the player has the Useless flag
            if (playerRecord->currentFlag == "USeless (+US)")
            {
                // Store their current position
                float currentPosition[3] = {playerRecord->lastKnownState.pos[0], playerRecord->lastKnownState.pos[1], playerRecord->lastKnownState.pos[2]};

                setMine(playerID, currentPosition, playerRecord->team);
            }
            else
            {
                bz_sendTextMessage(BZ_SERVER, playerID, "You can't place a mine without the Useless flag!");
            }
        }
        else
        {
            bz_sendTextMessage(BZ_SERVER, playerID, "Silly observer, you can't place a mine.");
        }

        return true;
    }

    return true;
}

// A function to format death messages in order to replace placeholders with callsigns and values
std::string UselessMine::formatDeathMessage(std::string msg, std::string victim, std::string owner)
{
    // Replace the %victim% and %owner% placeholders
    std::string formattedMessage = ReplaceString(ReplaceString(msg, "%victim%", victim), "%owner%", owner);

    // If the message has a %minecount%, then replace it
    if (formattedMessage.find("%minecount%") != std::string::npos)
    {
        // Subtract one from the mine count because the mine we're announcing hasn't beeb removed yet
        int minecount = (getMineCount() == 0) ? 0 : getMineCount() - 1;

        formattedMessage = ReplaceString(formattedMessage, "%minecount%", std::to_string(minecount));
    }

    return formattedMessage;
}

// A shortcut to get the amount of mines that are in play
int UselessMine::getMineCount()
{
    return activeMines.size();
}

// Remove all of the mines belonging to a player
void UselessMine::removeAllMines(int playerID)
{
    // Go through all of the mines
    for (int i = 0; i < getMineCount(); i++)
    {
        // Quick access mine
        Mine &currentMine = activeMines.at(i);

        // If the mine belongs to the player, remove it
        if (currentMine.owner == playerID)
        {
            removeMine(i);
        }
    }
}

// A shortcut to remove a mine from play
void UselessMine::removeMine(int mineIndex)
{
    activeMines.erase(activeMines.begin() + mineIndex);
}

// A shortcut to set a mine
void UselessMine::setMine(int owner, float pos[3], bz_eTeamType team)
{
    // Remove their flag because it's going to be a US flag
    bz_removePlayerFlag(owner);

    // Push the new mine
    Mine newMine(owner, pos, team);
    activeMines.push_back(newMine);
}<|endoftext|>