<commit_before>// Copyright (c) 2011 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/webui/options/password_manager_handler.h"

#include "base/callback.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/glue/password_form.h"

PasswordManagerHandler::PasswordManagerHandler()
    : ALLOW_THIS_IN_INITIALIZER_LIST(populater_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(exception_populater_(this)) {
}

PasswordManagerHandler::~PasswordManagerHandler() {
  PasswordStore* store = GetPasswordStore();
  if (store)
    store->RemoveObserver(this);
}

void PasswordManagerHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  DCHECK(localized_strings);

  static const OptionsStringResource resources[] = {
    { "savedPasswordsTitle",
      IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE },
    { "passwordExceptionsTitle",
      IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE },
    { "passwordSearchPlaceholder",
      IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS },
    { "passwordShowButton",
      IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON },
    { "passwordHideButton",
      IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON },
    { "passwordsSiteColumn",
      IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN },
    { "passwordsUsernameColumn",
      IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN },
    { "passwordsRemoveButton",
      IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON },
    { "passwordsNoPasswordsDescription",
     IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION },
    { "passwordsNoExceptionsDescription",
     IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION },
    { "passwordsRemoveAllButton",
      IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON },
    { "passwordsRemoveAllTitle",
      IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS },
    { "passwordsRemoveAllWarning",
      IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS },
  };

  RegisterStrings(localized_strings, resources, arraysize(resources));
  RegisterTitle(localized_strings, "passwordsPage",
                IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE);

  localized_strings->SetString("passwordManagerLearnMoreURL",
      google_util::AppendGoogleLocaleParam(
          GURL(chrome::kPasswordManagerLearnMoreURL)).spec());
}

void PasswordManagerHandler::Initialize() {
  show_passwords_.Init(prefs::kPasswordManagerAllowShowPasswords,
                       web_ui_->GetProfile()->GetPrefs(), this);
  // We should not cache web_ui_->GetProfile(). See crosbug.com/6304.
  PasswordStore* store = GetPasswordStore();
  if (store)
    store->AddObserver(this);
}

void PasswordManagerHandler::RegisterMessages() {
  DCHECK(web_ui_);

  web_ui_->RegisterMessageCallback("updatePasswordLists",
      NewCallback(this, &PasswordManagerHandler::UpdatePasswordLists));
  web_ui_->RegisterMessageCallback("removeSavedPassword",
      NewCallback(this, &PasswordManagerHandler::RemoveSavedPassword));
  web_ui_->RegisterMessageCallback("removePasswordException",
      NewCallback(this, &PasswordManagerHandler::RemovePasswordException));
  web_ui_->RegisterMessageCallback("removeAllSavedPasswords",
      NewCallback(this, &PasswordManagerHandler::RemoveAllSavedPasswords));
  web_ui_->RegisterMessageCallback("removeAllPasswordExceptions", NewCallback(
      this, &PasswordManagerHandler::RemoveAllPasswordExceptions));
}

void PasswordManagerHandler::OnLoginsChanged() {
  UpdatePasswordLists(NULL);
}

PasswordStore* PasswordManagerHandler::GetPasswordStore() {
  return web_ui_->GetProfile()->GetPasswordStore(Profile::EXPLICIT_ACCESS);
}

void PasswordManagerHandler::Observe(int type,
                                     const NotificationSource& source,
                                     const NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_PREF_CHANGED) {
    std::string* pref_name = Details<std::string>(details).ptr();
    if (*pref_name == prefs::kPasswordManagerAllowShowPasswords) {
      UpdatePasswordLists(NULL);
    }
  }

  OptionsPageUIHandler::Observe(type, source, details);
}

void PasswordManagerHandler::UpdatePasswordLists(const ListValue* args) {
  // Reset the current lists.
  password_list_.reset();
  password_exception_list_.reset();

  languages_ =
      web_ui_->GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
  populater_.Populate();
  exception_populater_.Populate();
}

void PasswordManagerHandler::RemoveSavedPassword(const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  std::string string_value = UTF16ToUTF8(ExtractStringValue(args));
  int index;
  if (base::StringToInt(string_value, &index) && index >= 0 &&
      static_cast<size_t>(index) < password_list_.size())
    store->RemoveLogin(*password_list_[index]);
}

void PasswordManagerHandler::RemovePasswordException(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  std::string string_value = UTF16ToUTF8(ExtractStringValue(args));
  int index;
  if (base::StringToInt(string_value, &index) && index >= 0 &&
      static_cast<size_t>(index) < password_exception_list_.size())
    store->RemoveLogin(*password_exception_list_[index]);
}

void PasswordManagerHandler::RemoveAllSavedPasswords(
    const ListValue* args) {
  // TODO(jhawkins): This will cause a list refresh for every password in the
  // list. Add PasswordStore::RemoveAllLogins().
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  for (size_t i = 0; i < password_list_.size(); ++i)
    store->RemoveLogin(*password_list_[i]);
}

void PasswordManagerHandler::RemoveAllPasswordExceptions(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  for (size_t i = 0; i < password_exception_list_.size(); ++i)
    store->RemoveLogin(*password_exception_list_[i]);
}

void PasswordManagerHandler::SetPasswordList() {
  ListValue entries;
  bool show_passwords = *show_passwords_;
  string16 empty;
  for (size_t i = 0; i < password_list_.size(); ++i) {
    ListValue* entry = new ListValue();
    entry->Append(new StringValue(net::FormatUrl(password_list_[i]->origin,
                                                 languages_)));
    entry->Append(new StringValue(password_list_[i]->username_value));
    entry->Append(new StringValue(
        show_passwords ? password_list_[i]->password_value : empty));
    entries.Append(entry);
  }

  web_ui_->CallJavascriptFunction("PasswordManager.setSavedPasswordsList",
                                  entries);
}

void PasswordManagerHandler::SetPasswordExceptionList() {
  ListValue entries;
  for (size_t i = 0; i < password_exception_list_.size(); ++i) {
    entries.Append(new StringValue(
        net::FormatUrl(password_exception_list_[i]->origin, languages_)));
  }

  web_ui_->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList",
                                  entries);
}

PasswordManagerHandler::ListPopulater::ListPopulater(
    PasswordManagerHandler* page)
    : page_(page),
      pending_login_query_(0) {
}

PasswordManagerHandler::ListPopulater::~ListPopulater() {
}

PasswordManagerHandler::PasswordListPopulater::PasswordListPopulater(
    PasswordManagerHandler* page) : ListPopulater(page) {
}

void PasswordManagerHandler::PasswordListPopulater::Populate() {
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL) {
    if (pending_login_query_)
      store->CancelRequest(pending_login_query_);

    pending_login_query_ = store->GetAutofillableLogins(this);
  } else {
    LOG(ERROR) << "No password store! Cannot display passwords.";
  }
}

void PasswordManagerHandler::PasswordListPopulater::
    OnPasswordStoreRequestDone(
        CancelableRequestProvider::Handle handle,
        const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_list_.reset();
  page_->password_list_.insert(page_->password_list_.end(),
                               result.begin(), result.end());
  page_->SetPasswordList();
}

PasswordManagerHandler::PasswordExceptionListPopulater::
    PasswordExceptionListPopulater(PasswordManagerHandler* page)
        : ListPopulater(page) {
}

void PasswordManagerHandler::PasswordExceptionListPopulater::Populate() {
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL) {
    if (pending_login_query_)
      store->CancelRequest(pending_login_query_);

    pending_login_query_ = store->GetBlacklistLogins(this);
  } else {
    LOG(ERROR) << "No password store! Cannot display exceptions.";
  }
}

void PasswordManagerHandler::PasswordExceptionListPopulater::
    OnPasswordStoreRequestDone(
        CancelableRequestProvider::Handle handle,
        const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_exception_list_.reset();
  page_->password_exception_list_.insert(page_->password_exception_list_.end(),
                                         result.begin(), result.end());
  page_->SetPasswordExceptionList();
}
<commit_msg>WebUI: work around a crash triggered by a specific navigation in tabbed options. This does not fix the root cause, which is explained in comment 3 on bug 88986. TEST=pressing the back button after closing the password manager does not crash BUG=88986<commit_after>// Copyright (c) 2011 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/webui/options/password_manager_handler.h"

#include "base/callback.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/common/notification_details.h"
#include "content/common/notification_source.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "net/base/net_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "webkit/glue/password_form.h"

