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

#include "chrome/browser/sync/syncable/model_type.h"

#include <sstream>

#include "base/metrics/histogram.h"
#include "chrome/browser/sync/engine/syncproto.h"
#include "chrome/browser/sync/protocol/app_specifics.pb.h"
#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
#include "chrome/browser/sync/protocol/extension_specifics.pb.h"
#include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
#include "chrome/browser/sync/protocol/password_specifics.pb.h"
#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
#include "chrome/browser/sync/protocol/session_specifics.pb.h"
#include "chrome/browser/sync/protocol/sync.pb.h"
#include "chrome/browser/sync/protocol/theme_specifics.pb.h"
#include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"

namespace syncable {

void AddDefaultExtensionValue(syncable::ModelType datatype,
                              sync_pb::EntitySpecifics* specifics) {
  switch (datatype) {
    case BOOKMARKS:
      specifics->MutableExtension(sync_pb::bookmark);
      break;
    case PASSWORDS:
      specifics->MutableExtension(sync_pb::password);
      break;
    case PREFERENCES:
      specifics->MutableExtension(sync_pb::preference);
      break;
    case AUTOFILL:
      specifics->MutableExtension(sync_pb::autofill);
      break;
    case AUTOFILL_PROFILE:
      specifics->MutableExtension(sync_pb::autofill_profile);
      break;
    case THEMES:
      specifics->MutableExtension(sync_pb::theme);
      break;
    case TYPED_URLS:
      specifics->MutableExtension(sync_pb::typed_url);
      break;
    case EXTENSIONS:
      specifics->MutableExtension(sync_pb::extension);
      break;
    case NIGORI:
      specifics->MutableExtension(sync_pb::nigori);
      break;
    case SESSIONS:
      specifics->MutableExtension(sync_pb::session);
      break;
    case APPS:
      specifics->MutableExtension(sync_pb::app);
      break;
    default:
      NOTREACHED() << "No known extension for model type.";
  }
}

// Note: keep this consistent with GetModelType in syncable.cc!
ModelType GetModelType(const sync_pb::SyncEntity& sync_pb_entity) {
  const browser_sync::SyncEntity& sync_entity =
      static_cast<const browser_sync::SyncEntity&>(sync_pb_entity);
  DCHECK(!sync_entity.id().IsRoot());  // Root shouldn't ever go over the wire.

  if (sync_entity.deleted())
    return UNSPECIFIED;

  // Backwards compatibility with old (pre-specifics) protocol.
  if (sync_entity.has_bookmarkdata())
    return BOOKMARKS;

  ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics());
  if (specifics_type != UNSPECIFIED)
    return specifics_type;

  // Loose check for server-created top-level folders that aren't
  // bound to a particular model type.
  if (!sync_entity.server_defined_unique_tag().empty() &&
      sync_entity.IsFolder()) {
    return TOP_LEVEL_FOLDER;
  }

  // This is an item of a datatype we can't understand. Maybe it's
  // from the future?  Either we mis-encoded the object, or the
  // server sent us entries it shouldn't have.
  NOTREACHED() << "Unknown datatype in sync proto.";
  return UNSPECIFIED;
}

ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
  if (specifics.HasExtension(sync_pb::bookmark))
    return BOOKMARKS;

  if (specifics.HasExtension(sync_pb::password))
    return PASSWORDS;

  if (specifics.HasExtension(sync_pb::preference))
    return PREFERENCES;

  if (specifics.HasExtension(sync_pb::autofill))
    return AUTOFILL;

  if (specifics.HasExtension(sync_pb::autofill_profile))
    return AUTOFILL_PROFILE;

  if (specifics.HasExtension(sync_pb::theme))
    return THEMES;

  if (specifics.HasExtension(sync_pb::typed_url))
    return TYPED_URLS;

  if (specifics.HasExtension(sync_pb::extension))
    return EXTENSIONS;

  if (specifics.HasExtension(sync_pb::nigori))
    return NIGORI;

  if (specifics.HasExtension(sync_pb::app))
    return APPS;

  if (specifics.HasExtension(sync_pb::session))
    return SESSIONS;

  return UNSPECIFIED;
}

std::string ModelTypeToString(ModelType model_type) {
  switch (model_type) {
    case BOOKMARKS:
      return "Bookmarks";
    case PREFERENCES:
      return "Preferences";
    case PASSWORDS:
      return "Passwords";
    case AUTOFILL:
      return "Autofill";
    case THEMES:
      return "Themes";
    case TYPED_URLS:
      return "Typed URLs";
    case EXTENSIONS:
      return "Extensions";
    case NIGORI:
      return "Encryption keys";
    case SESSIONS:
      return "Sessions";
    case APPS:
      return "Apps";
    case AUTOFILL_PROFILE:
      return "Autofill Profile";
      break;
    default:
      NOTREACHED() << "No known extension for model type.";
      return "INVALID";
  }
}

ModelType ModelTypeFromString(const std::string& model_type_string) {
  if (model_type_string == "Bookmarks")
    return BOOKMARKS;
  else if (model_type_string == "Preferences")
    return PREFERENCES;
  else if (model_type_string == "Passwords")
    return PASSWORDS;
  else if (model_type_string == "Autofill")
    return AUTOFILL;
  else if (model_type_string == "Themes")
    return THEMES;
  else if (model_type_string == "Typed URLs")
    return TYPED_URLS;
  else if (model_type_string == "Extensions")
    return EXTENSIONS;
  else if (model_type_string == "Encryption keys")
    return NIGORI;
  else if (model_type_string == "Sessions")
    return SESSIONS;
  else if (model_type_string == "Apps")
    return APPS;
  else
    NOTREACHED() << "No known model type corresponding to "
                 << model_type_string << ".";
  return UNSPECIFIED;
}

bool ModelTypeBitSetFromString(
    const std::string& model_type_bitset_string,
    ModelTypeBitSet* model_types) {
  if (model_type_bitset_string.length() != MODEL_TYPE_COUNT) {
    return false;
  }

  std::istringstream iss(model_type_bitset_string);
  iss >> *model_types;
  iss.peek();   // Need to peek before checking EOF.
  return iss.eof();
}

// For now, this just implements UMA_HISTOGRAM_LONG_TIMES. This can be adjusted
// if we feel the min, max, or bucket count amount are not appropriate.
#define SYNC_FREQ_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES( \
    name, time, base::TimeDelta::FromMilliseconds(1), \
    base::TimeDelta::FromHours(1), 50)

void PostTimeToTypeHistogram(ModelType model_type, base::TimeDelta time) {
  switch (model_type) {
    case BOOKMARKS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqBookmarks", time);
        return;
    }
    case PREFERENCES: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqPreferences", time);
        return;
    }
    case PASSWORDS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqPasswords", time);
        return;
    }
    case AUTOFILL: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqAutofill", time);
        return;
    }
    case THEMES: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqThemes", time);
        return;
    }
    case TYPED_URLS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqTypedUrls", time);
        return;
    }
    case EXTENSIONS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqExtensions", time);
        return;
    }
    case NIGORI: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqNigori", time);
        return;
    }
    case SESSIONS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqSessions", time);
        return;
    }
    case APPS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqApps", time);
        return;
    }
    default:
      LOG(ERROR) << "No known extension for model type.";
  }
}

#undef SYNC_FREQ_HISTOGRAM

// TODO(akalin): Figure out a better way to do these mappings.

namespace {
const char kBookmarkNotificationType[] = "BOOKMARK";
const char kPreferenceNotificationType[] = "PREFERENCE";
const char kPasswordNotificationType[] = "PASSWORD";
const char kAutofillNotificationType[] = "AUTOFILL";
const char kThemeNotificationType[] = "THEME";
const char kTypedUrlNotificationType[] = "TYPED_URL";
const char kExtensionNotificationType[] = "EXTENSION";
const char kNigoriNotificationType[] = "NIGORI";
const char kAppNotificationType[] = "APP";
const char kSessionNotificationType[] = "SESSION";
// TODO(lipalani) Bug 64111.
// talk to akalin to make sure this is what I understand this to be.
const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE";
// TODO(akalin): This is a hack to make new sync data types work with
// server-issued notifications.  Remove this when it's not needed
// anymore.
const char kUnknownNotificationType[] = "UNKNOWN";
}  // namespace

bool RealModelTypeToNotificationType(ModelType model_type,
                                     std::string* notification_type) {
  switch (model_type) {
    case BOOKMARKS:
      *notification_type = kBookmarkNotificationType;
      return true;
    case PREFERENCES:
      *notification_type = kPreferenceNotificationType;
      return true;
    case PASSWORDS:
      *notification_type = kPasswordNotificationType;
      return true;
    case AUTOFILL:
      *notification_type = kAutofillNotificationType;
      return true;
    case THEMES:
      *notification_type = kThemeNotificationType;
      return true;
    case TYPED_URLS:
      *notification_type = kTypedUrlNotificationType;
      return true;
    case EXTENSIONS:
      *notification_type = kExtensionNotificationType;
      return true;
    case NIGORI:
      *notification_type = kNigoriNotificationType;
      return true;
    case APPS:
      *notification_type = kAppNotificationType;
      return true;
    case SESSIONS:
      *notification_type = kSessionNotificationType;
      return true;
    case AUTOFILL_PROFILE:
      *notification_type = kAutofillProfileNotificationType;
      return true;
    // TODO(akalin): This is a hack to make new sync data types work with
    // server-issued notifications.  Remove this when it's not needed
    // anymore.
    case UNSPECIFIED:
      *notification_type = kUnknownNotificationType;
      return true;
    default:
      break;
  }
  notification_type->clear();
  return false;
}

bool NotificationTypeToRealModelType(const std::string& notification_type,
                                     ModelType* model_type) {
  if (notification_type == kBookmarkNotificationType) {
    *model_type = BOOKMARKS;
    return true;
  } else if (notification_type == kPreferenceNotificationType) {
    *model_type = PREFERENCES;
    return true;
  } else if (notification_type == kPasswordNotificationType) {
    *model_type = PASSWORDS;
    return true;
  } else if (notification_type == kAutofillNotificationType) {
    *model_type = AUTOFILL;
    return true;
  } else if (notification_type == kThemeNotificationType) {
    *model_type = THEMES;
    return true;
  } else if (notification_type == kTypedUrlNotificationType) {
    *model_type = TYPED_URLS;
    return true;
  } else if (notification_type == kExtensionNotificationType) {
    *model_type = EXTENSIONS;
    return true;
  } else if (notification_type == kNigoriNotificationType) {
    *model_type = NIGORI;
    return true;
  } else if (notification_type == kAppNotificationType) {
    *model_type = APPS;
    return true;
  } else if (notification_type == kSessionNotificationType) {
    *model_type = SESSIONS;
    return true;
  } else if (notification_type == kAutofillProfileNotificationType) {
    *model_type = AUTOFILL_PROFILE;
    return true;
  } else if (notification_type == kUnknownNotificationType) {
    // TODO(akalin): This is a hack to make new sync data types work with
    // server-issued notifications.  Remove this when it's not needed
    // anymore.
    *model_type = UNSPECIFIED;
    return true;
  }
  *model_type = UNSPECIFIED;
  return false;
}

}  // namespace syncable
<commit_msg>Adding missing AUTOFILL_PROFILE sync data type to model_type.cc<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/syncable/model_type.h"