PasswordManagerHandler::PasswordManagerHandler()
    : ALLOW_THIS_IN_INITIALIZER_LIST(populater_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(exception_populater_(this)) {
}

PasswordManagerHandler::~PasswordManagerHandler() {
  PasswordStore* store = GetPasswordStore();
  if (store)
    store->RemoveObserver(this);
}

void PasswordManagerHandler::GetLocalizedValues(
    DictionaryValue* localized_strings) {
  DCHECK(localized_strings);

  static const OptionsStringResource resources[] = {
    { "savedPasswordsTitle",
      IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE },
    { "passwordExceptionsTitle",
      IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE },
    { "passwordSearchPlaceholder",
      IDS_PASSWORDS_PAGE_SEARCH_PASSWORDS },
    { "passwordShowButton",
      IDS_PASSWORDS_PAGE_VIEW_SHOW_BUTTON },
    { "passwordHideButton",
      IDS_PASSWORDS_PAGE_VIEW_HIDE_BUTTON },
    { "passwordsSiteColumn",
      IDS_PASSWORDS_PAGE_VIEW_SITE_COLUMN },
    { "passwordsUsernameColumn",
      IDS_PASSWORDS_PAGE_VIEW_USERNAME_COLUMN },
    { "passwordsRemoveButton",
      IDS_PASSWORDS_PAGE_VIEW_REMOVE_BUTTON },
    { "passwordsNoPasswordsDescription",
     IDS_PASSWORDS_PAGE_VIEW_NO_PASSWORDS_DESCRIPTION },
    { "passwordsNoExceptionsDescription",
     IDS_PASSWORDS_PAGE_VIEW_NO_EXCEPTIONS_DESCRIPTION },
    { "passwordsRemoveAllButton",
      IDS_PASSWORDS_PAGE_VIEW_REMOVE_ALL_BUTTON },
    { "passwordsRemoveAllTitle",
      IDS_PASSWORDS_PAGE_VIEW_CAPTION_DELETE_ALL_PASSWORDS },
    { "passwordsRemoveAllWarning",
      IDS_PASSWORDS_PAGE_VIEW_TEXT_DELETE_ALL_PASSWORDS },
  };

  RegisterStrings(localized_strings, resources, arraysize(resources));
  RegisterTitle(localized_strings, "passwordsPage",
                IDS_PASSWORDS_EXCEPTIONS_WINDOW_TITLE);

  localized_strings->SetString("passwordManagerLearnMoreURL",
      google_util::AppendGoogleLocaleParam(
          GURL(chrome::kPasswordManagerLearnMoreURL)).spec());
}

void PasswordManagerHandler::Initialize() {
  // Due to the way that handlers are (re)initialized under certain types of
  // navigation, we may already be initialized. (See bugs 88986 and 86448.)
  // If this is the case, return immediately. This is a hack.
  // TODO(mdm): remove this hack once it is no longer necessary.
  if (!show_passwords_.GetPrefName().empty())
    return;

  show_passwords_.Init(prefs::kPasswordManagerAllowShowPasswords,
                       web_ui_->GetProfile()->GetPrefs(), this);
  // We should not cache web_ui_->GetProfile(). See crosbug.com/6304.
  PasswordStore* store = GetPasswordStore();
  if (store)
    store->AddObserver(this);
}

void PasswordManagerHandler::RegisterMessages() {
  DCHECK(web_ui_);

  web_ui_->RegisterMessageCallback("updatePasswordLists",
      NewCallback(this, &PasswordManagerHandler::UpdatePasswordLists));
  web_ui_->RegisterMessageCallback("removeSavedPassword",
      NewCallback(this, &PasswordManagerHandler::RemoveSavedPassword));
  web_ui_->RegisterMessageCallback("removePasswordException",
      NewCallback(this, &PasswordManagerHandler::RemovePasswordException));
  web_ui_->RegisterMessageCallback("removeAllSavedPasswords",
      NewCallback(this, &PasswordManagerHandler::RemoveAllSavedPasswords));
  web_ui_->RegisterMessageCallback("removeAllPasswordExceptions", NewCallback(
      this, &PasswordManagerHandler::RemoveAllPasswordExceptions));
}

void PasswordManagerHandler::OnLoginsChanged() {
  UpdatePasswordLists(NULL);
}

PasswordStore* PasswordManagerHandler::GetPasswordStore() {
  return web_ui_->GetProfile()->GetPasswordStore(Profile::EXPLICIT_ACCESS);
}

void PasswordManagerHandler::Observe(int type,
                                     const NotificationSource& source,
                                     const NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_PREF_CHANGED) {
    std::string* pref_name = Details<std::string>(details).ptr();
    if (*pref_name == prefs::kPasswordManagerAllowShowPasswords) {
      UpdatePasswordLists(NULL);
    }
  }

  OptionsPageUIHandler::Observe(type, source, details);
}

void PasswordManagerHandler::UpdatePasswordLists(const ListValue* args) {
  // Reset the current lists.
  password_list_.reset();
  password_exception_list_.reset();

  languages_ =
      web_ui_->GetProfile()->GetPrefs()->GetString(prefs::kAcceptLanguages);
  populater_.Populate();
  exception_populater_.Populate();
}

void PasswordManagerHandler::RemoveSavedPassword(const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  std::string string_value = UTF16ToUTF8(ExtractStringValue(args));
  int index;
  if (base::StringToInt(string_value, &index) && index >= 0 &&
      static_cast<size_t>(index) < password_list_.size())
    store->RemoveLogin(*password_list_[index]);
}

void PasswordManagerHandler::RemovePasswordException(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  std::string string_value = UTF16ToUTF8(ExtractStringValue(args));
  int index;
  if (base::StringToInt(string_value, &index) && index >= 0 &&
      static_cast<size_t>(index) < password_exception_list_.size())
    store->RemoveLogin(*password_exception_list_[index]);
}

void PasswordManagerHandler::RemoveAllSavedPasswords(
    const ListValue* args) {
  // TODO(jhawkins): This will cause a list refresh for every password in the
  // list. Add PasswordStore::RemoveAllLogins().
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  for (size_t i = 0; i < password_list_.size(); ++i)
    store->RemoveLogin(*password_list_[i]);
}

void PasswordManagerHandler::RemoveAllPasswordExceptions(
    const ListValue* args) {
  PasswordStore* store = GetPasswordStore();
  if (!store)
    return;
  for (size_t i = 0; i < password_exception_list_.size(); ++i)
    store->RemoveLogin(*password_exception_list_[i]);
}

void PasswordManagerHandler::SetPasswordList() {
  // Due to the way that handlers are (re)initialized under certain types of
  // navigation, we may not be initialized yet. (See bugs 88986 and 86448.)
  // If this is the case, initialize on demand. This is a hack.
  // TODO(mdm): remove this hack once it is no longer necessary.
  if (show_passwords_.GetPrefName().empty())
    Initialize();

  ListValue entries;
  bool show_passwords = *show_passwords_;
  string16 empty;
  for (size_t i = 0; i < password_list_.size(); ++i) {
    ListValue* entry = new ListValue();
    entry->Append(new StringValue(net::FormatUrl(password_list_[i]->origin,
                                                 languages_)));
    entry->Append(new StringValue(password_list_[i]->username_value));
    entry->Append(new StringValue(
        show_passwords ? password_list_[i]->password_value : empty));
    entries.Append(entry);
  }

  web_ui_->CallJavascriptFunction("PasswordManager.setSavedPasswordsList",
                                  entries);
}

void PasswordManagerHandler::SetPasswordExceptionList() {
  ListValue entries;
  for (size_t i = 0; i < password_exception_list_.size(); ++i) {
    entries.Append(new StringValue(
        net::FormatUrl(password_exception_list_[i]->origin, languages_)));
  }

  web_ui_->CallJavascriptFunction("PasswordManager.setPasswordExceptionsList",
                                  entries);
}

PasswordManagerHandler::ListPopulater::ListPopulater(
    PasswordManagerHandler* page)
    : page_(page),
      pending_login_query_(0) {
}

PasswordManagerHandler::ListPopulater::~ListPopulater() {
}

PasswordManagerHandler::PasswordListPopulater::PasswordListPopulater(
    PasswordManagerHandler* page) : ListPopulater(page) {
}

void PasswordManagerHandler::PasswordListPopulater::Populate() {
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL) {
    if (pending_login_query_)
      store->CancelRequest(pending_login_query_);

    pending_login_query_ = store->GetAutofillableLogins(this);
  } else {
    LOG(ERROR) << "No password store! Cannot display passwords.";
  }
}

void PasswordManagerHandler::PasswordListPopulater::
    OnPasswordStoreRequestDone(
        CancelableRequestProvider::Handle handle,
        const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_list_.reset();
  page_->password_list_.insert(page_->password_list_.end(),
                               result.begin(), result.end());
  page_->SetPasswordList();
}

PasswordManagerHandler::PasswordExceptionListPopulater::
    PasswordExceptionListPopulater(PasswordManagerHandler* page)
        : ListPopulater(page) {
}

void PasswordManagerHandler::PasswordExceptionListPopulater::Populate() {
  PasswordStore* store = page_->GetPasswordStore();
  if (store != NULL) {
    if (pending_login_query_)
      store->CancelRequest(pending_login_query_);

    pending_login_query_ = store->GetBlacklistLogins(this);
  } else {
    LOG(ERROR) << "No password store! Cannot display exceptions.";
  }
}

void PasswordManagerHandler::PasswordExceptionListPopulater::
    OnPasswordStoreRequestDone(
        CancelableRequestProvider::Handle handle,
        const std::vector<webkit_glue::PasswordForm*>& result) {
  DCHECK_EQ(pending_login_query_, handle);
  pending_login_query_ = 0;
  page_->password_exception_list_.reset();
  page_->password_exception_list_.insert(page_->password_exception_list_.end(),
                                         result.begin(), result.end());
  page_->SetPasswordExceptionList();
}
<|endoftext|>


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

#include "base/file_path.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/ui_test_utils.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"

namespace {

class MouseLeaveTest : public UITest {
 public:
  MouseLeaveTest() {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  DISALLOW_COPY_AND_ASSIGN(MouseLeaveTest);
};

TEST_F(MouseLeaveTest, TestOnMouseOut) {
  GURL test_url = ui_test_utils::GetTestUrl(
      FilePath(FilePath::kCurrentDirectory),
      FilePath(FILE_PATH_LITERAL("mouseleave.html")));

  scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0);
  ASSERT_TRUE(browser.get());
  scoped_refptr<WindowProxy> window = browser->GetWindow();
  ASSERT_TRUE(window.get());
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());

  gfx::Rect tab_view_bounds;
  ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER, &tab_view_bounds,
                                    true));
  gfx::Point in_content_point(
      tab_view_bounds.x() + tab_view_bounds.width() / 2,
      tab_view_bounds.y() + 10);
  gfx::Point above_content_point(
      tab_view_bounds.x() + tab_view_bounds.width() / 2,
      tab_view_bounds.y() - 2);

  // Start by moving the point just above the content.
  ASSERT_TRUE(window->SimulateOSMouseMove(above_content_point));

  // Navigate to the test html page.
  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(test_url));

  const int timeout_ms = 5 * action_max_timeout_ms();

  // Wait for the onload() handler to complete so we can do the
  // next part of the test.
  ASSERT_TRUE(WaitUntilCookieValue(
      tab.get(), test_url, "__state", timeout_ms, "initial"));

  // Move the cursor to the top-center of the content, which will trigger
  // a javascript onMouseOver event.
  ASSERT_TRUE(window->SimulateOSMouseMove(in_content_point));

  // Wait on the correct intermediate value of the cookie.
  ASSERT_TRUE(WaitUntilCookieValue(
      tab.get(), test_url, "__state", timeout_ms, "initial,entered"));

  // Move the cursor above the content again, which should trigger
  // a javascript onMouseOut event.
  ASSERT_TRUE(window->SimulateOSMouseMove(above_content_point));

  // Wait on the correct final value of the cookie.
  ASSERT_TRUE(WaitUntilCookieValue(
      tab.get(), test_url, "__state", timeout_ms, "initial,entered,left"));
}

}  // namespace
<commit_msg>Mac: Disable TestOnMouseOut, it requires more automation provider support than there is atm.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_path.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/ui_test_utils.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "googleurl/src/gurl.h"

namespace {

class MouseLeaveTest : public UITest {
 public:
  MouseLeaveTest() {
    dom_automation_enabled_ = true;
    show_window_ = true;
  }

  DISALLOW_COPY_AND_ASSIGN(MouseLeaveTest);
};

#if defined(OS_MACOSX)
// Missing automation provider support: http://crbug.com/45892
#define MAYBE_TestOnMouseOut FAILS_TestOnMouseOut
#else
#define MAYBE_TestOnMouseOut TestOnMouseOut
#endif
TEST_F(MouseLeaveTest, MAYBE_TestOnMouseOut) {
  GURL test_url = ui_test_utils::GetTestUrl(
      FilePath(FilePath::kCurrentDirectory),
      FilePath(FILE_PATH_LITERAL("mouseleave.html")));

  scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0);
  ASSERT_TRUE(browser.get());
  scoped_refptr<WindowProxy> window = browser->GetWindow();
  ASSERT_TRUE(window.get());
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());

  gfx::Rect tab_view_bounds;
  ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_CONTAINER, &tab_view_bounds,
                                    true));
  gfx::Point in_content_point(
      tab_view_bounds.x() + tab_view_bounds.width() / 2,
      tab_view_bounds.y() + 10);
  gfx::Point above_content_point(
      tab_view_bounds.x() + tab_view_bounds.width() / 2,
      tab_view_bounds.y() - 2);

  // Start by moving the point just above the content.
  ASSERT_TRUE(window->SimulateOSMouseMove(above_content_point));

  // Navigate to the test html page.
  ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, tab->NavigateToURL(test_url));

  const int timeout_ms = 5 * action_max_timeout_ms();

  // Wait for the onload() handler to complete so we can do the
  // next part of the test.
  ASSERT_TRUE(WaitUntilCookieValue(
      tab.get(), test_url, "__state", timeout_ms, "initial"));

  // Move the cursor to the top-center of the content, which will trigger
  // a javascript onMouseOver event.
  ASSERT_TRUE(window->SimulateOSMouseMove(in_content_point));

  // Wait on the correct intermediate value of the cookie.
  ASSERT_TRUE(WaitUntilCookieValue(
      tab.get(), test_url, "__state", timeout_ms, "initial,entered"));

  // Move the cursor above the content again, which should trigger
  // a javascript onMouseOut event.
  ASSERT_TRUE(window->SimulateOSMouseMove(above_content_point));

  // Wait on the correct final value of the cookie.
  ASSERT_TRUE(WaitUntilCookieValue(
      tab.get(), test_url, "__state", timeout_ms, "initial,entered,left"));
}

}  // namespace
<|endoftext|>


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

#include "cnttransformonlineaccount.h"
#include "cntmodelextuids.h"

QList<CContactItemField *> CntTransformOnlineAccount::transformDetailL(const QContactDetail &detail)
{
    if(detail.definitionName() != QContactOnlineAccount::DefinitionName)
        User::Leave(KErrArgument);

    QList<CContactItemField *> fieldList;

	//cast to phonenumber
	const QContactOnlineAccount &onlineAccount(static_cast<const QContactOnlineAccount&>(detail));

	//get the subType
	QStringList subTypes = onlineAccount.subTypes();

	//create new field
	TPtrC fieldText(reinterpret_cast<const TUint16*>(onlineAccount.accountUri().utf16()));
	if(fieldText.Length()) {
	    CContactItemField* newField = CContactItemField::NewLC(KStorageTypeText);
	    newField->TextStorage()->SetTextL(fieldText);

	    //no subtype
	    if(!subTypes.count())
	    {
	        User::LeaveIfError(KErrArgument);
	    }

	    // online account
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeImpp))
	    {
	        newField->AddFieldTypeL(KUidContactFieldIMPP);
	        newField->SetMapping(KUidContactFieldVCardMapUnknown);
	    }

	    //internet
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeSipVoip))
	    {
	        newField->AddFieldTypeL(KUidContactFieldSIPID);
	        newField->SetMapping(KUidContactFieldVCardMapSIPID);
	        newField->AddFieldTypeL(KUidContactFieldVCardMapVOIP);
	    }

	    //share video
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeVideoShare))
	    {
	        newField->AddFieldTypeL(KUidContactFieldSIPID);
	        newField->SetMapping(KUidContactFieldVCardMapSIPID);
	        newField->AddFieldTypeL(KUidContactFieldVCardMapSWIS);
	    }

	    //sip
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeSip))
	    {
	        newField->AddFieldTypeL(KUidContactFieldSIPID);
	        newField->SetMapping(KUidContactFieldVCardMapSIPID);
	        newField->AddFieldTypeL(KUidContactFieldVCardMapSIPID);
	    }

	    else
	    {
	        User::LeaveIfError(KErrNotSupported);
	    }

	    //contexts
	    setContextsL(onlineAccount, *newField);

	    fieldList.append(newField);
	    CleanupStack::Pop(newField);

        // Transform Service Provider Text
	    TPtrC ServiceProviderText(reinterpret_cast<const TUint16*>(onlineAccount.serviceProvider().utf16()));
	         if(ServiceProviderText.Length()) {
	             CContactItemField* serviceProviderField = CContactItemField::NewLC(KStorageTypeText);
	             serviceProviderField->TextStorage()->SetTextL(ServiceProviderText);
	             serviceProviderField->AddFieldTypeL(KUidContactFieldServiceProvider);
	             fieldList.append(serviceProviderField);
	             CleanupStack::Pop(serviceProviderField);
	         }

	     // Transform presence informaiton
        TPtrC presenceText(reinterpret_cast<const TUint16*>(onlineAccount.presence().utf16()));
            if(presenceText.Length()) {
                QString presence = QString::number(encodePresence(onlineAccount.presence()));
                CContactItemField* presenceField = CContactItemField::NewLC(KStorageTypeText);
                TPtrC presenceEncodedText(reinterpret_cast<const TUint16*>(presence.utf16()));
                presenceField->TextStorage()->SetTextL(presenceEncodedText);
                presenceField->AddFieldTypeL(KUidContactFieldPresence);
                fieldList.append(presenceField);
                CleanupStack::Pop(presenceField);
            }

	     // Transform statusMessage
	     TPtrC statusMsgText(reinterpret_cast<const TUint16*>(onlineAccount.statusMessage().utf16()));
	         if(statusMsgText.Length()) {
	             CContactItemField* statusMsgField = CContactItemField::NewLC(KStorageTypeText);
	             statusMsgField->TextStorage()->SetTextL(statusMsgText);
	             statusMsgField->AddFieldTypeL(KUidContactFieldStatusMsg);
	             fieldList.append(statusMsgField);
	             CleanupStack::Pop(statusMsgField);
	         }
	}

	return fieldList;
}

QContactDetail *CntTransformOnlineAccount::transformItemField(const CContactItemField& field, const QContact &contact)
{
    Q_UNUSED(contact);

    QContactOnlineAccount *onlineAccount = new QContactOnlineAccount();
	CContactTextField* storage = field.TextStorage();
	QString onlineAccountString = QString::fromUtf16(storage->Text().Ptr(), storage->Text().Length());

	// Adding Online Account Detail.
    for (int i = 0; i < field.ContentType().FieldTypeCount(); i++) {

        //Account URI
        if (field.ContentType().ContainsFieldType(KUidContactFieldIMPP)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeImpp);
        }
        else if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapVOIP)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeSipVoip);
        }
        else if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapSWIS)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeVideoShare);
        }
        else if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapSIPID)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeSip);
        }
        //Service Provider
        else if (field.ContentType().FieldType(i) == KUidContactFieldServiceProvider) {
            onlineAccount->setServiceProvider(onlineAccountString);
        }
        //Presence
        else if (field.ContentType().FieldType(i) == KUidContactFieldPresence) {
            QString presenceInfo = decodePresence(onlineAccountString.toInt());
            onlineAccount->setPresence(presenceInfo);
        }
        //Status Message
        else if (field.ContentType().FieldType(i) == KUidContactFieldStatusMsg) {
            onlineAccount->setStatusMessage(onlineAccountString);
        }
    }

    // set context
	for (int i = 0; i < field.ContentType().FieldTypeCount(); i++) {
        setContexts(field.ContentType().FieldType(i), *onlineAccount);
	}

	return onlineAccount;
}

bool CntTransformOnlineAccount::supportsField(TUint32 fieldType) const
{
    bool ret = false;
    if (fieldType == KUidContactFieldSIPID.iUid ||
        fieldType == KUidContactFieldIMPP.iUid  ||
        fieldType == KUidContactFieldServiceProvider.iUid  ||
        fieldType == KUidContactFieldPresence.iUid  ||
        fieldType == KUidContactFieldStatusMsg.iUid )
    {
        ret = true;
    }
    return ret;
}

bool CntTransformOnlineAccount::supportsDetail(QString detailName) const
{
    bool ret = false;
    if (detailName == QContactOnlineAccount::DefinitionName) {
        ret = true;
    }
    return ret;
}

QList<TUid> CntTransformOnlineAccount::supportedSortingFieldTypes(QString detailFieldName) const
{
    QList<TUid> uids;
    if (detailFieldName == QContactOnlineAccount::FieldAccountUri) {
        uids << KUidContactFieldIMPP;
        uids << KUidContactFieldSIPID;
    }
    return uids;
}

/*!
 * Checks whether the subtype is supported
 *
 * \a subType The subtype to be checked
 * \return True if this subtype is supported
 */
bool CntTransformOnlineAccount::supportsSubType(const QString& subType) const
{
    if(QContactOnlineAccount::FieldSubTypes  == subType)
        return true;
    else
        return false;
}

/*!
 * Returns the filed id corresponding to a field
 *
 * \a fieldName The name of the supported field
 * \return fieldId for the fieldName, 0  if not supported
 */
quint32 CntTransformOnlineAccount::getIdForField(const QString& fieldName) const
{
    if (QContactOnlineAccount::FieldAccountUri  == fieldName)
        return 0;
    else if (QContactOnlineAccount::SubTypeSip == fieldName)
        return KUidContactFieldSIPID.iUid;
    else if (QContactOnlineAccount::SubTypeImpp == fieldName)
        return KUidContactFieldIMPP.iUid;
    else if (QContactOnlineAccount::SubTypeSipVoip == fieldName)
        return KUidContactFieldVCardMapVOIP.iUid;
    else if (QContactOnlineAccount::SubTypeVideoShare == fieldName)
        return KUidContactFieldVCardMapSWIS.iUid;
    else
        return 0;
}

/*!
 * Modifies the detail definitions. The default detail definitions are
 * queried from QContactManagerEngine::schemaDefinitions and then modified
 * with this function in the transform leaf classes.
 *
 * \a definitions The detail definitions to modify.
 * \a contactType The contact type the definitions apply for.
 */