#include <sstream>

#include "base/metrics/histogram.h"
#include "chrome/browser/sync/engine/syncproto.h"
#include "chrome/browser/sync/protocol/app_specifics.pb.h"
#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
#include "chrome/browser/sync/protocol/extension_specifics.pb.h"
#include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
#include "chrome/browser/sync/protocol/password_specifics.pb.h"
#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
#include "chrome/browser/sync/protocol/session_specifics.pb.h"
#include "chrome/browser/sync/protocol/sync.pb.h"
#include "chrome/browser/sync/protocol/theme_specifics.pb.h"
#include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"

namespace syncable {

void AddDefaultExtensionValue(syncable::ModelType datatype,
                              sync_pb::EntitySpecifics* specifics) {
  switch (datatype) {
    case BOOKMARKS:
      specifics->MutableExtension(sync_pb::bookmark);
      break;
    case PASSWORDS:
      specifics->MutableExtension(sync_pb::password);
      break;
    case PREFERENCES:
      specifics->MutableExtension(sync_pb::preference);
      break;
    case AUTOFILL:
      specifics->MutableExtension(sync_pb::autofill);
      break;
    case AUTOFILL_PROFILE:
      specifics->MutableExtension(sync_pb::autofill_profile);
      break;
    case THEMES:
      specifics->MutableExtension(sync_pb::theme);
      break;
    case TYPED_URLS:
      specifics->MutableExtension(sync_pb::typed_url);
      break;
    case EXTENSIONS:
      specifics->MutableExtension(sync_pb::extension);
      break;
    case NIGORI:
      specifics->MutableExtension(sync_pb::nigori);
      break;
    case SESSIONS:
      specifics->MutableExtension(sync_pb::session);
      break;
    case APPS:
      specifics->MutableExtension(sync_pb::app);
      break;
    default:
      NOTREACHED() << "No known extension for model type.";
  }
}

// Note: keep this consistent with GetModelType in syncable.cc!
ModelType GetModelType(const sync_pb::SyncEntity& sync_pb_entity) {
  const browser_sync::SyncEntity& sync_entity =
      static_cast<const browser_sync::SyncEntity&>(sync_pb_entity);
  DCHECK(!sync_entity.id().IsRoot());  // Root shouldn't ever go over the wire.

  if (sync_entity.deleted())
    return UNSPECIFIED;

  // Backwards compatibility with old (pre-specifics) protocol.
  if (sync_entity.has_bookmarkdata())
    return BOOKMARKS;

  ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics());
  if (specifics_type != UNSPECIFIED)
    return specifics_type;

  // Loose check for server-created top-level folders that aren't
  // bound to a particular model type.
  if (!sync_entity.server_defined_unique_tag().empty() &&
      sync_entity.IsFolder()) {
    return TOP_LEVEL_FOLDER;
  }

  // This is an item of a datatype we can't understand. Maybe it's
  // from the future?  Either we mis-encoded the object, or the
  // server sent us entries it shouldn't have.
  NOTREACHED() << "Unknown datatype in sync proto.";
  return UNSPECIFIED;
}

ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
  if (specifics.HasExtension(sync_pb::bookmark))
    return BOOKMARKS;

  if (specifics.HasExtension(sync_pb::password))
    return PASSWORDS;

  if (specifics.HasExtension(sync_pb::preference))
    return PREFERENCES;

  if (specifics.HasExtension(sync_pb::autofill))
    return AUTOFILL;

  if (specifics.HasExtension(sync_pb::autofill_profile))
    return AUTOFILL_PROFILE;

  if (specifics.HasExtension(sync_pb::theme))
    return THEMES;

  if (specifics.HasExtension(sync_pb::typed_url))
    return TYPED_URLS;

  if (specifics.HasExtension(sync_pb::extension))
    return EXTENSIONS;

  if (specifics.HasExtension(sync_pb::nigori))
    return NIGORI;

  if (specifics.HasExtension(sync_pb::app))
    return APPS;

  if (specifics.HasExtension(sync_pb::session))
    return SESSIONS;

  return UNSPECIFIED;
}

std::string ModelTypeToString(ModelType model_type) {
  switch (model_type) {
    case BOOKMARKS:
      return "Bookmarks";
    case PREFERENCES:
      return "Preferences";
    case PASSWORDS:
      return "Passwords";
    case AUTOFILL:
      return "Autofill";
    case THEMES:
      return "Themes";
    case TYPED_URLS:
      return "Typed URLs";
    case EXTENSIONS:
      return "Extensions";
    case NIGORI:
      return "Encryption keys";
    case SESSIONS:
      return "Sessions";
    case APPS:
      return "Apps";
    case AUTOFILL_PROFILE:
      return "Autofill Profiles";
      break;
    default:
      NOTREACHED() << "No known extension for model type.";
      return "INVALID";
  }
}

ModelType ModelTypeFromString(const std::string& model_type_string) {
  if (model_type_string == "Bookmarks")
    return BOOKMARKS;
  else if (model_type_string == "Preferences")
    return PREFERENCES;
  else if (model_type_string == "Passwords")
    return PASSWORDS;
  else if (model_type_string == "Autofill")
    return AUTOFILL;
  else if (model_type_string == "Autofill Profiles")
    return AUTOFILL_PROFILE;
  else if (model_type_string == "Themes")
    return THEMES;
  else if (model_type_string == "Typed URLs")
    return TYPED_URLS;
  else if (model_type_string == "Extensions")
    return EXTENSIONS;
  else if (model_type_string == "Encryption keys")
    return NIGORI;
  else if (model_type_string == "Sessions")
    return SESSIONS;
  else if (model_type_string == "Apps")
    return APPS;
  else
    NOTREACHED() << "No known model type corresponding to "
                 << model_type_string << ".";
  return UNSPECIFIED;
}

bool ModelTypeBitSetFromString(
    const std::string& model_type_bitset_string,
    ModelTypeBitSet* model_types) {
  if (model_type_bitset_string.length() != MODEL_TYPE_COUNT) {
    return false;
  }

  std::istringstream iss(model_type_bitset_string);
  iss >> *model_types;
  iss.peek();   // Need to peek before checking EOF.
  return iss.eof();
}

// For now, this just implements UMA_HISTOGRAM_LONG_TIMES. This can be adjusted
// if we feel the min, max, or bucket count amount are not appropriate.
#define SYNC_FREQ_HISTOGRAM(name, time) UMA_HISTOGRAM_CUSTOM_TIMES( \
    name, time, base::TimeDelta::FromMilliseconds(1), \
    base::TimeDelta::FromHours(1), 50)

void PostTimeToTypeHistogram(ModelType model_type, base::TimeDelta time) {
  switch (model_type) {
    case BOOKMARKS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqBookmarks", time);
        return;
    }
    case PREFERENCES: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqPreferences", time);
        return;
    }
    case PASSWORDS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqPasswords", time);
        return;
    }
    case AUTOFILL: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqAutofill", time);
        return;
    }
    case AUTOFILL_PROFILE: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqAutofillProfiles", time);
        return;
    }
    case THEMES: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqThemes", time);
        return;
    }
    case TYPED_URLS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqTypedUrls", time);
        return;
    }
    case EXTENSIONS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqExtensions", time);
        return;
    }
    case NIGORI: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqNigori", time);
        return;
    }
    case SESSIONS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqSessions", time);
        return;
    }
    case APPS: {
        SYNC_FREQ_HISTOGRAM("Sync.FreqApps", time);
        return;
    }
    default:
      LOG(ERROR) << "No known extension for model type.";
  }
}

#undef SYNC_FREQ_HISTOGRAM

// TODO(akalin): Figure out a better way to do these mappings.

namespace {
const char kBookmarkNotificationType[] = "BOOKMARK";
const char kPreferenceNotificationType[] = "PREFERENCE";
const char kPasswordNotificationType[] = "PASSWORD";
const char kAutofillNotificationType[] = "AUTOFILL";
const char kThemeNotificationType[] = "THEME";
const char kTypedUrlNotificationType[] = "TYPED_URL";
const char kExtensionNotificationType[] = "EXTENSION";
const char kNigoriNotificationType[] = "NIGORI";
const char kAppNotificationType[] = "APP";
const char kSessionNotificationType[] = "SESSION";
// TODO(lipalani) Bug 64111.
// talk to akalin to make sure this is what I understand this to be.
const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE";
// TODO(akalin): This is a hack to make new sync data types work with
// server-issued notifications.  Remove this when it's not needed
// anymore.
const char kUnknownNotificationType[] = "UNKNOWN";
}  // namespace

bool RealModelTypeToNotificationType(ModelType model_type,
                                     std::string* notification_type) {
  switch (model_type) {
    case BOOKMARKS:
      *notification_type = kBookmarkNotificationType;
      return true;
    case PREFERENCES:
      *notification_type = kPreferenceNotificationType;
      return true;
    case PASSWORDS:
      *notification_type = kPasswordNotificationType;
      return true;
    case AUTOFILL:
      *notification_type = kAutofillNotificationType;
      return true;
    case THEMES:
      *notification_type = kThemeNotificationType;
      return true;
    case TYPED_URLS:
      *notification_type = kTypedUrlNotificationType;
      return true;
    case EXTENSIONS:
      *notification_type = kExtensionNotificationType;
      return true;
    case NIGORI:
      *notification_type = kNigoriNotificationType;
      return true;
    case APPS:
      *notification_type = kAppNotificationType;
      return true;
    case SESSIONS:
      *notification_type = kSessionNotificationType;
      return true;
    case AUTOFILL_PROFILE:
      *notification_type = kAutofillProfileNotificationType;
      return true;
    // TODO(akalin): This is a hack to make new sync data types work with
    // server-issued notifications.  Remove this when it's not needed
    // anymore.
    case UNSPECIFIED:
      *notification_type = kUnknownNotificationType;
      return true;
    default:
      break;
  }
  notification_type->clear();
  return false;
}