void CntTransformOnlineAccount::detailDefinitions(QMap<QString, QContactDetailDefinition> &definitions, const QString& contactType) const
{
    Q_UNUSED(contactType);

    if(definitions.contains(QContactOnlineAccount::DefinitionName)) {
        QContactDetailDefinition d = definitions.value(QContactOnlineAccount::DefinitionName);
        QMap<QString, QContactDetailFieldDefinition> fields = d.fields();
        QContactDetailFieldDefinition f;

        // Don't support "ContextOther"
        f.setDataType(QVariant::StringList);
        f.setAllowableValues(QVariantList()
            << QLatin1String(QContactDetail::ContextHome)
            << QLatin1String(QContactDetail::ContextWork));
        fields[QContactDetail::FieldContext] = f;
        d.setFields(fields);

        // Replace original definitions
        definitions.insert(d.name(), d);
    }
}

/*!
 * Encode the presence information.
 * \a aPresence
 */
quint32 CntTransformOnlineAccount::encodePresence(QString aPresence)
{
    if (QContactOnlineAccount::PresenceAvailable  == aPresence)
        return CntTransformOnlineAccount::EPresenceAvailable;
    else if (QContactOnlineAccount::PresenceHidden == aPresence)
        return CntTransformOnlineAccount::EPresenceHidden;
    else if (QContactOnlineAccount::PresenceBusy == aPresence)
        return CntTransformOnlineAccount::EPresenceBusy;
    else if (QContactOnlineAccount::PresenceAway == aPresence)
        return CntTransformOnlineAccount::EPresenceAway;
    else if (QContactOnlineAccount::PresenceExtendedAway == aPresence)
        return CntTransformOnlineAccount::EPresenceExtendedAway;
    else if (QContactOnlineAccount::PresenceUnknown == aPresence)
        return CntTransformOnlineAccount::EPresenceUnknown;
    else
        return CntTransformOnlineAccount::EPresenceOffline;
}

/*!
 * Decode the presence information.
 * \a aPresence
 */
QString CntTransformOnlineAccount::decodePresence(quint32 aPresence)
{
    if (CntTransformOnlineAccount::EPresenceAvailable  == aPresence)
        return QContactOnlineAccount::PresenceAvailable;
    else if (CntTransformOnlineAccount::EPresenceHidden == aPresence)
        return QContactOnlineAccount::PresenceHidden;
    else if (CntTransformOnlineAccount::EPresenceBusy == aPresence)
        return QContactOnlineAccount::PresenceBusy;
    else if ( CntTransformOnlineAccount::EPresenceAway == aPresence)
        return QContactOnlineAccount::PresenceAway;
    else if ( CntTransformOnlineAccount::EPresenceExtendedAway == aPresence)
        return QContactOnlineAccount::PresenceExtendedAway;
    else if ( CntTransformOnlineAccount::EPresenceUnknown == aPresence)
        return QContactOnlineAccount::PresenceUnknown;
    else
        return QContactOnlineAccount::PresenceOffline;
}

#endif // SYMBIAN_BACKEND_USE_SQLITE

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

#include "cnttransformonlineaccount.h"
#include "cntmodelextuids.h"
#include "qcontactpresence.h"

QList<CContactItemField *> CntTransformOnlineAccount::transformDetailL(const QContactDetail &detail)
{
    if(detail.definitionName() != QContactOnlineAccount::DefinitionName)
        User::Leave(KErrArgument);

    QList<CContactItemField *> fieldList;

	//cast to phonenumber
	const QContactOnlineAccount &onlineAccount(static_cast<const QContactOnlineAccount&>(detail));

	//get the subType
	QStringList subTypes = onlineAccount.subTypes();

	//create new field
	TPtrC fieldText(reinterpret_cast<const TUint16*>(onlineAccount.accountUri().utf16()));
	if(fieldText.Length()) {
	    CContactItemField* newField = CContactItemField::NewLC(KStorageTypeText);
	    newField->TextStorage()->SetTextL(fieldText);

	    //no subtype
	    if(!subTypes.count())
	    {
	        User::LeaveIfError(KErrArgument);
	    }

	    // online account
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeImpp))
	    {
	        newField->AddFieldTypeL(KUidContactFieldIMPP);
	        newField->SetMapping(KUidContactFieldVCardMapUnknown);
	    }

	    //internet
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeSipVoip))
	    {
	        newField->AddFieldTypeL(KUidContactFieldSIPID);
	        newField->SetMapping(KUidContactFieldVCardMapSIPID);
	        newField->AddFieldTypeL(KUidContactFieldVCardMapVOIP);
	    }

	    //share video
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeVideoShare))
	    {
	        newField->AddFieldTypeL(KUidContactFieldSIPID);
	        newField->SetMapping(KUidContactFieldVCardMapSIPID);
	        newField->AddFieldTypeL(KUidContactFieldVCardMapSWIS);
	    }

	    //sip
	    else if (subTypes.contains(QContactOnlineAccount::SubTypeSip))
	    {
	        newField->AddFieldTypeL(KUidContactFieldSIPID);
	        newField->SetMapping(KUidContactFieldVCardMapSIPID);
	        newField->AddFieldTypeL(KUidContactFieldVCardMapSIPID);
	    }

	    else
	    {
	        User::LeaveIfError(KErrNotSupported);
	    }

	    //contexts
	    setContextsL(onlineAccount, *newField);

	    fieldList.append(newField);
	    CleanupStack::Pop(newField);

        // Transform Service Provider Text
	    TPtrC ServiceProviderText(reinterpret_cast<const TUint16*>(onlineAccount.serviceProvider().utf16()));
	         if(ServiceProviderText.Length()) {
	             CContactItemField* serviceProviderField = CContactItemField::NewLC(KStorageTypeText);
	             serviceProviderField->TextStorage()->SetTextL(ServiceProviderText);
	             serviceProviderField->AddFieldTypeL(KUidContactFieldServiceProvider);
	             fieldList.append(serviceProviderField);
	             CleanupStack::Pop(serviceProviderField);
	         }

                 //FIXME:no presence in onlineaccount anymore..
//	     // Transform presence informaiton
//        TPtrC presenceText(reinterpret_cast<const TUint16*>(onlineAccount.presence().utf16()));
//            if(presenceText.Length()) {
//                QString presence = QString::number(encodePresence(onlineAccount.presence()));
//                CContactItemField* presenceField = CContactItemField::NewLC(KStorageTypeText);
//                TPtrC presenceEncodedText(reinterpret_cast<const TUint16*>(presence.utf16()));
//                presenceField->TextStorage()->SetTextL(presenceEncodedText);
//                presenceField->AddFieldTypeL(KUidContactFieldPresence);
//                fieldList.append(presenceField);
//                CleanupStack::Pop(presenceField);
//            }

//	     // Transform statusMessage
//	     TPtrC statusMsgText(reinterpret_cast<const TUint16*>(onlineAccount.statusMessage().utf16()));
//	         if(statusMsgText.Length()) {
//	             CContactItemField* statusMsgField = CContactItemField::NewLC(KStorageTypeText);
//	             statusMsgField->TextStorage()->SetTextL(statusMsgText);
//	             statusMsgField->AddFieldTypeL(KUidContactFieldStatusMsg);
//	             fieldList.append(statusMsgField);
//	             CleanupStack::Pop(statusMsgField);
//	         }
	}

	return fieldList;
}

QContactDetail *CntTransformOnlineAccount::transformItemField(const CContactItemField& field, const QContact &contact)
{
    Q_UNUSED(contact);

    QContactOnlineAccount *onlineAccount = new QContactOnlineAccount();
	CContactTextField* storage = field.TextStorage();
	QString onlineAccountString = QString::fromUtf16(storage->Text().Ptr(), storage->Text().Length());

	// Adding Online Account Detail.
    for (int i = 0; i < field.ContentType().FieldTypeCount(); i++) {

        //Account URI
        if (field.ContentType().ContainsFieldType(KUidContactFieldIMPP)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeImpp);
        }
        else if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapVOIP)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeSipVoip);
        }
        else if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapSWIS)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeVideoShare);
        }
        else if (field.ContentType().ContainsFieldType(KUidContactFieldVCardMapSIPID)) {
            onlineAccount->setAccountUri(onlineAccountString);
            onlineAccount->setSubTypes(QContactOnlineAccount::SubTypeSip);
        }
        //Service Provider
        else if (field.ContentType().FieldType(i) == KUidContactFieldServiceProvider) {
            onlineAccount->setServiceProvider(onlineAccountString);
        }
        //Presence
        else if (field.ContentType().FieldType(i) == KUidContactFieldPresence) {
            QString presenceInfo = decodePresence(onlineAccountString.toInt());
//            onlineAccount->setPresence(presenceInfo);
        }
        //Status Message
        else if (field.ContentType().FieldType(i) == KUidContactFieldStatusMsg) {
//            onlineAccount->setStatusMessage(onlineAccountString);
        }
    }

    // set context
	for (int i = 0; i < field.ContentType().FieldTypeCount(); i++) {
        setContexts(field.ContentType().FieldType(i), *onlineAccount);
	}

	return onlineAccount;
}

bool CntTransformOnlineAccount::supportsField(TUint32 fieldType) const
{
    bool ret = false;
    if (fieldType == KUidContactFieldSIPID.iUid ||
        fieldType == KUidContactFieldIMPP.iUid  ||
        fieldType == KUidContactFieldServiceProvider.iUid  ||
        fieldType == KUidContactFieldPresence.iUid  ||
        fieldType == KUidContactFieldStatusMsg.iUid )
    {
        ret = true;
    }
    return ret;
}

bool CntTransformOnlineAccount::supportsDetail(QString detailName) const
{
    bool ret = false;
    if (detailName == QContactOnlineAccount::DefinitionName) {
        ret = true;
    }
    return ret;
}

QList<TUid> CntTransformOnlineAccount::supportedSortingFieldTypes(QString detailFieldName) const
{
    QList<TUid> uids;
    if (detailFieldName == QContactOnlineAccount::FieldAccountUri) {
        uids << KUidContactFieldIMPP;
        uids << KUidContactFieldSIPID;
    }
    return uids;
}

/*!
 * Checks whether the subtype is supported
 *
 * \a subType The subtype to be checked
 * \return True if this subtype is supported
 */
bool CntTransformOnlineAccount::supportsSubType(const QString& subType) const
{
    if(QContactOnlineAccount::FieldSubTypes  == subType)
        return true;
    else
        return false;
}

/*!
 * Returns the filed id corresponding to a field
 *
 * \a fieldName The name of the supported field
 * \return fieldId for the fieldName, 0  if not supported
 */