bool NotificationTypeToRealModelType(const std::string& notification_type,
                                     ModelType* model_type) {
  if (notification_type == kBookmarkNotificationType) {
    *model_type = BOOKMARKS;
    return true;
  } else if (notification_type == kPreferenceNotificationType) {
    *model_type = PREFERENCES;
    return true;
  } else if (notification_type == kPasswordNotificationType) {
    *model_type = PASSWORDS;
    return true;
  } else if (notification_type == kAutofillNotificationType) {
    *model_type = AUTOFILL;
    return true;
  } else if (notification_type == kThemeNotificationType) {
    *model_type = THEMES;
    return true;
  } else if (notification_type == kTypedUrlNotificationType) {
    *model_type = TYPED_URLS;
    return true;
  } else if (notification_type == kExtensionNotificationType) {
    *model_type = EXTENSIONS;
    return true;
  } else if (notification_type == kNigoriNotificationType) {
    *model_type = NIGORI;
    return true;
  } else if (notification_type == kAppNotificationType) {
    *model_type = APPS;
    return true;
  } else if (notification_type == kSessionNotificationType) {
    *model_type = SESSIONS;
    return true;
  } else if (notification_type == kAutofillProfileNotificationType) {
    *model_type = AUTOFILL_PROFILE;
    return true;
  } else if (notification_type == kUnknownNotificationType) {
    // TODO(akalin): This is a hack to make new sync data types work with
    // server-issued notifications.  Remove this when it's not needed
    // anymore.
    *model_type = UNSPECIFIED;
    return true;
  }
  *model_type = UNSPECIFIED;
  return false;
}

}  // namespace syncable
<|endoftext|>


<commit_before>#include "Universe.hpp"

using namespace sf;
using namespace std;

Universe::Universe()
	: show_path(false), old_paths(LinesStrip)
{

}

void Universe::addPlanet(Vector2f position, uint64_t m, Vector2f dir)
{
	planets.push_back(Body(position, m, dir, show_path));
}

void Universe::addPlanet(Body p)
{
	p.setPathEnabled(show_path);
	planets.push_back(p);
}

void Universe::createProtodisk(const int number, const int radius, const int mass, const sf::Vector2f& position)
{
	for (int i = 0; i < number; i++)
	{
		float a = distribution(rng);
		float b = distribution(rng);

		if (b > a)
		{
			std::swap(a, b);
		}

		Vector2f pos(b*radius*cos(2*M_PI*a/b), b*radius*sin(2*M_PI*a/b));
		float len = sqrt(pos.x*pos.x + pos.y*pos.y);
		pos += position;

		Vector2f dir = tangentThroughPoint(position, len, pos);
		if (isnan(dir.x) || isnan(dir.y))
		{
			dir = Vector2f();
		}

		dir *= 125.0f;

		Body p(pos, mass, dir, show_path);
		planets.push_back(p);
	}
}

void Universe::togglePath()
{
	show_path = !show_path;

	for (Body& b : planets)
	{
		b.setPathEnabled(show_path);
	}

	if (!show_path)
	{
		old_paths.clear();
	}
}

void Universe::move(float delta_t)
{
	if (planets.size() < 1)
	{
		return;
	}

	for (unsigned int i = 0; i < planets.size(); i++)
	{
		for (unsigned int j = 0; j < planets.size(); j++)
		{
			if (i != j)
			{
				if (planets[i].collideWith(planets[j]))
				{
					Body p = combinedPlanets(planets[i], planets[j]);
					p.setPathEnabled(show_path);

					planets.push_back(p);

					savePlanetPath(planets[i]);
					savePlanetPath(planets[j]);

					planets.erase(planets.begin()+j);
					planets.erase(planets.begin()+i);
				}

				planets[i].applyGravityOf(planets[j], delta_t);
			}
		}
	}

	for (Body& b : planets)
	{
		b.move(delta_t);
	}
}

void Universe::draw(RenderWindow& window)
{
	for (Body& b : planets)
	{
		b.draw(window);
	}

	if (show_path)
	{
		for (VertexArray& path : old_paths)
		{
			window.draw(path);
		}
	}
}

void Universe::eraseAt(const Vector2f& pos)
{
	for (unsigned int i = 0; i < planets.size(); i++)
	{
		if (planets[i].contains(Vector2f(pos.x, pos.y)))
		{
			planets.erase(planets.begin()+i);
		}
	}
}

void Universe::eraseAll()
{
	planets.clear();
	old_paths.clear();
}

void Universe::savePlanetPath(const Body& b)
{
	old_paths.push_back(b.getPath());
}

// helper functions
Body combinedPlanets(const Body& a, const Body& b)
{
	Vector2f p1m1 = float(a.mass)*a.direction;
	Vector2f p2m2 = float(b.mass)*b.direction;

	uint64_t total_mass(a.mass+b.mass);
	Vector2f direction = (p1m1+p2m2) / float(total_mass);

	Vector2f pos = (a.mass >= b.mass ? a.position :
									   b.position);

	return Body(pos, total_mass, direction, false);
}

Vector2f tangentThroughPoint(Vector2f circle_center, float radius, Vector2f point)
{
	Vector2f dir = point - circle_center;
	float len = sqrt(dir.x*dir.x + dir.y*dir.y);
	float angle = atan2(dir.y, dir.x);

	float tangent_length = sqrt(len*len - radius*radius);
	float tangent_angle = asin(radius/len);

	//Vector2f pos(angle+tangent_angle);
	float neg(angle-tangent_angle);

	return Vector2f(cos(neg), sin(neg));
}
<commit_msg>the speed of the planets in the protodisk now depends on their distance from the center<commit_after>#include "Universe.hpp"

using namespace sf;
using namespace std;

Universe::Universe()
	: show_path(false), old_paths(LinesStrip)
{

}

void Universe::addPlanet(Vector2f position, uint64_t m, Vector2f dir)
{
	planets.push_back(Body(position, m, dir, show_path));
}

void Universe::addPlanet(Body p)
{
	p.setPathEnabled(show_path);
	planets.push_back(p);
}

void Universe::createProtodisk(const int number, const int radius, const int mass, const sf::Vector2f& position)
{
	int cancelled = 0;
	for (int i = 0; i < number; i++)
	{
		float a = distribution(rng);
		float b = distribution(rng);

		if (b > a)
		{
			std::swap(a, b);
		}

		Vector2f pos(b*radius*cos(2*M_PI*a/b), b*radius*sin(2*M_PI*a/b));
		float len = sqrt(pos.x*pos.x + pos.y*pos.y);
		pos += position;

		Vector2f dir = tangentThroughPoint(position, len, pos);
		if (isnan(dir.x) || isnan(dir.y))
		{
			cout << "cancelled at len=" << len << endl;
			cout << " - number " << ++cancelled  << endl;
			dir = Vector2f();
		}

		dir *= interpolate(125.0f, 75.0f, len/radius);

		Body p(pos, mass, dir, show_path);
		planets.push_back(p);
	}
}

void Universe::togglePath()
{
	show_path = !show_path;

	for (Body& b : planets)
	{
		b.setPathEnabled(show_path);
	}

	if (!show_path)
	{
		old_paths.clear();
	}
}

void Universe::move(float delta_t)
{
	if (planets.size() < 1)
	{
		return;
	}

	for (unsigned int i = 0; i < planets.size(); i++)
	{
		for (unsigned int j = 0; j < planets.size(); j++)
		{
			if (i != j)
			{
				if (planets[i].collideWith(planets[j]))
				{
					Body p = combinedPlanets(planets[i], planets[j]);
					p.setPathEnabled(show_path);

					planets.push_back(p);

					savePlanetPath(planets[i]);
					savePlanetPath(planets[j]);

					planets.erase(planets.begin()+j);
					planets.erase(planets.begin()+i);
				}

				planets[i].applyGravityOf(planets[j], delta_t);
			}
		}
	}

	for (Body& b : planets)
	{
		b.move(delta_t);
	}
}

void Universe::draw(RenderWindow& window)
{
	for (Body& b : planets)
	{
		b.draw(window);
	}

	if (show_path)
	{
		for (VertexArray& path : old_paths)
		{
			window.draw(path);
		}
	}
}

void Universe::eraseAt(const Vector2f& pos)
{
	for (unsigned int i = 0; i < planets.size(); i++)
	{
		if (planets[i].contains(Vector2f(pos.x, pos.y)))
		{
			planets.erase(planets.begin()+i);
		}
	}
}

void Universe::eraseAll()
{
	planets.clear();
	old_paths.clear();
}

void Universe::savePlanetPath(const Body& b)
{
	old_paths.push_back(b.getPath());
}

// helper functions
Body combinedPlanets(const Body& a, const Body& b)
{
	Vector2f p1m1 = float(a.mass)*a.direction;
	Vector2f p2m2 = float(b.mass)*b.direction;

	uint64_t total_mass(a.mass+b.mass);
	Vector2f direction = (p1m1+p2m2) / float(total_mass);

	Vector2f pos = (a.mass >= b.mass ? a.position :
									   b.position);

	return Body(pos, total_mass, direction, false);
}

Vector2f tangentThroughPoint(Vector2f circle_center, float radius, Vector2f point)
{
	Vector2f dir = point - circle_center;
	float len = sqrt(dir.x*dir.x + dir.y*dir.y);
	float angle = atan2(dir.y, dir.x);

	float tangent_length = sqrt(len*len - radius*radius);
	float tangent_angle = asin(radius/len);

	//Vector2f pos(angle+tangent_angle);
	float neg(angle-tangent_angle);

	return Vector2f(cos(neg), sin(neg));
}
<|endoftext|>


<commit_before><commit_msg>GetThemeProvider error in DownloadItemView. Just remove the offending line for now.<commit_after><|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Pavel Strakhov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "MainWindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  a.setOrganizationName("ToolWindowManagerTest");
  a.setApplicationName("ToolWindowManagerTest");
  MainWindow* w = new MainWindow();
  w->show();

  return a.exec();
}
<commit_msg>Fix string literal compile error that didn't show up before<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Pavel Strakhov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "MainWindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  a.setOrganizationName(QStringLiteral("ToolWindowManagerTest"));
  a.setApplicationName(QStringLiteral("ToolWindowManagerTest"));
  MainWindow* w = new MainWindow();
  w->show();

  return a.exec();
}
<|endoftext|>


<commit_before><commit_msg>Be more specific with bookmark bar visibility to mirror other platforms. Fixes pyauto bookmark bar visibility test on ChromeOS.<commit_after><|endoftext|>


<commit_before><commit_msg>Make most of browser_view compile on Linux. Review URL: http://codereview.chromium.org/115786<commit_after><|endoftext|>


<commit_before>//                                MFEM Example 5
//
// Compile with: make ex5
//
// Sample runs:  ex5 -m ../data/square-disc.mesh
//               ex5 -m ../data/star.mesh
//               ex5 -m ../data/beam-tet.mesh
//               ex5 -m ../data/beam-hex.mesh
//               ex5 -m ../data/escher.mesh
//               ex5 -m ../data/fichera.mesh
//
// Description:  This example code solves a simple 2D/3D mixed Darcy problem
//               corresponding to the saddle point system
//                                 k*u + grad p = f
//                                 - div u      = g
//               with natural boundary condition -p = <given pressure>.
//               Here, we use a given exact solution (u,p) and compute the
//               corresponding r.h.s. (f,g).  We discretize with Raviart-Thomas
//               finite elements (velocity u) and piecewise discontinuous
//               polynomials (pressure p).
//
//               The example demonstrates the use of the BlockMatrix class, as
//               well as the collective saving of several grid functions in a
//               VisIt (visit.llnl.gov) visualization format.
//
//               We recommend viewing examples 1-4 before viewing this example.

#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <algorithm>

using namespace std;
using namespace mfem;

// Define the analytical solution and forcing terms / boundary conditions
void uFun_ex(const Vector & x, Vector & u);
double pFun_ex(const Vector & x);
void fFun(const Vector & x, Vector & f);
double gFun(const Vector & x);
double f_natural(const Vector & x);

int main(int argc, char *argv[])
{
   StopWatch chrono;

   // 1. Parse command-line options.
   const char *mesh_file = "../data/star.mesh";
   int order = 1;
   bool visualization = 1;

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh",
                  "Mesh file to use.");
   args.AddOption(&order, "-o", "--order",
                  "Finite element order (polynomial degree).");
   args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");
   args.Parse();
   if (!args.Good())
   {
      args.PrintUsage(cout);
      return 1;
   }
   args.PrintOptions(cout);

   // 2. Read the mesh from the given mesh file. We can handle triangular,
   //    quadrilateral, tetrahedral, hexahedral, surface and volume meshes with
   //    the same code.
   Mesh *mesh = new Mesh(mesh_file, 1, 1);
   int dim = mesh->Dimension();

   // 3. Refine the mesh to increase the resolution. In this example we do
   //    'ref_levels' of uniform refinement. We choose 'ref_levels' to be the
   //    largest number that gives a final mesh with no more than 10,000
   //    elements.
   {
      int ref_levels =
         (int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
      for (int l = 0; l < ref_levels; l++)
      {
         mesh->UniformRefinement();
      }
   }

   // 4. Define a finite element space on the mesh. Here we use the
   //    Raviart-Thomas finite elements of the specified order.
   FiniteElementCollection *hdiv_coll(new RT_FECollection(order, dim));
   FiniteElementCollection *l2_coll(new L2_FECollection(order, dim));

   FiniteElementSpace *R_space = new FiniteElementSpace(mesh, hdiv_coll);
   FiniteElementSpace *W_space = new FiniteElementSpace(mesh, l2_coll);

   // 5. Define the BlockStructure of the problem, i.e. define the array of
   //    offsets for each variable. The last component of the Array is the sum
   //    of the dimensions of each block.
   Array<int> block_offsets(3); // number of variables + 1
   block_offsets[0] = 0;
   block_offsets[1] = R_space->GetVSize();
   block_offsets[2] = W_space->GetVSize();
   block_offsets.PartialSum();

   std::cout << "***********************************************************\n";
   std::cout << "dim(R) = " << block_offsets[1] - block_offsets[0] << "\n";
   std::cout << "dim(W) = " << block_offsets[2] - block_offsets[1] << "\n";
   std::cout << "dim(R+W) = " << block_offsets.Last() << "\n";
   std::cout << "***********************************************************\n";

   // 6. Define the coefficients, analytical solution, and rhs of the PDE.
   ConstantCoefficient k(1.0);

   VectorFunctionCoefficient fcoeff(dim, fFun);
   FunctionCoefficient fnatcoeff(f_natural);
   FunctionCoefficient gcoeff(gFun);

   VectorFunctionCoefficient ucoeff(dim, uFun_ex);
   FunctionCoefficient pcoeff(pFun_ex);

   // 7. Allocate memory (x, rhs) for the analytical solution and the right hand
   //    side.  Define the GridFunction u,p for the finite element solution and
   //    linear forms fform and gform for the right hand side.  The data
   //    allocated by x and rhs are passed as a reference to the grid functions
   //    (u,p) and the linear forms (fform, gform).
   BlockVector x(block_offsets), rhs(block_offsets);

   LinearForm *fform(new LinearForm);
   fform->Update(R_space, rhs.GetBlock(0), 0);
   fform->AddDomainIntegrator(new VectorFEDomainLFIntegrator(fcoeff));
   fform->AddBoundaryIntegrator(new VectorFEBoundaryFluxLFIntegrator(fnatcoeff));
   fform->Assemble();

   LinearForm *gform(new LinearForm);
   gform->Update(W_space, rhs.GetBlock(1), 0);
   gform->AddDomainIntegrator(new DomainLFIntegrator(gcoeff));
   gform->Assemble();

   // 8. Assemble the finite element matrices for the Darcy operator
   //
   //                            D = [ M  B^T ]
   //                                [ B   0  ]
   //     where:
   //
   //     M = \int_\Omega k u_h \cdot v_h d\Omega   u_h, v_h \in R_h
   //     B   = -\int_\Omega \div u_h q_h d\Omega   u_h \in R_h, q_h \in W_h
   BilinearForm *mVarf(new BilinearForm(R_space));
   MixedBilinearForm *bVarf(new MixedBilinearForm(R_space, W_space));

   mVarf->AddDomainIntegrator(new VectorFEMassIntegrator(k));
   mVarf->Assemble();
   mVarf->Finalize();
   SparseMatrix &M(mVarf->SpMat());

   bVarf->AddDomainIntegrator(new VectorFEDivergenceIntegrator);
   bVarf->Assemble();
   bVarf->Finalize();
   SparseMatrix & B(bVarf->SpMat());
   B *= -1.;
   SparseMatrix *BT = Transpose(B);

   BlockMatrix darcyMatrix(block_offsets);
   darcyMatrix.SetBlock(0,0, &M);
   darcyMatrix.SetBlock(0,1, BT);
   darcyMatrix.SetBlock(1,0, &B);

   // 9. Construct the operators for preconditioner
   //
   //                 P = [ diag(M)         0         ]
   //                     [  0       B diag(M)^-1 B^T ]
   //
   //     Here we use Symmetric Gauss-Seidel to approximate the inverse of the
   //     pressure Schur Complement
   SparseMatrix *MinvBt = Transpose(B);
   Vector Md(M.Height());
   M.GetDiag(Md);
   for (int i = 0; i < Md.Size(); i++)
   {
      MinvBt->ScaleRow(i, 1./Md(i));
   }
   SparseMatrix *S = Mult(B, *MinvBt);

   Solver *invM, *invS;
   invM = new DSmoother(M);
#ifndef MFEM_USE_SUITESPARSE
   invS = new GSSmoother(*S);
#else
   invS = new UMFPackSolver(*S);
#endif

   invM->iterative_mode = false;
   invS->iterative_mode = false;

   BlockDiagonalPreconditioner darcyPrec(block_offsets);
   darcyPrec.SetDiagonalBlock(0, invM);
   darcyPrec.SetDiagonalBlock(1, invS);

   // 10. Solve the linear system with MINRES.
   //     Check the norm of the unpreconditioned residual.
   int maxIter(1000);
   double rtol(1.e-6);
   double atol(1.e-10);

   chrono.Clear();
   chrono.Start();
   MINRESSolver solver;
   solver.SetAbsTol(atol);
   solver.SetRelTol(rtol);
   solver.SetMaxIter(maxIter);
   solver.SetOperator(darcyMatrix);
   solver.SetPreconditioner(darcyPrec);
   solver.SetPrintLevel(1);
   x = 0.0;
   solver.Mult(rhs, x);
   chrono.Stop();

   if (solver.GetConverged())
      std::cout << "MINRES converged in " << solver.GetNumIterations()
                << " iterations with a residual norm of " << solver.GetFinalNorm() << ".\n";
   else
      std::cout << "MINRES did not converge in " << solver.GetNumIterations()
                << " iterations. Residual norm is " << solver.GetFinalNorm() << ".\n";
   std::cout << "MINRES solver took " << chrono.RealTime() << "s. \n";

   // 11. Create the grid functions u and p. Compute the L2 error norms.
   GridFunction u, p;
   u.MakeRef(R_space, x.GetBlock(0), 0);
   p.MakeRef(W_space, x.GetBlock(1), 0);

   int order_quad = max(2, 2*order+1);
   const IntegrationRule *irs[Geometry::NumGeom];
   for (int i=0; i < Geometry::NumGeom; ++i)
   {
      irs[i] = &(IntRules.Get(i, order_quad));
   }

   double err_u  = u.ComputeL2Error(ucoeff, irs);
   double norm_u = ComputeLpNorm(2., ucoeff, *mesh, irs);
   double err_p  = p.ComputeL2Error(pcoeff, irs);
   double norm_p = ComputeLpNorm(2., pcoeff, *mesh, irs);

   std::cout << "|| u_h - u_ex || / || u_ex || = " << err_u / norm_u << "\n";
   std::cout << "|| p_h - p_ex || / || p_ex || = " << err_p / norm_p << "\n";

   // 12. Save the mesh and the solution. This output can be viewed later using
   //     GLVis: "glvis -m ex5.mesh -g sol_u.gf" or "glvis -m ex5.mesh -g
   //     sol_p.gf".
   {
      ofstream mesh_ofs("ex5.mesh");
      mesh_ofs.precision(8);
      mesh->Print(mesh_ofs);

      ofstream u_ofs("sol_u.gf");
      u_ofs.precision(8);
      u.Save(u_ofs);

      ofstream p_ofs("sol_p.gf");
      p_ofs.precision(8);
      p.Save(p_ofs);
   }

   // 13. Save data in the VisIt format
   VisItDataCollection visit_dc("Example5", mesh);
   visit_dc.RegisterField("velocity", &u);
   visit_dc.RegisterField("pressure", &p);
   visit_dc.Save();

   // 14. Save data in the Paraview format
   ParaviewDataCollection paraview_dc("PExample5", mesh);
   paraview_dc.SetLevelsOfDetail(2);
   paraview_dc.SetCycle(1);
   paraview_dc.SetTime(0.0); //set the time
   paraview_dc.RegisterField("velocity",&u);
   paraview_dc.RegisterField("pressure",&p);
   paraview_dc.Save();

   // 15. Send the solution by socket to a GLVis server.
   if (visualization)
   {
      char vishost[] = "localhost";
      int  visport   = 19916;
      socketstream u_sock(vishost, visport);
      u_sock.precision(8);
      u_sock << "solution\n" << *mesh << u << "window_title 'Velocity'" << endl;
      socketstream p_sock(vishost, visport);
      p_sock.precision(8);
      p_sock << "solution\n" << *mesh << p << "window_title 'Pressure'" << endl;
   }

   // 16. Free the used memory.
   delete fform;
   delete gform;
   delete invM;
   delete invS;
   delete S;
   delete MinvBt;
   delete BT;
   delete mVarf;
   delete bVarf;
   delete W_space;
   delete R_space;
   delete l2_coll;
   delete hdiv_coll;
   delete mesh;

   return 0;
}