quint32 CntTransformOnlineAccount::getIdForField(const QString& fieldName) const
{
    if (QContactOnlineAccount::FieldAccountUri  == fieldName)
        return 0;
    else if (QContactOnlineAccount::SubTypeSip == fieldName)
        return KUidContactFieldSIPID.iUid;
    else if (QContactOnlineAccount::SubTypeImpp == fieldName)
        return KUidContactFieldIMPP.iUid;
    else if (QContactOnlineAccount::SubTypeSipVoip == fieldName)
        return KUidContactFieldVCardMapVOIP.iUid;
    else if (QContactOnlineAccount::SubTypeVideoShare == fieldName)
        return KUidContactFieldVCardMapSWIS.iUid;
    else
        return 0;
}

/*!
 * Modifies the detail definitions. The default detail definitions are
 * queried from QContactManagerEngine::schemaDefinitions and then modified
 * with this function in the transform leaf classes.
 *
 * \a definitions The detail definitions to modify.
 * \a contactType The contact type the definitions apply for.
 */
void CntTransformOnlineAccount::detailDefinitions(QMap<QString, QContactDetailDefinition> &definitions, const QString& contactType) const
{
    Q_UNUSED(contactType);

    if(definitions.contains(QContactOnlineAccount::DefinitionName)) {
        QContactDetailDefinition d = definitions.value(QContactOnlineAccount::DefinitionName);
        QMap<QString, QContactDetailFieldDefinition> fields = d.fields();
        QContactDetailFieldDefinition f;

        // Don't support "ContextOther"
        f.setDataType(QVariant::StringList);
        f.setAllowableValues(QVariantList()
            << QLatin1String(QContactDetail::ContextHome)
            << QLatin1String(QContactDetail::ContextWork));
        fields[QContactDetail::FieldContext] = f;
        d.setFields(fields);

        // Replace original definitions
        definitions.insert(d.name(), d);
    }
}

/*!
 * Encode the presence information.
 * \a aPresence
 */
quint32 CntTransformOnlineAccount::encodePresence(QString aPresence)
{
    //FIXME:presence
//    if (QContactPresence::PresenceAvailable  == aPresence)
//        return CntTransformOnlineAccount::EPresenceAvailable;
//    else if (QContactPresence::PresenceHidden == aPresence)
//        return CntTransformOnlineAccount::EPresenceHidden;
//    else if (QContactPresence::PresenceBusy == aPresence)
//        return CntTransformOnlineAccount::EPresenceBusy;
//    else if (QContactPresence::PresenceAway == aPresence)
//        return CntTransformOnlineAccount::EPresenceAway;
//    else if (QContactPresence::PresenceExtendedAway == aPresence)
//        return CntTransformOnlineAccount::EPresenceExtendedAway;
//    else if (QContactPresence::PresenceUnknown == aPresence)
//        return CntTransformOnlineAccount::EPresenceUnknown;
//    else
        return CntTransformOnlineAccount::EPresenceOffline;
}

/*!
 * Decode the presence information.
 * \a aPresence
 */
QString CntTransformOnlineAccount::decodePresence(quint32 aPresence)
{
    if (CntTransformOnlineAccount::EPresenceAvailable  == aPresence)
        return QContactPresence::PresenceAvailable;
    else if (CntTransformOnlineAccount::EPresenceHidden == aPresence)
        return QContactPresence::PresenceHidden;
    else if (CntTransformOnlineAccount::EPresenceBusy == aPresence)
        return QContactPresence::PresenceBusy;
    else if ( CntTransformOnlineAccount::EPresenceAway == aPresence)
        return QContactPresence::PresenceAway;
    else if ( CntTransformOnlineAccount::EPresenceExtendedAway == aPresence)
        return QContactPresence::PresenceExtendedAway;
    else if ( CntTransformOnlineAccount::EPresenceUnknown == aPresence)
        return QContactPresence::PresenceUnknown;
    else
        return QContactPresence::PresenceOffline;
}

#endif // SYMBIAN_BACKEND_USE_SQLITE

// End of file
<|endoftext|>


<commit_before>/*++
Copyright (c) 2012 Microsoft Corporation

Module Name:

    ctx_solver_simplify_tactic.cpp

Abstract:

    Context simplifier for propagating solver assignments.

Author:

    Nikolaj (nbjorner) 2012-3-6

Notes:

--*/

#include"ctx_solver_simplify_tactic.h"
#include"arith_decl_plugin.h"
#include"smt_params.h"
#include"smt_kernel.h"
#include"ast_pp.h"
#include"mk_simplified_app.h"

class ctx_solver_simplify_tactic : public tactic {
    ast_manager&          m;
    params_ref            m_params;
    smt_params            m_front_p;
    smt::kernel           m_solver;
    arith_util            m_arith;
    mk_simplified_app     m_mk_app;
    func_decl_ref         m_fn;
    obj_map<sort, func_decl*> m_fns;
    unsigned              m_num_steps;
    volatile bool         m_cancel;
public:
    ctx_solver_simplify_tactic(ast_manager & m, params_ref const & p = params_ref()):
        m(m), m_params(p), m_solver(m, m_front_p),
        m_arith(m), m_mk_app(m), m_fn(m), m_num_steps(0),
        m_cancel(false) {
        sort* i_sort = m_arith.mk_int();
        m_fn = m.mk_func_decl(symbol(0xbeef101), i_sort, m.mk_bool_sort());
    }

    virtual tactic * translate(ast_manager & m) {
        return alloc(ctx_solver_simplify_tactic, m, m_params);
    }

    virtual ~ctx_solver_simplify_tactic() {
        obj_map<sort, func_decl*>::iterator it = m_fns.begin(), end = m_fns.end();
        for (; it != end; ++it) {
            m.dec_ref(it->m_value);
        }
        m_fns.reset();
    }

    virtual void updt_params(params_ref const & p) {
        m_solver.updt_params(p);
    }

    virtual void collect_param_descrs(param_descrs & r) {
        m_solver.collect_param_descrs(r);
    }

    virtual void collect_statistics(statistics & st) const {
        st.update("solver-simplify-steps", m_num_steps);
    }

    virtual void reset_statistics() { m_num_steps = 0; }

    virtual void operator()(goal_ref const & in,
                            goal_ref_buffer & result,
                            model_converter_ref & mc,
                            proof_converter_ref & pc,
                            expr_dependency_ref & core) {

        mc = 0; pc = 0; core = 0;
        reduce(*(in.get()));
        in->inc_depth();
        result.push_back(in.get());
    }

    virtual void cleanup() {
        reset_statistics();
        m_solver.reset();
        m_cancel = false;
    }

protected:

    virtual void set_cancel(bool f) {
        m_solver.set_cancel(f);
        m_cancel = false;
    }

    void reduce(goal& g) {
        SASSERT(g.is_well_sorted());
        expr_ref fml(m);
        tactic_report report("ctx-solver-simplify", g);
        if (g.inconsistent())
            return;
        ptr_vector<expr> fmls;
        g.get_formulas(fmls);
        fml = m.mk_and(fmls.size(), fmls.c_ptr());
        m_solver.push();
        reduce(fml);
        m_solver.pop(1);
        SASSERT(m_solver.get_scope_level() == 0);
        TRACE("ctx_solver_simplify_tactic",
              for (unsigned i = 0; i < fmls.size(); ++i) {
                  tout << mk_pp(fmls[i], m) << "\n";
              }
              tout << "=>\n";
              tout << mk_pp(fml, m) << "\n";);
        DEBUG_CODE(
        {
            m_solver.push();
            expr_ref fml1(m);
            fml1 = m.mk_and(fmls.size(), fmls.c_ptr());
            fml1 = m.mk_iff(fml, fml1);
            fml1 = m.mk_not(fml1);
            m_solver.assert_expr(fml1);
            lbool is_sat = m_solver.check();
            TRACE("ctx_solver_simplify_tactic", tout << "is non-equivalence sat?: " << is_sat << "\n";);
            if (is_sat != l_false) {
                TRACE("ctx_solver_simplify_tactic",
                      tout << "result is not equivalent to input\n";
                      tout << mk_pp(fml1, m) << "\n";);
                UNREACHABLE();
            }
            m_solver.pop(1);
        });
        g.reset();
        g.assert_expr(fml, 0, 0);
        IF_VERBOSE(TACTIC_VERBOSITY_LVL, verbose_stream() << "(ctx-solver-simplify :num-steps " << m_num_steps << ")\n";);
        SASSERT(g.is_well_sorted());
    }

    void reduce(expr_ref& result){
        SASSERT(m.is_bool(result));
        ptr_vector<expr> todo;
        ptr_vector<expr> names;
        svector<bool>    is_checked;
        svector<unsigned> parent_ids, self_ids;
        expr_ref_vector fresh_vars(m), trail(m);
        expr_ref res(m), tmp(m);
        obj_map<expr,std::pair<unsigned, expr*> > cache;
        unsigned id = 1;
        expr_ref n2(m), fml(m);
        unsigned path_id = 0, self_pos = 0;
        app * a;
        unsigned sz;
        std::pair<unsigned,expr*> path_r;
        ptr_vector<expr> found;
        expr_ref_vector args(m);
        expr_ref n = mk_fresh(id, m.mk_bool_sort());
        trail.push_back(n);

        fml = result.get();
        tmp = m.mk_not(m.mk_iff(fml, n));
        m_solver.assert_expr(tmp);

        todo.push_back(fml);
        names.push_back(n);
        is_checked.push_back(false);
        parent_ids.push_back(0);
        self_ids.push_back(0);
        m_solver.push();

        while (!todo.empty() && !m_cancel) {
            expr_ref res(m);
            args.reset();
            expr* e = todo.back();
            unsigned pos = parent_ids.back();
            n = names.back();
            bool checked = is_checked.back();

            if (cache.contains(e)) {
                goto done;
            }
            if (m.is_bool(e) && !checked && simplify_bool(n, res)) {
                TRACE("ctx_solver_simplify_tactic", tout << "simplified: " << mk_pp(e, m) << " |-> " << mk_pp(res, m) << "\n";);
                goto done;
            }
            if (!is_app(e)) {
                res = e;
                goto done;
            }

            a = to_app(e);
            if (!is_checked.back()) {
                self_ids.back() = ++path_id;
                is_checked.back() = true;
            }
            self_pos = self_ids.back();
            sz = a->get_num_args();

            n2 = 0;

            found.reset(); // arguments already simplified.
            for (unsigned i = 0; i < sz; ++i) {
                expr* arg = a->get_arg(i);
                if (cache.find(arg, path_r) && !found.contains(arg)) {
                    //
                    // This is a single traversal version of the context
                    // simplifier. It simplifies only the first occurrence of
                    // a sub-term with respect to the context.
                    //

                    found.push_back(arg);
                    if (path_r.first == self_pos) {
                        TRACE("ctx_solver_simplify_tactic", tout << "cached " << mk_pp(arg, m) << " |-> " << mk_pp(path_r.second, m) << "\n";);
                        args.push_back(path_r.second);
                    }
                    else if (m.is_bool(arg)) {
                        res = local_simplify(a, n, id, i);
                        TRACE("ctx_solver_simplify_tactic",
                              tout << "Already cached: " << path_r.first << " " << mk_pp(res, m) << "\n";);
                        args.push_back(res);
                    }
                    else {
                        args.push_back(arg);
                    }
                }
                else if (!n2 && !found.contains(arg)) {
                    n2 = mk_fresh(id, m.get_sort(arg));
                    trail.push_back(n2);
                    todo.push_back(arg);
                    parent_ids.push_back(self_pos);
                    self_ids.push_back(0);
                    names.push_back(n2);
                    args.push_back(n2);
                    is_checked.push_back(false);
                }
                else {
                    args.push_back(arg);
                }
            }
            m_mk_app(a->get_decl(), args.size(), args.c_ptr(), res);
            trail.push_back(res);
            // child needs to be visited.
            if (n2) {
                m_solver.push();
                tmp = m.mk_eq(res, n);
                m_solver.assert_expr(tmp);
                continue;
            }

        done:
            if (res) {
                cache.insert(e, std::make_pair(pos, res));
            }

            TRACE("ctx_solver_simplify_tactic",
                  tout << mk_pp(e, m) << " checked: " << checked << " cached: " << mk_pp(res?res.get():e, m) << "\n";);

            todo.pop_back();
            parent_ids.pop_back();
            self_ids.pop_back();
            names.pop_back();
            is_checked.pop_back();
            m_solver.pop(1);
        }
        if (!m_cancel) {
            VERIFY(cache.find(fml, path_r));
            result = path_r.second;
        }
    }

    bool simplify_bool(expr* n, expr_ref& res) {
        expr_ref tmp(m);
        m_solver.push();
        m_solver.assert_expr(n);
        lbool is_sat = m_solver.check();
        m_solver.pop(1);
        if (is_sat == l_false) {
            res = m.mk_true();
            return true;
        }

        m_solver.push();
        tmp = m.mk_not(n);
        m_solver.assert_expr(tmp);
        is_sat = m_solver.check();
        m_solver.pop(1);
        if (is_sat == l_false) {
            res = m.mk_false();
            return true;
        }

        return false;
    }

    expr_ref mk_fresh(unsigned& id, sort* s) {
        func_decl* fn;
        if (m.is_bool(s)) {
            fn = m_fn;
        }
        else if (!m_fns.find(s, fn)) {
            fn = m.mk_func_decl(symbol(0xbeef101 + id), m_arith.mk_int(), s);
            m.inc_ref(fn);
            m_fns.insert(s, fn);
        }
        return expr_ref(m.mk_app(fn, m_arith.mk_numeral(rational(id++), true)), m);
    }

    expr_ref local_simplify(app* a, expr* n, unsigned& id, unsigned index) {
        SASSERT(index < a->get_num_args());
        SASSERT(m.is_bool(a->get_arg(index)));
        expr_ref n2(m), result(m), tmp(m);
        n2 = mk_fresh(id, m.get_sort(a->get_arg(index)));
        ptr_buffer<expr> args;
        for (unsigned i = 0; i < a->get_num_args(); ++i) {
            if (i == index) {
                args.push_back(n2);
            }
            else {
                args.push_back(a->get_arg(i));
            }
        }
        m_mk_app(a->get_decl(), args.size(), args.c_ptr(), result);
        m_solver.push();
        tmp = m.mk_eq(result, n);
        m_solver.assert_expr(tmp);
        if (!simplify_bool(n2, result)) {
            result = a;
        }
        m_solver.pop(1);
        return result;
    }

};

tactic * mk_ctx_solver_simplify_tactic(ast_manager & m, params_ref const & p) {
    return clean(alloc(ctx_solver_simplify_tactic, m, p));
}
<commit_msg>Fix minor problem<commit_after>/*++
Copyright (c) 2012 Microsoft Corporation

Module Name:

    ctx_solver_simplify_tactic.cpp

Abstract:

    Context simplifier for propagating solver assignments.

Author:

    Nikolaj (nbjorner) 2012-3-6

Notes:

--*/

#include"ctx_solver_simplify_tactic.h"
#include"arith_decl_plugin.h"
#include"smt_params.h"
#include"smt_kernel.h"
#include"ast_pp.h"
#include"mk_simplified_app.h"
#include"ast_util.h"

class ctx_solver_simplify_tactic : public tactic {
    ast_manager&          m;
    params_ref            m_params;
    smt_params            m_front_p;
    smt::kernel           m_solver;
    arith_util            m_arith;
    mk_simplified_app     m_mk_app;
    func_decl_ref         m_fn;
    obj_map<sort, func_decl*> m_fns;
    unsigned              m_num_steps;
    volatile bool         m_cancel;
public:
    ctx_solver_simplify_tactic(ast_manager & m, params_ref const & p = params_ref()):
        m(m), m_params(p), m_solver(m, m_front_p),
        m_arith(m), m_mk_app(m), m_fn(m), m_num_steps(0),
        m_cancel(false) {
        sort* i_sort = m_arith.mk_int();
        m_fn = m.mk_func_decl(symbol(0xbeef101), i_sort, m.mk_bool_sort());
    }

    virtual tactic * translate(ast_manager & m) {
        return alloc(ctx_solver_simplify_tactic, m, m_params);
    }

    virtual ~ctx_solver_simplify_tactic() {
        obj_map<sort, func_decl*>::iterator it = m_fns.begin(), end = m_fns.end();
        for (; it != end; ++it) {
            m.dec_ref(it->m_value);
        }
        m_fns.reset();
    }

    virtual void updt_params(params_ref const & p) {
        m_solver.updt_params(p);
    }

    virtual void collect_param_descrs(param_descrs & r) {
        m_solver.collect_param_descrs(r);
    }

    virtual void collect_statistics(statistics & st) const {
        st.update("solver-simplify-steps", m_num_steps);
    }

    virtual void reset_statistics() { m_num_steps = 0; }

    virtual void operator()(goal_ref const & in,
                            goal_ref_buffer & result,
                            model_converter_ref & mc,
                            proof_converter_ref & pc,
                            expr_dependency_ref & core) {

        mc = 0; pc = 0; core = 0;
        reduce(*(in.get()));
        in->inc_depth();
        result.push_back(in.get());
    }

    virtual void cleanup() {
        reset_statistics();
        m_solver.reset();
        m_cancel = false;
    }

protected:

    virtual void set_cancel(bool f) {
        m_solver.set_cancel(f);
        m_cancel = false;
    }

    void reduce(goal& g) {
        SASSERT(g.is_well_sorted());
        expr_ref fml(m);
        tactic_report report("ctx-solver-simplify", g);
        if (g.inconsistent())
            return;
        ptr_vector<expr> fmls;
        g.get_formulas(fmls);
        fml = mk_and(m, fmls.size(), fmls.c_ptr());
        m_solver.push();
        reduce(fml);
        m_solver.pop(1);
        SASSERT(m_solver.get_scope_level() == 0);
        TRACE("ctx_solver_simplify_tactic",
              for (unsigned i = 0; i < fmls.size(); ++i) {
                  tout << mk_pp(fmls[i], m) << "\n";
              }
              tout << "=>\n";
              tout << mk_pp(fml, m) << "\n";);
        DEBUG_CODE(
        {
            m_solver.push();
            expr_ref fml1(m);
            fml1 = mk_and(m, fmls.size(), fmls.c_ptr());
            fml1 = m.mk_iff(fml, fml1);
            fml1 = m.mk_not(fml1);
            m_solver.assert_expr(fml1);
            lbool is_sat = m_solver.check();
            TRACE("ctx_solver_simplify_tactic", tout << "is non-equivalence sat?: " << is_sat << "\n";);
            if (is_sat != l_false) {
                TRACE("ctx_solver_simplify_tactic",
                      tout << "result is not equivalent to input\n";
                      tout << mk_pp(fml1, m) << "\n";);
                UNREACHABLE();
            }
            m_solver.pop(1);
        });
        g.reset();
        g.assert_expr(fml, 0, 0);
        IF_VERBOSE(TACTIC_VERBOSITY_LVL, verbose_stream() << "(ctx-solver-simplify :num-steps " << m_num_steps << ")\n";);
        SASSERT(g.is_well_sorted());
    }

    void reduce(expr_ref& result){
        SASSERT(m.is_bool(result));
        ptr_vector<expr> todo;
        ptr_vector<expr> names;
        svector<bool>    is_checked;
        svector<unsigned> parent_ids, self_ids;
        expr_ref_vector fresh_vars(m), trail(m);
        expr_ref res(m), tmp(m);
        obj_map<expr,std::pair<unsigned, expr*> > cache;
        unsigned id = 1;
        expr_ref n2(m), fml(m);
        unsigned path_id = 0, self_pos = 0;
        app * a;
        unsigned sz;
        std::pair<unsigned,expr*> path_r;
        ptr_vector<expr> found;
        expr_ref_vector args(m);
        expr_ref n = mk_fresh(id, m.mk_bool_sort());
        trail.push_back(n);

        fml = result.get();
        tmp = m.mk_not(m.mk_iff(fml, n));
        m_solver.assert_expr(tmp);

        todo.push_back(fml);
        names.push_back(n);
        is_checked.push_back(false);
        parent_ids.push_back(0);
        self_ids.push_back(0);
        m_solver.push();

        while (!todo.empty() && !m_cancel) {
            expr_ref res(m);
            args.reset();
            expr* e = todo.back();
            unsigned pos = parent_ids.back();
            n = names.back();
            bool checked = is_checked.back();

            if (cache.contains(e)) {
                goto done;
            }
            if (m.is_bool(e) && !checked && simplify_bool(n, res)) {
                TRACE("ctx_solver_simplify_tactic", tout << "simplified: " << mk_pp(e, m) << " |-> " << mk_pp(res, m) << "\n";);
                goto done;
            }
            if (!is_app(e)) {
                res = e;
                goto done;
            }

            a = to_app(e);
            if (!is_checked.back()) {
                self_ids.back() = ++path_id;
                is_checked.back() = true;
            }
            self_pos = self_ids.back();
            sz = a->get_num_args();

            n2 = 0;

            found.reset(); // arguments already simplified.
            for (unsigned i = 0; i < sz; ++i) {
                expr* arg = a->get_arg(i);
                if (cache.find(arg, path_r) && !found.contains(arg)) {
                    //
                    // This is a single traversal version of the context
                    // simplifier. It simplifies only the first occurrence of
                    // a sub-term with respect to the context.
                    //

                    found.push_back(arg);
                    if (path_r.first == self_pos) {
                        TRACE("ctx_solver_simplify_tactic", tout << "cached " << mk_pp(arg, m) << " |-> " << mk_pp(path_r.second, m) << "\n";);
                        args.push_back(path_r.second);
                    }
                    else if (m.is_bool(arg)) {
                        res = local_simplify(a, n, id, i);
                        TRACE("ctx_solver_simplify_tactic",
                              tout << "Already cached: " << path_r.first << " " << mk_pp(res, m) << "\n";);
                        args.push_back(res);
                    }
                    else {
                        args.push_back(arg);
                    }
                }
                else if (!n2 && !found.contains(arg)) {
                    n2 = mk_fresh(id, m.get_sort(arg));
                    trail.push_back(n2);
                    todo.push_back(arg);
                    parent_ids.push_back(self_pos);
                    self_ids.push_back(0);
                    names.push_back(n2);
                    args.push_back(n2);
                    is_checked.push_back(false);
                }
                else {
                    args.push_back(arg);
                }
            }
            m_mk_app(a->get_decl(), args.size(), args.c_ptr(), res);
            trail.push_back(res);
            // child needs to be visited.
            if (n2) {
                m_solver.push();
                tmp = m.mk_eq(res, n);
                m_solver.assert_expr(tmp);
                continue;
            }

        done:
            if (res) {
                cache.insert(e, std::make_pair(pos, res));
            }

            TRACE("ctx_solver_simplify_tactic",
                  tout << mk_pp(e, m) << " checked: " << checked << " cached: " << mk_pp(res?res.get():e, m) << "\n";);

            todo.pop_back();
            parent_ids.pop_back();
            self_ids.pop_back();
            names.pop_back();
            is_checked.pop_back();
            m_solver.pop(1);
        }
        if (!m_cancel) {
            VERIFY(cache.find(fml, path_r));
            result = path_r.second;
        }
    }