void uFun_ex(const Vector & x, Vector & u)
{
   double xi(x(0));
   double yi(x(1));
   double zi(0.0);
   if (x.Size() == 3)
   {
      zi = x(2);
   }

   u(0) = - exp(xi)*sin(yi)*cos(zi);
   u(1) = - exp(xi)*cos(yi)*cos(zi);

   if (x.Size() == 3)
   {
      u(2) = exp(xi)*sin(yi)*sin(zi);
   }
}

// Change if needed
double pFun_ex(const Vector & x)
{
   double xi(x(0));
   double yi(x(1));
   double zi(0.0);

   if (x.Size() == 3)
   {
      zi = x(2);
   }

   return exp(xi)*sin(yi)*cos(zi);
}

void fFun(const Vector & x, Vector & f)
{
   f = 0.0;
}

double gFun(const Vector & x)
{
   if (x.Size() == 3)
   {
      return -pFun_ex(x);
   }
   else
   {
      return 0;
   }
}

double f_natural(const Vector & x)
{
   return (-pFun_ex(x));
}
<commit_msg>make style<commit_after>//                                MFEM Example 5
//
// Compile with: make ex5
//
// Sample runs:  ex5 -m ../data/square-disc.mesh
//               ex5 -m ../data/star.mesh
//               ex5 -m ../data/beam-tet.mesh
//               ex5 -m ../data/beam-hex.mesh
//               ex5 -m ../data/escher.mesh
//               ex5 -m ../data/fichera.mesh
//
// Description:  This example code solves a simple 2D/3D mixed Darcy problem
//               corresponding to the saddle point system
//                                 k*u + grad p = f
//                                 - div u      = g
//               with natural boundary condition -p = <given pressure>.
//               Here, we use a given exact solution (u,p) and compute the
//               corresponding r.h.s. (f,g).  We discretize with Raviart-Thomas
//               finite elements (velocity u) and piecewise discontinuous
//               polynomials (pressure p).
//
//               The example demonstrates the use of the BlockMatrix class, as
//               well as the collective saving of several grid functions in a
//               VisIt (visit.llnl.gov) visualization format.
//
//               We recommend viewing examples 1-4 before viewing this example.

#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <algorithm>

using namespace std;
using namespace mfem;

// Define the analytical solution and forcing terms / boundary conditions
void uFun_ex(const Vector & x, Vector & u);
double pFun_ex(const Vector & x);
void fFun(const Vector & x, Vector & f);
double gFun(const Vector & x);
double f_natural(const Vector & x);