    bool simplify_bool(expr* n, expr_ref& res) {
        expr_ref tmp(m);
        m_solver.push();
        m_solver.assert_expr(n);
        lbool is_sat = m_solver.check();
        m_solver.pop(1);
        if (is_sat == l_false) {
            res = m.mk_true();
            return true;
        }

        m_solver.push();
        tmp = m.mk_not(n);
        m_solver.assert_expr(tmp);
        is_sat = m_solver.check();
        m_solver.pop(1);
        if (is_sat == l_false) {
            res = m.mk_false();
            return true;
        }

        return false;
    }

    expr_ref mk_fresh(unsigned& id, sort* s) {
        func_decl* fn;
        if (m.is_bool(s)) {
            fn = m_fn;
        }
        else if (!m_fns.find(s, fn)) {
            fn = m.mk_func_decl(symbol(0xbeef101 + id), m_arith.mk_int(), s);
            m.inc_ref(fn);
            m_fns.insert(s, fn);
        }
        return expr_ref(m.mk_app(fn, m_arith.mk_numeral(rational(id++), true)), m);
    }

    expr_ref local_simplify(app* a, expr* n, unsigned& id, unsigned index) {
        SASSERT(index < a->get_num_args());
        SASSERT(m.is_bool(a->get_arg(index)));
        expr_ref n2(m), result(m), tmp(m);
        n2 = mk_fresh(id, m.get_sort(a->get_arg(index)));
        ptr_buffer<expr> args;
        for (unsigned i = 0; i < a->get_num_args(); ++i) {
            if (i == index) {
                args.push_back(n2);
            }
            else {
                args.push_back(a->get_arg(i));
            }
        }
        m_mk_app(a->get_decl(), args.size(), args.c_ptr(), result);
        m_solver.push();
        tmp = m.mk_eq(result, n);
        m_solver.assert_expr(tmp);
        if (!simplify_bool(n2, result)) {
            result = a;
        }
        m_solver.pop(1);
        return result;
    }

};

tactic * mk_ctx_solver_simplify_tactic(ast_manager & m, params_ref const & p) {
    return clean(alloc(ctx_solver_simplify_tactic, m, p));
}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * http://lxqt.org/
 *
 * Copyright: 2015 LXQt team
 * Authors:
 *   Paulo Lieuthier <paulolieuthier@gmail.com>
 *
 * This program or 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 Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "statusnotifieritem.h"
#include "statusnotifieritemadaptor.h"
#include <QDBusInterface>
#include <QDBusServiceWatcher>
#include <dbusmenu-qt5/dbusmenuexporter.h>

int StatusNotifierItem::mServiceCounter = 0;

StatusNotifierItem::StatusNotifierItem(QString id, QObject *parent)
    : QObject(parent),
    mAdaptor(new StatusNotifierItemAdaptor(this)),
    mService(QString("org.freedesktop.StatusNotifierItem-%1-%2")
             .arg(QCoreApplication::applicationPid())
             .arg(++mServiceCounter)),
    mId(id),
    mTitle("Test"),
    mStatus("Active"),
    mMenu(nullptr),
    mMenuExporter(nullptr),
    mSessionBus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, mService))
{
    // Separate DBus connection to the session bus is created, because QDbus does not provide
    // a way to register different objects for different services with the same paths.
    // For status notifiers we need different /StatusNotifierItem for each service.

    // register service

    mSessionBus.registerService(mService);
    mSessionBus.registerObject(QLatin1String("/StatusNotifierItem"), this);

    registerToHost();

    // monitor the watcher service in case the host restarts
    QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.StatusNotifierWatcher",
                                                           mSessionBus,
                                                           QDBusServiceWatcher::WatchForOwnerChange,
                                                           this);
    connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged,
            this, &StatusNotifierItem::onServiceOwnerChanged);
}

StatusNotifierItem::~StatusNotifierItem()
{
    mSessionBus.unregisterObject(QLatin1String("/StatusNotifierItem"));
    mSessionBus.unregisterService(mService);
    QDBusConnection::disconnectFromBus(mService);
}

void StatusNotifierItem::registerToHost()
{
    QDBusInterface interface("org.kde.StatusNotifierWatcher",
                             "/StatusNotifierWatcher",
                             "org.kde.StatusNotifierWatcher",
                             mSessionBus);
    interface.asyncCall("RegisterStatusNotifierItem", mService);
}

void StatusNotifierItem::onServiceOwnerChanged(const QString& service, const QString& oldOwner,
                                               const QString& newOwner)
{
    if (!newOwner.isEmpty())
        registerToHost();
}

void StatusNotifierItem::onMenuDestroyed()
{
    mMenu = nullptr;
    mMenuExporter = nullptr; //mMenu is a QObject parent of the mMenuExporter
}

void StatusNotifierItem::setTitle(const QString &title)
{
    if (mTitle == title)
        return;

    mTitle = title;
    Q_EMIT mAdaptor->NewTitle();
}

void StatusNotifierItem::setStatus(const QString &status)
{
    if (mStatus == status)
        return;

    mStatus = status;
    Q_EMIT mAdaptor->NewStatus(mStatus);
}

void StatusNotifierItem::setMenuPath(const QString& path)
{
    mMenuPath.setPath(path);
}

void StatusNotifierItem::setIconByName(const QString &name)
{
    if (mIconName == name)
        return;

    mIconName = name;
    Q_EMIT mAdaptor->NewIcon();
}

void StatusNotifierItem::setIconByPixmap(const QIcon &icon)
{
    if (mIconCacheKey == icon.cacheKey())
        return;

    mIconCacheKey = icon.cacheKey();
    mIcon = iconToPixmapList(icon);
    mIconName.clear();
    Q_EMIT mAdaptor->NewIcon();
}

void StatusNotifierItem::setOverlayIconByName(const QString &name)
{
    if (mOverlayIconName == name)
        return;

    mOverlayIconName = name;
    Q_EMIT mAdaptor->NewOverlayIcon();
}

void StatusNotifierItem::setOverlayIconByPixmap(const QIcon &icon)
{
    if (mOverlayIconCacheKey == icon.cacheKey())
        return;

    mOverlayIconCacheKey = icon.cacheKey();
    mOverlayIcon = iconToPixmapList(icon);
    mOverlayIconName.clear();
    Q_EMIT mAdaptor->NewOverlayIcon();
}

void StatusNotifierItem::setAttentionIconByName(const QString &name)
{
    if (mAttentionIconName == name)
        return;

    mAttentionIconName = name;
    Q_EMIT mAdaptor->NewAttentionIcon();
}

void StatusNotifierItem::setAttentionIconByPixmap(const QIcon &icon)
{
    if (mAttentionIconCacheKey == icon.cacheKey())
        return;

    mAttentionIconCacheKey = icon.cacheKey();
    mAttentionIcon = iconToPixmapList(icon);
    mAttentionIconName.clear();
    Q_EMIT mAdaptor->NewAttentionIcon();
}

void StatusNotifierItem::setToolTipTitle(const QString &title)
{
    if (mTooltipTitle == title)
        return;

    mTooltipTitle = title;
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setToolTipSubTitle(const QString &subTitle)
{
    if (mTooltipSubtitle == subTitle)
        return;

    mTooltipSubtitle = subTitle;
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setToolTipIconByName(const QString &name)
{
    if (mTooltipIconName == name)
        return;

    mTooltipIconName = name;
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setToolTipIconByPixmap(const QIcon &icon)
{
    if (mTooltipIconCacheKey == icon.cacheKey())
        return;

    mTooltipIconCacheKey = icon.cacheKey();
    mTooltipIcon = iconToPixmapList(icon);
    mTooltipIconName.clear();
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setContextMenu(QMenu* menu)
{
    if (mMenu == menu)
        return;

    if (nullptr != mMenu)
    {
        disconnect(mMenu, &QObject::destroyed, this, &StatusNotifierItem::onMenuDestroyed);
    }
    mMenu = menu;

    setMenuPath("/MenuBar");
    //Note: we need to destroy menu exporter before creating new one -> to free the DBus object path for new menu
    delete mMenuExporter;
    if (nullptr != mMenu)
    {
        connect(mMenu, &QObject::destroyed, this, &StatusNotifierItem::onMenuDestroyed);
        mMenuExporter = new DBusMenuExporter{this->menu().path(), mMenu, mSessionBus};
    }
}

void StatusNotifierItem::Activate(int x, int y)
{
    if (mStatus == "NeedsAttention")
        mStatus = "Active";

    Q_EMIT activateRequested(QPoint(x, y));
}

void StatusNotifierItem::SecondaryActivate(int x, int y)
{
    if (mStatus == "NeedsAttention")
        mStatus = "Active";

    Q_EMIT secondaryActivateRequested(QPoint(x, y));
}

void StatusNotifierItem::ContextMenu(int x, int y)
{
    if (mMenu)
    {
        if (mMenu->isVisible())
            mMenu->popup(QPoint(x, y));
        else
            mMenu->hide();
    }
}

void StatusNotifierItem::Scroll(int delta, const QString &orientation)
{
    Qt::Orientation orient = Qt::Vertical;
    if (orientation.toLower() == "horizontal")
        orient = Qt::Horizontal;

    Q_EMIT scrollRequested(delta, orient);
}

void StatusNotifierItem::showMessage(const QString& title, const QString& msg,
                                     const QString& iconName, int secs)
{
    QDBusInterface interface("org.freedesktop.Notifications", "/org/freedesktop/Notifications",
                             "org.freedesktop.Notifications", mSessionBus);
    interface.call("Notify", mTitle, (uint) 0, iconName, title,
                   msg, QStringList(), QVariantMap(), secs);
}

IconPixmapList StatusNotifierItem::iconToPixmapList(const QIcon& icon)
{
    IconPixmapList pixmapList;

    // long live KDE!
    const QList<QSize> sizes = icon.availableSizes();
    for (const QSize &size : sizes)
    {
        QImage image = icon.pixmap(size).toImage();

        IconPixmap pix;
        pix.height = image.height();
        pix.width = image.width();

        if (image.format() != QImage::Format_ARGB32)
            image = image.convertToFormat(QImage::Format_ARGB32);

        pix.bytes = QByteArray((char *) image.bits(), image.byteCount());

        // swap to network byte order if we are little endian
        if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
        {
            quint32 *uintBuf = (quint32 *) pix.bytes.data();
            for (uint i = 0; i < pix.bytes.size() / sizeof(quint32); ++i)
            {
                *uintBuf = qToBigEndian(*uintBuf);
                ++uintBuf;
            }
        }

        pixmapList.append(pix);
    }

    return pixmapList;
}
<commit_msg>Flag unused vars in onServiceOwnerChanged<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * http://lxqt.org/
 *
 * Copyright: 2015 LXQt team
 * Authors:
 *   Paulo Lieuthier <paulolieuthier@gmail.com>
 *
 * This program or 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 Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "statusnotifieritem.h"
#include "statusnotifieritemadaptor.h"
#include <QDBusInterface>
#include <QDBusServiceWatcher>
#include <dbusmenu-qt5/dbusmenuexporter.h>

int StatusNotifierItem::mServiceCounter = 0;

StatusNotifierItem::StatusNotifierItem(QString id, QObject *parent)
    : QObject(parent),
    mAdaptor(new StatusNotifierItemAdaptor(this)),
    mService(QString("org.freedesktop.StatusNotifierItem-%1-%2")
             .arg(QCoreApplication::applicationPid())
             .arg(++mServiceCounter)),
    mId(id),
    mTitle("Test"),
    mStatus("Active"),
    mMenu(nullptr),
    mMenuExporter(nullptr),
    mSessionBus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, mService))
{
    // Separate DBus connection to the session bus is created, because QDbus does not provide
    // a way to register different objects for different services with the same paths.
    // For status notifiers we need different /StatusNotifierItem for each service.

    // register service

    mSessionBus.registerService(mService);
    mSessionBus.registerObject(QLatin1String("/StatusNotifierItem"), this);

    registerToHost();

    // monitor the watcher service in case the host restarts
    QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.StatusNotifierWatcher",
                                                           mSessionBus,
                                                           QDBusServiceWatcher::WatchForOwnerChange,
                                                           this);
    connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged,
            this, &StatusNotifierItem::onServiceOwnerChanged);
}

StatusNotifierItem::~StatusNotifierItem()
{
    mSessionBus.unregisterObject(QLatin1String("/StatusNotifierItem"));
    mSessionBus.unregisterService(mService);
    QDBusConnection::disconnectFromBus(mService);
}

void StatusNotifierItem::registerToHost()
{
    QDBusInterface interface("org.kde.StatusNotifierWatcher",
                             "/StatusNotifierWatcher",
                             "org.kde.StatusNotifierWatcher",
                             mSessionBus);
    interface.asyncCall("RegisterStatusNotifierItem", mService);
}

void StatusNotifierItem::onServiceOwnerChanged(const QString& service, const QString& oldOwner,
                                               const QString& newOwner)
{
	Q_UNUSED(service);
	Q_UNUSED(oldOwner);

    if (!newOwner.isEmpty())
        registerToHost();
}

void StatusNotifierItem::onMenuDestroyed()
{
    mMenu = nullptr;
    mMenuExporter = nullptr; //mMenu is a QObject parent of the mMenuExporter
}

void StatusNotifierItem::setTitle(const QString &title)
{
    if (mTitle == title)
        return;

    mTitle = title;
    Q_EMIT mAdaptor->NewTitle();
}

void StatusNotifierItem::setStatus(const QString &status)
{
    if (mStatus == status)
        return;

    mStatus = status;
    Q_EMIT mAdaptor->NewStatus(mStatus);
}

void StatusNotifierItem::setMenuPath(const QString& path)
{
    mMenuPath.setPath(path);
}

void StatusNotifierItem::setIconByName(const QString &name)
{
    if (mIconName == name)
        return;

    mIconName = name;
    Q_EMIT mAdaptor->NewIcon();
}

void StatusNotifierItem::setIconByPixmap(const QIcon &icon)
{
    if (mIconCacheKey == icon.cacheKey())
        return;

    mIconCacheKey = icon.cacheKey();
    mIcon = iconToPixmapList(icon);
    mIconName.clear();
    Q_EMIT mAdaptor->NewIcon();
}

void StatusNotifierItem::setOverlayIconByName(const QString &name)
{
    if (mOverlayIconName == name)
        return;

    mOverlayIconName = name;
    Q_EMIT mAdaptor->NewOverlayIcon();
}

void StatusNotifierItem::setOverlayIconByPixmap(const QIcon &icon)
{
    if (mOverlayIconCacheKey == icon.cacheKey())
        return;

    mOverlayIconCacheKey = icon.cacheKey();
    mOverlayIcon = iconToPixmapList(icon);
    mOverlayIconName.clear();
    Q_EMIT mAdaptor->NewOverlayIcon();
}

void StatusNotifierItem::setAttentionIconByName(const QString &name)
{
    if (mAttentionIconName == name)
        return;

    mAttentionIconName = name;
    Q_EMIT mAdaptor->NewAttentionIcon();
}

void StatusNotifierItem::setAttentionIconByPixmap(const QIcon &icon)
{
    if (mAttentionIconCacheKey == icon.cacheKey())
        return;

    mAttentionIconCacheKey = icon.cacheKey();
    mAttentionIcon = iconToPixmapList(icon);
    mAttentionIconName.clear();
    Q_EMIT mAdaptor->NewAttentionIcon();
}

void StatusNotifierItem::setToolTipTitle(const QString &title)
{
    if (mTooltipTitle == title)
        return;

    mTooltipTitle = title;
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setToolTipSubTitle(const QString &subTitle)
{
    if (mTooltipSubtitle == subTitle)
        return;

    mTooltipSubtitle = subTitle;
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setToolTipIconByName(const QString &name)
{
    if (mTooltipIconName == name)
        return;

    mTooltipIconName = name;
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setToolTipIconByPixmap(const QIcon &icon)
{
    if (mTooltipIconCacheKey == icon.cacheKey())
        return;

    mTooltipIconCacheKey = icon.cacheKey();
    mTooltipIcon = iconToPixmapList(icon);
    mTooltipIconName.clear();
    Q_EMIT mAdaptor->NewToolTip();
}

void StatusNotifierItem::setContextMenu(QMenu* menu)
{
    if (mMenu == menu)
        return;

    if (nullptr != mMenu)
    {
        disconnect(mMenu, &QObject::destroyed, this, &StatusNotifierItem::onMenuDestroyed);
    }
    mMenu = menu;

    setMenuPath("/MenuBar");
    //Note: we need to destroy menu exporter before creating new one -> to free the DBus object path for new menu
    delete mMenuExporter;
    if (nullptr != mMenu)
    {
        connect(mMenu, &QObject::destroyed, this, &StatusNotifierItem::onMenuDestroyed);
        mMenuExporter = new DBusMenuExporter{this->menu().path(), mMenu, mSessionBus};
    }
}

void StatusNotifierItem::Activate(int x, int y)
{
    if (mStatus == "NeedsAttention")
        mStatus = "Active";

    Q_EMIT activateRequested(QPoint(x, y));
}

void StatusNotifierItem::SecondaryActivate(int x, int y)
{
    if (mStatus == "NeedsAttention")
        mStatus = "Active";

    Q_EMIT secondaryActivateRequested(QPoint(x, y));
}

void StatusNotifierItem::ContextMenu(int x, int y)
{
    if (mMenu)
    {
        if (mMenu->isVisible())
            mMenu->popup(QPoint(x, y));
        else
            mMenu->hide();
    }
}

void StatusNotifierItem::Scroll(int delta, const QString &orientation)
{
    Qt::Orientation orient = Qt::Vertical;
    if (orientation.toLower() == "horizontal")
        orient = Qt::Horizontal;

    Q_EMIT scrollRequested(delta, orient);
}

void StatusNotifierItem::showMessage(const QString& title, const QString& msg,
                                     const QString& iconName, int secs)
{
    QDBusInterface interface("org.freedesktop.Notifications", "/org/freedesktop/Notifications",
                             "org.freedesktop.Notifications", mSessionBus);
    interface.call("Notify", mTitle, (uint) 0, iconName, title,
                   msg, QStringList(), QVariantMap(), secs);
}

IconPixmapList StatusNotifierItem::iconToPixmapList(const QIcon& icon)
{
    IconPixmapList pixmapList;

    // long live KDE!
    const QList<QSize> sizes = icon.availableSizes();
    for (const QSize &size : sizes)
    {
        QImage image = icon.pixmap(size).toImage();

        IconPixmap pix;
        pix.height = image.height();
        pix.width = image.width();

        if (image.format() != QImage::Format_ARGB32)
            image = image.convertToFormat(QImage::Format_ARGB32);

        pix.bytes = QByteArray((char *) image.bits(), image.byteCount());

        // swap to network byte order if we are little endian
        if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
        {
            quint32 *uintBuf = (quint32 *) pix.bytes.data();
            for (uint i = 0; i < pix.bytes.size() / sizeof(quint32); ++i)
            {
                *uintBuf = qToBigEndian(*uintBuf);
                ++uintBuf;
            }
        }

        pixmapList.append(pix);
    }

    return pixmapList;
}
<|endoftext|>