int main(int argc, char *argv[])
{
   StopWatch chrono;

   // 1. Parse command-line options.
   const char *mesh_file = "../data/star.mesh";
   int order = 1;
   bool visualization = 1;

   OptionsParser args(argc, argv);
   args.AddOption(&mesh_file, "-m", "--mesh",
                  "Mesh file to use.");
   args.AddOption(&order, "-o", "--order",
                  "Finite element order (polynomial degree).");
   args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");
   args.Parse();
   if (!args.Good())
   {
      args.PrintUsage(cout);
      return 1;
   }
   args.PrintOptions(cout);

   // 2. Read the mesh from the given mesh file. We can handle triangular,
   //    quadrilateral, tetrahedral, hexahedral, surface and volume meshes with
   //    the same code.
   Mesh *mesh = new Mesh(mesh_file, 1, 1);
   int dim = mesh->Dimension();

   // 3. Refine the mesh to increase the resolution. In this example we do
   //    'ref_levels' of uniform refinement. We choose 'ref_levels' to be the
   //    largest number that gives a final mesh with no more than 10,000
   //    elements.
   {
      int ref_levels =
         (int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
      for (int l = 0; l < ref_levels; l++)
      {
         mesh->UniformRefinement();
      }
   }

   // 4. Define a finite element space on the mesh. Here we use the
   //    Raviart-Thomas finite elements of the specified order.
   FiniteElementCollection *hdiv_coll(new RT_FECollection(order, dim));
   FiniteElementCollection *l2_coll(new L2_FECollection(order, dim));

   FiniteElementSpace *R_space = new FiniteElementSpace(mesh, hdiv_coll);
   FiniteElementSpace *W_space = new FiniteElementSpace(mesh, l2_coll);

   // 5. Define the BlockStructure of the problem, i.e. define the array of
   //    offsets for each variable. The last component of the Array is the sum
   //    of the dimensions of each block.
   Array<int> block_offsets(3); // number of variables + 1
   block_offsets[0] = 0;
   block_offsets[1] = R_space->GetVSize();
   block_offsets[2] = W_space->GetVSize();
   block_offsets.PartialSum();

   std::cout << "***********************************************************\n";
   std::cout << "dim(R) = " << block_offsets[1] - block_offsets[0] << "\n";
   std::cout << "dim(W) = " << block_offsets[2] - block_offsets[1] << "\n";
   std::cout << "dim(R+W) = " << block_offsets.Last() << "\n";
   std::cout << "***********************************************************\n";

   // 6. Define the coefficients, analytical solution, and rhs of the PDE.
   ConstantCoefficient k(1.0);

   VectorFunctionCoefficient fcoeff(dim, fFun);
   FunctionCoefficient fnatcoeff(f_natural);
   FunctionCoefficient gcoeff(gFun);

   VectorFunctionCoefficient ucoeff(dim, uFun_ex);
   FunctionCoefficient pcoeff(pFun_ex);

   // 7. Allocate memory (x, rhs) for the analytical solution and the right hand
   //    side.  Define the GridFunction u,p for the finite element solution and
   //    linear forms fform and gform for the right hand side.  The data
   //    allocated by x and rhs are passed as a reference to the grid functions
   //    (u,p) and the linear forms (fform, gform).
   BlockVector x(block_offsets), rhs(block_offsets);

   LinearForm *fform(new LinearForm);
   fform->Update(R_space, rhs.GetBlock(0), 0);
   fform->AddDomainIntegrator(new VectorFEDomainLFIntegrator(fcoeff));
   fform->AddBoundaryIntegrator(new VectorFEBoundaryFluxLFIntegrator(fnatcoeff));
   fform->Assemble();

   LinearForm *gform(new LinearForm);
   gform->Update(W_space, rhs.GetBlock(1), 0);
   gform->AddDomainIntegrator(new DomainLFIntegrator(gcoeff));
   gform->Assemble();

   // 8. Assemble the finite element matrices for the Darcy operator
   //
   //                            D = [ M  B^T ]
   //                                [ B   0  ]
   //     where:
   //
   //     M = \int_\Omega k u_h \cdot v_h d\Omega   u_h, v_h \in R_h
   //     B   = -\int_\Omega \div u_h q_h d\Omega   u_h \in R_h, q_h \in W_h
   BilinearForm *mVarf(new BilinearForm(R_space));
   MixedBilinearForm *bVarf(new MixedBilinearForm(R_space, W_space));

   mVarf->AddDomainIntegrator(new VectorFEMassIntegrator(k));
   mVarf->Assemble();
   mVarf->Finalize();
   SparseMatrix &M(mVarf->SpMat());

   bVarf->AddDomainIntegrator(new VectorFEDivergenceIntegrator);
   bVarf->Assemble();
   bVarf->Finalize();
   SparseMatrix & B(bVarf->SpMat());
   B *= -1.;
   SparseMatrix *BT = Transpose(B);

   BlockMatrix darcyMatrix(block_offsets);
   darcyMatrix.SetBlock(0,0, &M);
   darcyMatrix.SetBlock(0,1, BT);
   darcyMatrix.SetBlock(1,0, &B);

   // 9. Construct the operators for preconditioner
   //
   //                 P = [ diag(M)         0         ]
   //                     [  0       B diag(M)^-1 B^T ]
   //
   //     Here we use Symmetric Gauss-Seidel to approximate the inverse of the
   //     pressure Schur Complement
   SparseMatrix *MinvBt = Transpose(B);
   Vector Md(M.Height());
   M.GetDiag(Md);
   for (int i = 0; i < Md.Size(); i++)
   {
      MinvBt->ScaleRow(i, 1./Md(i));
   }
   SparseMatrix *S = Mult(B, *MinvBt);

   Solver *invM, *invS;
   invM = new DSmoother(M);
#ifndef MFEM_USE_SUITESPARSE
   invS = new GSSmoother(*S);
#else
   invS = new UMFPackSolver(*S);
#endif

   invM->iterative_mode = false;
   invS->iterative_mode = false;

   BlockDiagonalPreconditioner darcyPrec(block_offsets);
   darcyPrec.SetDiagonalBlock(0, invM);
   darcyPrec.SetDiagonalBlock(1, invS);

   // 10. Solve the linear system with MINRES.
   //     Check the norm of the unpreconditioned residual.
   int maxIter(1000);
   double rtol(1.e-6);
   double atol(1.e-10);

   chrono.Clear();
   chrono.Start();
   MINRESSolver solver;
   solver.SetAbsTol(atol);
   solver.SetRelTol(rtol);
   solver.SetMaxIter(maxIter);
   solver.SetOperator(darcyMatrix);
   solver.SetPreconditioner(darcyPrec);
   solver.SetPrintLevel(1);
   x = 0.0;
   solver.Mult(rhs, x);
   chrono.Stop();

   if (solver.GetConverged())
      std::cout << "MINRES converged in " << solver.GetNumIterations()
                << " iterations with a residual norm of " << solver.GetFinalNorm() << ".\n";
   else
      std::cout << "MINRES did not converge in " << solver.GetNumIterations()
                << " iterations. Residual norm is " << solver.GetFinalNorm() << ".\n";
   std::cout << "MINRES solver took " << chrono.RealTime() << "s. \n";

   // 11. Create the grid functions u and p. Compute the L2 error norms.
   GridFunction u, p;
   u.MakeRef(R_space, x.GetBlock(0), 0);
   p.MakeRef(W_space, x.GetBlock(1), 0);

   int order_quad = max(2, 2*order+1);
   const IntegrationRule *irs[Geometry::NumGeom];
   for (int i=0; i < Geometry::NumGeom; ++i)
   {
      irs[i] = &(IntRules.Get(i, order_quad));
   }

   double err_u  = u.ComputeL2Error(ucoeff, irs);
   double norm_u = ComputeLpNorm(2., ucoeff, *mesh, irs);
   double err_p  = p.ComputeL2Error(pcoeff, irs);
   double norm_p = ComputeLpNorm(2., pcoeff, *mesh, irs);

   std::cout << "|| u_h - u_ex || / || u_ex || = " << err_u / norm_u << "\n";
   std::cout << "|| p_h - p_ex || / || p_ex || = " << err_p / norm_p << "\n";

   // 12. Save the mesh and the solution. This output can be viewed later using
   //     GLVis: "glvis -m ex5.mesh -g sol_u.gf" or "glvis -m ex5.mesh -g
   //     sol_p.gf".
   {
      ofstream mesh_ofs("ex5.mesh");
      mesh_ofs.precision(8);
      mesh->Print(mesh_ofs);

      ofstream u_ofs("sol_u.gf");
      u_ofs.precision(8);
      u.Save(u_ofs);

      ofstream p_ofs("sol_p.gf");
      p_ofs.precision(8);
      p.Save(p_ofs);
   }

   // 13. Save data in the VisIt format
   VisItDataCollection visit_dc("Example5", mesh);
   visit_dc.RegisterField("velocity", &u);
   visit_dc.RegisterField("pressure", &p);
   visit_dc.Save();

   // 14. Save data in the Paraview format
   ParaviewDataCollection paraview_dc("PExample5", mesh);
   paraview_dc.SetLevelsOfDetail(2);
   paraview_dc.SetCycle(1);
   paraview_dc.SetTime(0.0); //set the time
   paraview_dc.RegisterField("velocity",&u);
   paraview_dc.RegisterField("pressure",&p);
   paraview_dc.Save();

   // 15. Send the solution by socket to a GLVis server.
   if (visualization)
   {
      char vishost[] = "localhost";
      int  visport   = 19916;
      socketstream u_sock(vishost, visport);
      u_sock.precision(8);
      u_sock << "solution\n" << *mesh << u << "window_title 'Velocity'" << endl;
      socketstream p_sock(vishost, visport);
      p_sock.precision(8);
      p_sock << "solution\n" << *mesh << p << "window_title 'Pressure'" << endl;
   }

   // 16. Free the used memory.
   delete fform;
   delete gform;
   delete invM;
   delete invS;
   delete S;
   delete MinvBt;
   delete BT;
   delete mVarf;
   delete bVarf;
   delete W_space;
   delete R_space;
   delete l2_coll;
   delete hdiv_coll;
   delete mesh;

   return 0;
}

void uFun_ex(const Vector & x, Vector & u)
{
   double xi(x(0));
   double yi(x(1));
   double zi(0.0);
   if (x.Size() == 3)
   {
      zi = x(2);
   }

   u(0) = - exp(xi)*sin(yi)*cos(zi);
   u(1) = - exp(xi)*cos(yi)*cos(zi);

   if (x.Size() == 3)
   {
      u(2) = exp(xi)*sin(yi)*sin(zi);
   }
}

// Change if needed
double pFun_ex(const Vector & x)
{
   double xi(x(0));
   double yi(x(1));
   double zi(0.0);

   if (x.Size() == 3)
   {
      zi = x(2);
   }

   return exp(xi)*sin(yi)*cos(zi);
}

void fFun(const Vector & x, Vector & f)
{
   f = 0.0;
}

double gFun(const Vector & x)
{
   if (x.Size() == 3)
   {
      return -pFun_ex(x);
   }
   else
   {
      return 0;
   }
}

double f_natural(const Vector & x)
{
   return (-pFun_ex(x));
}
<|endoftext|>


<commit_before>//
//  ControlWithChilds.hpp
//  MusicPlayer
//
//  Created by Albert Zeyer on 21.01.14.
//  Copyright (c) 2014 Albert Zeyer. All rights reserved.
//

#ifndef __MP_guiQt_ControlWithChilds_hpp__
#define __MP_guiQt_ControlWithChilds_hpp__

#include "GuiObject.hpp"
#include <functional>

typedef std::function<void(GuiObject*, bool& stop)> ChildIterCallback;

/*
@protocol ControlWithChilds
-(void) childIter:(ChildIterCallback) block;

@end
*/

#endif
<commit_msg>rm. not needed<commit_after><|endoftext|>


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

#include "chrome/browser/shell_dialogs.h"

#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/json/json_reader.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/dom_ui/html_dialog_ui.h"
#include "chrome/browser/shell_dialogs.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/html_dialog_view.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
#include "views/window/non_client_view.h"
#include "views/window/window.h"

namespace {

static const wchar_t* kKeyNamePath = L"path";

};  // namespace

// Implementation of SelectFileDialog that shows an UI for choosing a file
// or folder using FileBrowseUI.
class SelectFileDialogImpl : public SelectFileDialog {
 public:
  explicit SelectFileDialogImpl(Listener* listener);

  // BaseShellDialog implementation.
  virtual bool IsRunning(gfx::NativeWindow parent_window) const;
  virtual void ListenerDestroyed();

  // SelectFileDialog implementation.
  // |params| is user data we pass back via the Listener interface.
  virtual void SelectFile(Type type,
                          const string16& title,
                          const FilePath& default_path,
                          const FileTypeInfo* file_types,
                          int file_type_index,
                          const FilePath::StringType& default_extension,
                          gfx::NativeWindow owning_window,
                          void* params);

 private:
  virtual ~SelectFileDialogImpl();

  class FileBrowseDelegate : public HtmlDialogUIDelegate {
   public:
    FileBrowseDelegate(SelectFileDialogImpl* owner,
                       Type type,
                       const std::wstring& title,
                       const FilePath& default_path,
                       const FileTypeInfo* file_types,
                       int file_type_index,
                       const FilePath::StringType& default_extension,
                       gfx::NativeWindow parent,
                       void* params);

    // Owner of this FileBrowseDelegate.
    scoped_refptr<SelectFileDialogImpl> owner_;

    // Parent window.
    gfx::NativeWindow parent_;

    // The type of dialog we are showing the user.
    Type type_;

    // The dialog title.
    std::wstring title_;

    // Default path of the file dialog.
    FilePath default_path_;

    // The file filters.
    FileTypeInfo file_types_;

    // The index of the default selected file filter.
    // Note: This starts from 1, not 0.
    int file_type_index_;

    // Default extension to be added to file if user does not type one.
    FilePath::StringType default_extension_;

    // Associated user data.
    void* params_;

   private:
    ~FileBrowseDelegate();

    // Overridden from HtmlDialogUI::Delegate:
    virtual bool IsDialogModal() const;
    virtual std::wstring GetDialogTitle() const;
    virtual GURL GetDialogContentURL() const;
    virtual void GetDOMMessageHandlers(
        std::vector<DOMMessageHandler*>* handlers) const;
    virtual void GetDialogSize(gfx::Size* size) const;
    virtual std::string GetDialogArgs() const;
    virtual void OnDialogClosed(const std::string& json_retval);

    DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegate);
  };

  class FileBrowseDelegateHandler : public DOMMessageHandler {
   public:
    explicit FileBrowseDelegateHandler(FileBrowseDelegate* delegate);

    // DOMMessageHandler implementation.
    virtual void RegisterMessages();

    // Callback for the "setDialogTitle" message.
    void HandleSetDialogTitle(const Value* value);

   private:
    FileBrowseDelegate* delegate_;

    DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegateHandler);
  };

  // Notification from FileBrowseDelegate when file browse UI is dismissed.
  void OnDialogClosed(FileBrowseDelegate* delegate, const std::string& json);

  // The set of all parent windows for which we are currently running dialogs.
  std::set<gfx::NativeWindow> parents_;

  // The set of all FileBrowseDelegate that we are currently running.
  std::set<FileBrowseDelegate*> delegates_;

  // The listener to be notified of selection completion.
  Listener* listener_;

  DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
};

// static
SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
  DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::IO));
  DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::FILE));
  return new SelectFileDialogImpl(listener);
}

SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
    : listener_(listener) {
}

SelectFileDialogImpl::~SelectFileDialogImpl() {
  // All dialogs should be dismissed by now.
  DCHECK(parents_.empty() && delegates_.empty());
}

bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
  return parent_window && parents_.find(parent_window) != parents_.end();
}

void SelectFileDialogImpl::ListenerDestroyed() {
  listener_ = NULL;
}

void SelectFileDialogImpl::SelectFile(
    Type type,
    const string16& title,
    const FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const FilePath::StringType& default_extension,
    gfx::NativeWindow owning_window,
    void* params) {
  std::wstring title_string;
  if (title.empty()) {
    int string_id;
    switch (type) {
      case SELECT_FOLDER:
        string_id = IDS_SELECT_FOLDER_DIALOG_TITLE;
        break;
      case SELECT_OPEN_FILE:
      case SELECT_OPEN_MULTI_FILE:
        string_id = IDS_OPEN_FILE_DIALOG_TITLE;
        break;
      case SELECT_SAVEAS_FILE:
        string_id = IDS_SAVE_AS_DIALOG_TITLE;
        break;
      default:
        NOTREACHED();
        return;
    }
    title_string = l10n_util::GetString(string_id);
  } else {
    title_string = UTF16ToWide(title);
  }

  if (owning_window)
    parents_.insert(owning_window);

  FileBrowseDelegate* file_browse_delegate = new FileBrowseDelegate(this,
      type, title_string, default_path, file_types, file_type_index,
      default_extension, owning_window, params);
  delegates_.insert(file_browse_delegate);

  Browser* browser = BrowserList::GetLastActive();
  DCHECK(browser);
  browser->BrowserShowHtmlDialog(file_browse_delegate, owning_window);
}

void SelectFileDialogImpl::OnDialogClosed(FileBrowseDelegate* delegate,
                                          const std::string& json) {
  // Nothing to do if listener_ is gone.

  if (!listener_)
    return;

  bool notification_fired = false;

  if (!json.empty()) {
    scoped_ptr<Value> value(base::JSONReader::Read(json, false));
    if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) {
      // Bad json value returned.
      NOTREACHED();
    } else {
      const DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
      if (delegate->type_ == SELECT_OPEN_FILE ||
          delegate->type_ == SELECT_SAVEAS_FILE ||
          delegate->type_ == SELECT_FOLDER) {
        std::wstring path_string;
        if (dict->HasKey(kKeyNamePath) &&
            dict->GetString(kKeyNamePath, &path_string)) {
          FilePath path = FilePath::FromWStringHack(path_string);

          listener_->FileSelected(path, 0, delegate->params_);
          notification_fired = true;
        }
      } else if (delegate->type_ == SELECT_OPEN_MULTI_FILE) {
        ListValue* paths_value = NULL;
        if (dict->HasKey(kKeyNamePath) &&
            dict->GetList(kKeyNamePath, &paths_value) &&
            paths_value) {
          std::vector<FilePath> paths;
          paths.reserve(paths_value->GetSize());
          for (size_t i = 0; i < paths_value->GetSize(); ++i) {
            std::wstring path_string;
            if (paths_value->GetString(i, &path_string) &&
                !path_string.empty()) {
              paths.push_back(FilePath::FromWStringHack(path_string));
            }
          }

          listener_->MultiFilesSelected(paths, delegate->params_);
          notification_fired = true;
        }
      } else {
        NOTREACHED();
      }
    }
  }

  // Always notify listener when dialog is dismissed.
  if (!notification_fired)
    listener_->FileSelectionCanceled(delegate->params_);

  parents_.erase(delegate->parent_);
  delegates_.erase(delegate);
}

SelectFileDialogImpl::FileBrowseDelegate::FileBrowseDelegate(
    SelectFileDialogImpl* owner,
    Type type,
    const std::wstring& title,
    const FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const FilePath::StringType& default_extension,
    gfx::NativeWindow parent,
    void* params)
  : owner_(owner),
    parent_(parent),
    type_(type),
    title_(title),
    default_path_(default_path),
    file_type_index_(file_type_index),
    default_extension_(default_extension),
    params_(params) {
  if (file_types)
    file_types_ = *file_types;
  else
    file_types_.include_all_files = true;
}

SelectFileDialogImpl::FileBrowseDelegate::~FileBrowseDelegate() {
}

bool SelectFileDialogImpl::FileBrowseDelegate::IsDialogModal() const {
  return true;
}

std::wstring SelectFileDialogImpl::FileBrowseDelegate::GetDialogTitle() const {
  return title_;
}

GURL SelectFileDialogImpl::FileBrowseDelegate::GetDialogContentURL() const {
  std::string url_string(chrome::kChromeUIFileBrowseURL);

  return GURL(url_string);
}

void SelectFileDialogImpl::FileBrowseDelegate::GetDOMMessageHandlers(
    std::vector<DOMMessageHandler*>* handlers) const {
  handlers->push_back(new FileBrowseDelegateHandler(
      const_cast<FileBrowseDelegate*>(this)));
  return;
}

void SelectFileDialogImpl::FileBrowseDelegate::GetDialogSize(
    gfx::Size* size) const {
  size->SetSize(320, 240);
}

std::string SelectFileDialogImpl::FileBrowseDelegate::GetDialogArgs() const {
  // SelectFile inputs as json.
  //  {
  //    "type"            : "open",   // (or "open_multiple", "save", "folder"
  //    "all_files"       : true,
  //    "file_types"      : {
  //                          "exts" : [ ["htm", "html"], ["txt"] ],
  //                          "desc" : [ "HTML files", "Text files" ],
  //                        },
  //    "file_type_index" : 1,    // 1-based file type index.
  //  }
  //  See browser/shell_dialogs.h for more details.

  std::string type_string;
  switch (type_) {
    case SELECT_FOLDER:
      type_string = "folder";
      break;
    case SELECT_OPEN_FILE:
      type_string = "open";
      break;
    case SELECT_OPEN_MULTI_FILE:
      type_string = "open_multiple";
      break;
    case SELECT_SAVEAS_FILE:
      type_string = "save";
      break;
    default:
      NOTREACHED();
      return std::string();
  }

  std::string exts_list;
  std::string desc_list;
  for (size_t i = 0; i < file_types_.extensions.size(); ++i) {
    DCHECK(!file_types_.extensions[i].empty());

    std::string exts;
    for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) {
      if (!exts.empty())
        exts.append(",");
      StringAppendF(&exts, "\"%s\"", file_types_.extensions[i][j].c_str());
    }

    if (!exts_list.empty())
      exts_list.append(",");
    StringAppendF(&exts_list, "[%s]", exts.c_str());

    std::string desc;
    if (i < file_types_.extension_description_overrides.size()) {
      desc = UTF16ToUTF8(file_types_.extension_description_overrides[i]);
    } else {
#if defined(OS_WIN)
      desc = WideToUTF8(file_types_.extensions[i][0]);
#elif defined(OS_POSIX)
      desc = file_types_.extensions[i][0];
#else
      NOTIMPLEMENTED();
#endif
    }

    if (!desc_list.empty())
      desc_list.append(",");
    StringAppendF(&desc_list, "\"%s\"", desc.c_str());
  }

  std::string filename = default_path_.BaseName().value();

  return StringPrintf("{"
        "\"type\":\"%s\","
        "\"all_files\":%s,"
        "\"current_file\":\"%s\","
        "\"file_types\":{\"exts\":[%s],\"desc\":[%s]},"
        "\"file_type_index\":%d"
      "}",
      type_string.c_str(),
      file_types_.include_all_files ? "true" : "false",
      filename.c_str(),
      exts_list.c_str(),
      desc_list.c_str(),
      file_type_index_);
}

void SelectFileDialogImpl::FileBrowseDelegate::OnDialogClosed(
    const std::string& json_retval) {
  owner_->OnDialogClosed(this, json_retval);
  delete this;
  return;
}

SelectFileDialogImpl::FileBrowseDelegateHandler::FileBrowseDelegateHandler(
    FileBrowseDelegate* delegate)
    : delegate_(delegate) {
}

void SelectFileDialogImpl::FileBrowseDelegateHandler::RegisterMessages() {
  dom_ui_->RegisterMessageCallback("setDialogTitle",
      NewCallback(this, &FileBrowseDelegateHandler::HandleSetDialogTitle));
}

void SelectFileDialogImpl::FileBrowseDelegateHandler::HandleSetDialogTitle(
    const Value* value) {
  std::wstring new_title = ExtractStringValue(value);
  if (new_title != delegate_->title_) {
    delegate_->title_ = new_title;

    // Notify the containing view about the title change.
    // The current HtmlDialogUIDelegate and HtmlDialogView does not support
    // dynamic title change. We hijacked the mechanism between HTMLDialogUI
    // and HtmlDialogView to get the HtmlDialgoView and forced it to update
    // its title.
    // TODO(xiyuan): Change this when the infrastructure is improved.
    HtmlDialogUIDelegate** delegate = HtmlDialogUI::GetPropertyAccessor().
        GetProperty(dom_ui_->tab_contents()->property_bag());
    HtmlDialogView* containing_view = static_cast<HtmlDialogView*>(*delegate);
    DCHECK(containing_view);

    containing_view->GetWindow()->UpdateWindowTitle();
    containing_view->GetWindow()->GetNonClientView()->SchedulePaint();
  }
}
<commit_msg>Fix for assert in SavePackage::ContinueSave(): save package type index outside of allowed bounds. <commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/shell_dialogs.h"

#include "app/l10n_util.h"
#include "base/callback.h"
#include "base/file_path.h"
#include "base/json/json_reader.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/dom_ui/html_dialog_ui.h"
#include "chrome/browser/shell_dialogs.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/views/html_dialog_view.h"
#include "chrome/common/url_constants.h"
#include "grit/generated_resources.h"
#include "views/window/non_client_view.h"
#include "views/window/window.h"

namespace {

static const wchar_t* kKeyNamePath = L"path";
static const int kSaveCompletePageIndex = 2;

};  // namespace

// Implementation of SelectFileDialog that shows an UI for choosing a file
// or folder using FileBrowseUI.
class SelectFileDialogImpl : public SelectFileDialog {
 public:
  explicit SelectFileDialogImpl(Listener* listener);

  // BaseShellDialog implementation.
  virtual bool IsRunning(gfx::NativeWindow parent_window) const;
  virtual void ListenerDestroyed();

  // SelectFileDialog implementation.
  // |params| is user data we pass back via the Listener interface.
  virtual void SelectFile(Type type,
                          const string16& title,
                          const FilePath& default_path,
                          const FileTypeInfo* file_types,
                          int file_type_index,
                          const FilePath::StringType& default_extension,
                          gfx::NativeWindow owning_window,
                          void* params);

 private:
  virtual ~SelectFileDialogImpl();

  class FileBrowseDelegate : public HtmlDialogUIDelegate {
   public:
    FileBrowseDelegate(SelectFileDialogImpl* owner,
                       Type type,
                       const std::wstring& title,
                       const FilePath& default_path,
                       const FileTypeInfo* file_types,
                       int file_type_index,
                       const FilePath::StringType& default_extension,
                       gfx::NativeWindow parent,
                       void* params);

    // Owner of this FileBrowseDelegate.
    scoped_refptr<SelectFileDialogImpl> owner_;

    // Parent window.
    gfx::NativeWindow parent_;

    // The type of dialog we are showing the user.
    Type type_;

    // The dialog title.
    std::wstring title_;

    // Default path of the file dialog.
    FilePath default_path_;

    // The file filters.
    FileTypeInfo file_types_;

    // The index of the default selected file filter.
    // Note: This starts from 1, not 0.
    int file_type_index_;

    // Default extension to be added to file if user does not type one.
    FilePath::StringType default_extension_;

    // Associated user data.
    void* params_;

   private:
    ~FileBrowseDelegate();

    // Overridden from HtmlDialogUI::Delegate:
    virtual bool IsDialogModal() const;
    virtual std::wstring GetDialogTitle() const;
    virtual GURL GetDialogContentURL() const;
    virtual void GetDOMMessageHandlers(
        std::vector<DOMMessageHandler*>* handlers) const;
    virtual void GetDialogSize(gfx::Size* size) const;
    virtual std::string GetDialogArgs() const;
    virtual void OnDialogClosed(const std::string& json_retval);

    DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegate);
  };

  class FileBrowseDelegateHandler : public DOMMessageHandler {
   public:
    explicit FileBrowseDelegateHandler(FileBrowseDelegate* delegate);

    // DOMMessageHandler implementation.
    virtual void RegisterMessages();

    // Callback for the "setDialogTitle" message.
    void HandleSetDialogTitle(const Value* value);

   private:
    FileBrowseDelegate* delegate_;

    DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegateHandler);
  };

  // Notification from FileBrowseDelegate when file browse UI is dismissed.
  void OnDialogClosed(FileBrowseDelegate* delegate, const std::string& json);

  // The set of all parent windows for which we are currently running dialogs.
  std::set<gfx::NativeWindow> parents_;

  // The set of all FileBrowseDelegate that we are currently running.
  std::set<FileBrowseDelegate*> delegates_;

  // The listener to be notified of selection completion.
  Listener* listener_;

  DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
};

// static
SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
  DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::IO));
  DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::FILE));
  return new SelectFileDialogImpl(listener);
}

SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
    : listener_(listener) {
}

SelectFileDialogImpl::~SelectFileDialogImpl() {
  // All dialogs should be dismissed by now.
  DCHECK(parents_.empty() && delegates_.empty());
}

bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
  return parent_window && parents_.find(parent_window) != parents_.end();
}

void SelectFileDialogImpl::ListenerDestroyed() {
  listener_ = NULL;
}

void SelectFileDialogImpl::SelectFile(
    Type type,
    const string16& title,
    const FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const FilePath::StringType& default_extension,
    gfx::NativeWindow owning_window,
    void* params) {
  std::wstring title_string;
  if (title.empty()) {
    int string_id;
    switch (type) {
      case SELECT_FOLDER:
        string_id = IDS_SELECT_FOLDER_DIALOG_TITLE;
        break;
      case SELECT_OPEN_FILE:
      case SELECT_OPEN_MULTI_FILE:
        string_id = IDS_OPEN_FILE_DIALOG_TITLE;
        break;
      case SELECT_SAVEAS_FILE:
        string_id = IDS_SAVE_AS_DIALOG_TITLE;
        break;
      default:
        NOTREACHED();
        return;
    }
    title_string = l10n_util::GetString(string_id);
  } else {
    title_string = UTF16ToWide(title);
  }

  if (owning_window)
    parents_.insert(owning_window);

  FileBrowseDelegate* file_browse_delegate = new FileBrowseDelegate(this,
      type, title_string, default_path, file_types, file_type_index,
      default_extension, owning_window, params);
  delegates_.insert(file_browse_delegate);

  Browser* browser = BrowserList::GetLastActive();
  DCHECK(browser);
  browser->BrowserShowHtmlDialog(file_browse_delegate, owning_window);
}

void SelectFileDialogImpl::OnDialogClosed(FileBrowseDelegate* delegate,
                                          const std::string& json) {
  // Nothing to do if listener_ is gone.

  if (!listener_)
    return;

  bool notification_fired = false;

  if (!json.empty()) {
    scoped_ptr<Value> value(base::JSONReader::Read(json, false));
    if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) {
      // Bad json value returned.
      NOTREACHED();
    } else {
      const DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
      if (delegate->type_ == SELECT_OPEN_FILE ||
          delegate->type_ == SELECT_SAVEAS_FILE ||
          delegate->type_ == SELECT_FOLDER) {
        std::wstring path_string;
        if (dict->HasKey(kKeyNamePath) &&
            dict->GetString(kKeyNamePath, &path_string)) {
          FilePath path = FilePath::FromWStringHack(path_string);

          listener_->FileSelected(path, kSaveCompletePageIndex,
                                  delegate->params_);
          notification_fired = true;
        }
      } else if (delegate->type_ == SELECT_OPEN_MULTI_FILE) {
        ListValue* paths_value = NULL;
        if (dict->HasKey(kKeyNamePath) &&
            dict->GetList(kKeyNamePath, &paths_value) &&
            paths_value) {
          std::vector<FilePath> paths;
          paths.reserve(paths_value->GetSize());
          for (size_t i = 0; i < paths_value->GetSize(); ++i) {
            std::wstring path_string;
            if (paths_value->GetString(i, &path_string) &&
                !path_string.empty()) {
              paths.push_back(FilePath::FromWStringHack(path_string));
            }
          }

          listener_->MultiFilesSelected(paths, delegate->params_);
          notification_fired = true;
        }
      } else {
        NOTREACHED();
      }
    }
  }

  // Always notify listener when dialog is dismissed.
  if (!notification_fired)
    listener_->FileSelectionCanceled(delegate->params_);

  parents_.erase(delegate->parent_);
  delegates_.erase(delegate);
}

SelectFileDialogImpl::FileBrowseDelegate::FileBrowseDelegate(
    SelectFileDialogImpl* owner,
    Type type,
    const std::wstring& title,
    const FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const FilePath::StringType& default_extension,
    gfx::NativeWindow parent,
    void* params)
  : owner_(owner),
    parent_(parent),
    type_(type),
    title_(title),
    default_path_(default_path),
    file_type_index_(file_type_index),
    default_extension_(default_extension),
    params_(params) {
  if (file_types)
    file_types_ = *file_types;
  else
    file_types_.include_all_files = true;
}

SelectFileDialogImpl::FileBrowseDelegate::~FileBrowseDelegate() {
}

bool SelectFileDialogImpl::FileBrowseDelegate::IsDialogModal() const {
  return true;
}

std::wstring SelectFileDialogImpl::FileBrowseDelegate::GetDialogTitle() const {
  return title_;
}

GURL SelectFileDialogImpl::FileBrowseDelegate::GetDialogContentURL() const {
  std::string url_string(chrome::kChromeUIFileBrowseURL);

  return GURL(url_string);
}

void SelectFileDialogImpl::FileBrowseDelegate::GetDOMMessageHandlers(
    std::vector<DOMMessageHandler*>* handlers) const {
  handlers->push_back(new FileBrowseDelegateHandler(
      const_cast<FileBrowseDelegate*>(this)));
  return;
}

void SelectFileDialogImpl::FileBrowseDelegate::GetDialogSize(
    gfx::Size* size) const {
  size->SetSize(320, 240);
}

std::string SelectFileDialogImpl::FileBrowseDelegate::GetDialogArgs() const {
  // SelectFile inputs as json.
  //  {
  //    "type"            : "open",   // (or "open_multiple", "save", "folder"
  //    "all_files"       : true,
  //    "file_types"      : {
  //                          "exts" : [ ["htm", "html"], ["txt"] ],
  //                          "desc" : [ "HTML files", "Text files" ],
  //                        },
  //    "file_type_index" : 1,    // 1-based file type index.
  //  }
  //  See browser/shell_dialogs.h for more details.

  std::string type_string;
  switch (type_) {
    case SELECT_FOLDER:
      type_string = "folder";
      break;
    case SELECT_OPEN_FILE:
      type_string = "open";
      break;
    case SELECT_OPEN_MULTI_FILE:
      type_string = "open_multiple";
      break;
    case SELECT_SAVEAS_FILE:
      type_string = "save";
      break;
    default:
      NOTREACHED();
      return std::string();
  }

  std::string exts_list;
  std::string desc_list;
  for (size_t i = 0; i < file_types_.extensions.size(); ++i) {
    DCHECK(!file_types_.extensions[i].empty());

    std::string exts;
    for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) {
      if (!exts.empty())
        exts.append(",");
      StringAppendF(&exts, "\"%s\"", file_types_.extensions[i][j].c_str());
    }

    if (!exts_list.empty())
      exts_list.append(",");
    StringAppendF(&exts_list, "[%s]", exts.c_str());

    std::string desc;
    if (i < file_types_.extension_description_overrides.size()) {
      desc = UTF16ToUTF8(file_types_.extension_description_overrides[i]);
    } else {
#if defined(OS_WIN)
      desc = WideToUTF8(file_types_.extensions[i][0]);
#elif defined(OS_POSIX)
      desc = file_types_.extensions[i][0];
#else
      NOTIMPLEMENTED();
#endif
    }

    if (!desc_list.empty())
      desc_list.append(",");
    StringAppendF(&desc_list, "\"%s\"", desc.c_str());
  }

  std::string filename = default_path_.BaseName().value();

  return StringPrintf("{"
        "\"type\":\"%s\","
        "\"all_files\":%s,"
        "\"current_file\":\"%s\","
        "\"file_types\":{\"exts\":[%s],\"desc\":[%s]},"
        "\"file_type_index\":%d"
      "}",
      type_string.c_str(),
      file_types_.include_all_files ? "true" : "false",
      filename.c_str(),
      exts_list.c_str(),
      desc_list.c_str(),
      file_type_index_);
}

void SelectFileDialogImpl::FileBrowseDelegate::OnDialogClosed(
    const std::string& json_retval) {
  owner_->OnDialogClosed(this, json_retval);
  delete this;
  return;
}

SelectFileDialogImpl::FileBrowseDelegateHandler::FileBrowseDelegateHandler(
    FileBrowseDelegate* delegate)
    : delegate_(delegate) {
}

void SelectFileDialogImpl::FileBrowseDelegateHandler::RegisterMessages() {
  dom_ui_->RegisterMessageCallback("setDialogTitle",
      NewCallback(this, &FileBrowseDelegateHandler::HandleSetDialogTitle));
}

void SelectFileDialogImpl::FileBrowseDelegateHandler::HandleSetDialogTitle(
    const Value* value) {
  std::wstring new_title = ExtractStringValue(value);
  if (new_title != delegate_->title_) {
    delegate_->title_ = new_title;

    // Notify the containing view about the title change.
    // The current HtmlDialogUIDelegate and HtmlDialogView does not support
    // dynamic title change. We hijacked the mechanism between HTMLDialogUI
    // and HtmlDialogView to get the HtmlDialgoView and forced it to update
    // its title.
    // TODO(xiyuan): Change this when the infrastructure is improved.
    HtmlDialogUIDelegate** delegate = HtmlDialogUI::GetPropertyAccessor().
        GetProperty(dom_ui_->tab_contents()->property_bag());
    HtmlDialogView* containing_view = static_cast<HtmlDialogView*>(*delegate);
    DCHECK(containing_view);

    containing_view->GetWindow()->UpdateWindowTitle();
    containing_view->GetWindow()->GetNonClientView()->SchedulePaint();
  }
}
<|endoftext|>