<commit_before>#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64

#include "util/file.hh"

#include "util/exception.hh"

#include <cstdlib>
#include <cstdio>
#include <iostream>

#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <io.h>
#include <algorithm>
#include <limits.h>
#else
#include <unistd.h>
#endif

namespace util {

scoped_fd::~scoped_fd() {
  if (fd_ != -1 && close(fd_)) {
    std::cerr << "Could not close file " << fd_ << std::endl;
    std::abort();
  }
}

scoped_FILE::~scoped_FILE() {
  if (file_ && std::fclose(file_)) {
    std::cerr << "Could not close file " << std::endl;
    std::abort();
  }
}

int OpenReadOrThrow(const char *name) {
  int ret;
#if defined(_WIN32) || defined(_WIN64)
  UTIL_THROW_IF(-1 == (ret = _open(name, _O_BINARY | _O_RDONLY)), ErrnoException, "while opening " << name);
#else
  UTIL_THROW_IF(-1 == (ret = open(name, O_RDONLY)), ErrnoException, "while opening " << name);
#endif
  return ret;
}

int CreateOrThrow(const char *name) {
  int ret;
#if defined(_WIN32) || defined(_WIN64)
  UTIL_THROW_IF(-1 == (ret = _open(name, _O_CREAT | _O_TRUNC | _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE)), ErrnoException, "while creating " << name);
#else
  UTIL_THROW_IF(-1 == (ret = open(name, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)), ErrnoException, "while creating " << name);
#endif
  return ret;
}

uint64_t SizeFile(int fd) {
#if defined(_WIN32) || defined(_WIN64)
  __int64 ret = _filelengthi64(fd);
  return (ret == -1) ? kBadSize : ret;
#else
  struct stat sb;
  if (fstat(fd, &sb) == -1 || (!sb.st_size && !S_ISREG(sb.st_mode))) return kBadSize;
  return sb.st_size;
#endif
}

void ResizeOrThrow(int fd, uint64_t to) {
#if defined(_WIN32) || defined(_WIN64)
  UTIL_THROW_IF(_chsize_s(fd, to), ErrnoException, "Resizing to " << to << " bytes failed");
#else
  UTIL_THROW_IF(ftruncate(fd, to), ErrnoException, "Resizing to " << to << " bytes failed");
#endif
}

std::size_t PartialRead(int fd, void *to, std::size_t amount) {
#if defined(_WIN32) || defined(_WIN64)
  amount = min(static_cast<std::size_t>(INT_MAX), amount);
  int ret = _read(fd, to, amount);
#else
  ssize_t ret = read(fd, to, amount);
#endif
  UTIL_THROW_IF(ret < 0, ErrnoException, "Reading " << amount << " from fd " << fd << " failed.");
  return static_cast<std::size_t>(ret);
}

void ReadOrThrow(int fd, void *to_void, std::size_t amount) {
  uint8_t *to = static_cast<uint8_t*>(to_void);
  while (amount) {
    std::size_t ret = PartialRead(fd, to, amount);
    UTIL_THROW_IF(ret == 0, EndOfFileException, " in fd " << fd << " but there should be " << amount << " more bytes to read.");
    amount -= ret;
    to += ret;
  }
}

std::size_t ReadOrEOF(int fd, void *to_void, std::size_t amount) {
  uint8_t *to = static_cast<uint8_t*>(to_void);
  std::size_t remaining = amount;
  while (remaining) {
    std::size_t ret = PartialRead(fd, to, remaining);
    if (!ret) return amount - remaining;
    remaining -= ret;
    to += ret;
  }
  return amount;
}

void WriteOrThrow(int fd, const void *data_void, std::size_t size) {
  const uint8_t *data = static_cast<const uint8_t*>(data_void);
  while (size) {
#if defined(_WIN32) || defined(_WIN64)
    int ret = write(fd, data, min(static_cast<std::size_t>(INT_MAX), size));
#else
    ssize_t ret = write(fd, data, size);
#endif
    if (ret < 1) UTIL_THROW(util::ErrnoException, "Write failed");
    data += ret;
    size -= ret;
  }
}

void WriteOrThrow(FILE *to, const void *data, std::size_t size) {
  assert(size);
  UTIL_THROW_IF(1 != std::fwrite(data, size, 1, to), util::ErrnoException, "Short write; requested size " << size);
}

void FSyncOrThrow(int fd) {
// Apparently windows doesn't have fsync?
#if !defined(_WIN32) && !defined(_WIN64)
  UTIL_THROW_IF(-1 == fsync(fd), ErrnoException, "Sync of " << fd << " failed.");
#endif
}

namespace {
// Can't we all just get along?
void InternalSeek(int fd, int64_t off, int whence) {
  UTIL_THROW_IF(
#if defined(_WIN32) || defined(_WIN64)
    (__int64)-1 == _lseeki64(fd, off, whence),
#else
    (off_t)-1 == lseek(fd, off, whence),
#endif
    ErrnoException, "Seek failed");
}
} // namespace

void SeekOrThrow(int fd, uint64_t off) {
  InternalSeek(fd, off, SEEK_SET);
}

void AdvanceOrThrow(int fd, int64_t off) {
  InternalSeek(fd, off, SEEK_CUR);
}

void SeekEnd(int fd) {
  InternalSeek(fd, 0, SEEK_END);
}

std::FILE *FDOpenOrThrow(scoped_fd &file) {
  std::FILE *ret = fdopen(file.get(), "r+b");
  if (!ret) UTIL_THROW(util::ErrnoException, "Could not fdopen descriptor " << file.get());
  file.release();
  return ret;
}

std::FILE *FDOpenReadOrThrow(scoped_fd &file) {
  std::FILE *ret = fdopen(file.get(), "rb");
  if (!ret) UTIL_THROW(util::ErrnoException, "Could not fdopen descriptor " << file.get());
  file.release();
  return ret;
}

TempMaker::TempMaker(const std::string &prefix) : base_(prefix) {
  base_ += "XXXXXX";
}

// Sigh.  Windows temporary file creation is full of race conditions.
#if defined(_WIN32) || defined(_WIN64)
/* mkstemp extracted from libc/sysdeps/posix/tempname.c.  Copyright
   (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.

   The GNU C 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 has been modified from the original version to rename the function and
 * set the Windows temporary flag. */

static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

/* Generate a temporary file name based on TMPL.  TMPL must match the
   rules for mk[s]temp (i.e. end in "XXXXXX").  The name constructed
   does not exist at the time of the call to mkstemp.  TMPL is
   overwritten with the result.  */
int
mkstemp_and_unlink(char *tmpl)
{
  int len;
  char *XXXXXX;
  static unsigned long long value;
  unsigned long long random_time_bits;
  unsigned int count;
  int fd = -1;
  int save_errno = errno;

  /* A lower bound on the number of temporary files to attempt to
     generate.  The maximum total number of temporary file names that
     can exist for a given template is 62**6.  It should never be
     necessary to try all these combinations.  Instead if a reasonable
     number of names is tried (we define reasonable as 62**3) fail to
     give the system administrator the chance to remove the problems.  */
#define ATTEMPTS_MIN (62 * 62 * 62)

  /* The number of times to attempt to generate a temporary file.  To
     conform to POSIX, this must be no smaller than TMP_MAX.  */
#if ATTEMPTS_MIN < TMP_MAX
  unsigned int attempts = TMP_MAX;
#else
  unsigned int attempts = ATTEMPTS_MIN;
#endif

  len = strlen (tmpl);
  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
    {
      errno = EINVAL;
      return -1;
    }

/* This is where the Xs start.  */
  XXXXXX = &tmpl[len - 6];

  /* Get some more or less random data.  */
  {
    SYSTEMTIME      stNow;
    FILETIME ftNow;

    // get system time
    GetSystemTime(&stNow);
    stNow.wMilliseconds = 500;
    if (!SystemTimeToFileTime(&stNow, &ftNow))
    {
        errno = -1;
        return -1;
    }

    random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
                        | (unsigned long long)ftNow.dwLowDateTime);
  }
  value += random_time_bits ^ (unsigned long long)GetCurrentThreadId ();

  for (count = 0; count < attempts; value += 7777, ++count)
  {
    unsigned long long v = value;

    /* Fill in the random bits.  */
    XXXXXX[0] = letters[v % 62];
    v /= 62;
    XXXXXX[1] = letters[v % 62];
    v /= 62;
    XXXXXX[2] = letters[v % 62];
    v /= 62;
    XXXXXX[3] = letters[v % 62];
    v /= 62;
    XXXXXX[4] = letters[v % 62];
    v /= 62;
    XXXXXX[5] = letters[v % 62];

    /* Modified for windows and to unlink */
    //      fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
    int flags = _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY;
    flags |= _O_TEMPORARY;
    fd = _open (tmpl, flags, _S_IREAD | _S_IWRITE);
    if (fd >= 0)
    {
      errno = save_errno;
      return fd;
    }
    else if (errno != EEXIST)
      return -1;
  }

  /* We got out of the loop because we ran out of combinations to try.  */
  errno = EEXIST;
  return -1;
}
#else
int
mkstemp_and_unlink(char *tmpl) {
  int ret = mkstemp(tmpl);
  if (ret != -1) {
    UTIL_THROW_IF(unlink(tmpl), util::ErrnoException, "Failed to delete " << tmpl);
  }
  return ret;
}
#endif

int TempMaker::Make() const {
  std::string name(base_);
  name.push_back(0);
  int ret;
  UTIL_THROW_IF(-1 == (ret = mkstemp_and_unlink(&name[0])), util::ErrnoException, "Failed to make a temporary based on " << base_);
  return ret;
}

std::FILE *TempMaker::MakeFile() const {
  util::scoped_fd file(Make());
  return FDOpenOrThrow(file);
}

} // namespace util
<commit_msg>Stupid android 64-bit file offsets, static assert sizeof(off_t) == 8<commit_after>#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64

#include "util/file.hh"

#include "util/exception.hh"

#include <cstdlib>
#include <cstdio>
#include <iostream>

#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>

#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <io.h>
#include <algorithm>
#include <limits.h>
#else
#include <unistd.h>
#endif

namespace util {

scoped_fd::~scoped_fd() {
  if (fd_ != -1 && close(fd_)) {
    std::cerr << "Could not close file " << fd_ << std::endl;
    std::abort();
  }
}

scoped_FILE::~scoped_FILE() {
  if (file_ && std::fclose(file_)) {
    std::cerr << "Could not close file " << std::endl;
    std::abort();
  }
}

int OpenReadOrThrow(const char *name) {
  int ret;
#if defined(_WIN32) || defined(_WIN64)
  UTIL_THROW_IF(-1 == (ret = _open(name, _O_BINARY | _O_RDONLY)), ErrnoException, "while opening " << name);
#else
  UTIL_THROW_IF(-1 == (ret = open(name, O_RDONLY)), ErrnoException, "while opening " << name);
#endif
  return ret;
}

int CreateOrThrow(const char *name) {
  int ret;
#if defined(_WIN32) || defined(_WIN64)
  UTIL_THROW_IF(-1 == (ret = _open(name, _O_CREAT | _O_TRUNC | _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE)), ErrnoException, "while creating " << name);
#else
  UTIL_THROW_IF(-1 == (ret = open(name, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)), ErrnoException, "while creating " << name);
#endif
  return ret;
}

uint64_t SizeFile(int fd) {
#if defined(_WIN32) || defined(_WIN64)
  __int64 ret = _filelengthi64(fd);
  return (ret == -1) ? kBadSize : ret;
#else // Not windows.

#ifdef OS_ANDROID
  struct stat64 sb;
  int ret = fstat64(fd, &sb);
#else
  struct stat sb;
  int ret = fstat(fd, &sb);
#endif
  if (ret == -1 || (!sb.st_size && !S_ISREG(sb.st_mode))) return kBadSize;
  return sb.st_size;
#endif
}

void ResizeOrThrow(int fd, uint64_t to) {
#if defined(_WIN32) || defined(_WIN64)
  UTIL_THROW_IF(_chsize_s(fd, to), ErrnoException, "Resizing to " << to << " bytes failed");
#else
  UTIL_THROW_IF(ftruncate(fd, to), ErrnoException, "Resizing to " << to << " bytes failed");
#endif
}

std::size_t PartialRead(int fd, void *to, std::size_t amount) {
#if defined(_WIN32) || defined(_WIN64)
  amount = min(static_cast<std::size_t>(INT_MAX), amount);
  int ret = _read(fd, to, amount);
#else
  ssize_t ret = read(fd, to, amount);
#endif
  UTIL_THROW_IF(ret < 0, ErrnoException, "Reading " << amount << " from fd " << fd << " failed.");
  return static_cast<std::size_t>(ret);
}

void ReadOrThrow(int fd, void *to_void, std::size_t amount) {
  uint8_t *to = static_cast<uint8_t*>(to_void);
  while (amount) {
    std::size_t ret = PartialRead(fd, to, amount);
    UTIL_THROW_IF(ret == 0, EndOfFileException, " in fd " << fd << " but there should be " << amount << " more bytes to read.");
    amount -= ret;
    to += ret;
  }
}

std::size_t ReadOrEOF(int fd, void *to_void, std::size_t amount) {
  uint8_t *to = static_cast<uint8_t*>(to_void);
  std::size_t remaining = amount;
  while (remaining) {
    std::size_t ret = PartialRead(fd, to, remaining);
    if (!ret) return amount - remaining;
    remaining -= ret;
    to += ret;
  }
  return amount;
}

void WriteOrThrow(int fd, const void *data_void, std::size_t size) {
  const uint8_t *data = static_cast<const uint8_t*>(data_void);
  while (size) {
#if defined(_WIN32) || defined(_WIN64)
    int ret = write(fd, data, min(static_cast<std::size_t>(INT_MAX), size));
#else
    ssize_t ret = write(fd, data, size);
#endif
    if (ret < 1) UTIL_THROW(util::ErrnoException, "Write failed");
    data += ret;
    size -= ret;
  }
}

void WriteOrThrow(FILE *to, const void *data, std::size_t size) {
  assert(size);
  UTIL_THROW_IF(1 != std::fwrite(data, size, 1, to), util::ErrnoException, "Short write; requested size " << size);
}

void FSyncOrThrow(int fd) {
// Apparently windows doesn't have fsync?
#if !defined(_WIN32) && !defined(_WIN64)
  UTIL_THROW_IF(-1 == fsync(fd), ErrnoException, "Sync of " << fd << " failed.");
#endif
}

namespace {

// Static assert for 64-bit off_t size.
#if !defined(_WIN32) && !defined(_WIN64) && !defined(OS_ANDROID)
template <unsigned> struct CheckOffT;
template <> struct CheckOffT<8> {
  struct True {};
};
// If there's a compiler error on the next line, then off_t isn't 64 bit.  And
// that makes me a sad panda.
typedef CheckOffT<sizeof(off_t)>::True IgnoredType;
#endif

// Can't we all just get along?
void InternalSeek(int fd, int64_t off, int whence) {
  UTIL_THROW_IF(
#if defined(_WIN32) || defined(_WIN64)
    (__int64)-1 == _lseeki64(fd, off, whence),
#elif defined(OS_ANDROID)
    (off64_t)-1 == lseek64(fd, off, whence),
#else
    (off_t)-1 == lseek(fd, off, whence),
#endif
    ErrnoException, "Seek failed");
}
} // namespace

void SeekOrThrow(int fd, uint64_t off) {
  InternalSeek(fd, off, SEEK_SET);
}

void AdvanceOrThrow(int fd, int64_t off) {
  InternalSeek(fd, off, SEEK_CUR);
}

void SeekEnd(int fd) {
  InternalSeek(fd, 0, SEEK_END);
}

std::FILE *FDOpenOrThrow(scoped_fd &file) {
  std::FILE *ret = fdopen(file.get(), "r+b");
  if (!ret) UTIL_THROW(util::ErrnoException, "Could not fdopen descriptor " << file.get());
  file.release();
  return ret;
}

std::FILE *FDOpenReadOrThrow(scoped_fd &file) {
  std::FILE *ret = fdopen(file.get(), "rb");
  if (!ret) UTIL_THROW(util::ErrnoException, "Could not fdopen descriptor " << file.get());
  file.release();
  return ret;
}

TempMaker::TempMaker(const std::string &prefix) : base_(prefix) {
  base_ += "XXXXXX";
}

// Sigh.  Windows temporary file creation is full of race conditions.
#if defined(_WIN32) || defined(_WIN64)
/* mkstemp extracted from libc/sysdeps/posix/tempname.c.  Copyright
   (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.

   The GNU C 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 has been modified from the original version to rename the function and
 * set the Windows temporary flag. */

static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

/* Generate a temporary file name based on TMPL.  TMPL must match the
   rules for mk[s]temp (i.e. end in "XXXXXX").  The name constructed
   does not exist at the time of the call to mkstemp.  TMPL is
   overwritten with the result.  */
int
mkstemp_and_unlink(char *tmpl)
{
  int len;
  char *XXXXXX;
  static unsigned long long value;
  unsigned long long random_time_bits;
  unsigned int count;
  int fd = -1;
  int save_errno = errno;

  /* A lower bound on the number of temporary files to attempt to
     generate.  The maximum total number of temporary file names that
     can exist for a given template is 62**6.  It should never be
     necessary to try all these combinations.  Instead if a reasonable
     number of names is tried (we define reasonable as 62**3) fail to
     give the system administrator the chance to remove the problems.  */
#define ATTEMPTS_MIN (62 * 62 * 62)

  /* The number of times to attempt to generate a temporary file.  To
     conform to POSIX, this must be no smaller than TMP_MAX.  */
#if ATTEMPTS_MIN < TMP_MAX
  unsigned int attempts = TMP_MAX;
#else
  unsigned int attempts = ATTEMPTS_MIN;
#endif

  len = strlen (tmpl);
  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
    {
      errno = EINVAL;
      return -1;
    }

/* This is where the Xs start.  */
  XXXXXX = &tmpl[len - 6];

  /* Get some more or less random data.  */
  {
    SYSTEMTIME      stNow;
    FILETIME ftNow;

    // get system time
    GetSystemTime(&stNow);
    stNow.wMilliseconds = 500;
    if (!SystemTimeToFileTime(&stNow, &ftNow))
    {
        errno = -1;
        return -1;
    }

    random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
                        | (unsigned long long)ftNow.dwLowDateTime);
  }
  value += random_time_bits ^ (unsigned long long)GetCurrentThreadId ();

  for (count = 0; count < attempts; value += 7777, ++count)
  {
    unsigned long long v = value;

    /* Fill in the random bits.  */
    XXXXXX[0] = letters[v % 62];
    v /= 62;
    XXXXXX[1] = letters[v % 62];
    v /= 62;
    XXXXXX[2] = letters[v % 62];
    v /= 62;
    XXXXXX[3] = letters[v % 62];
    v /= 62;
    XXXXXX[4] = letters[v % 62];
    v /= 62;
    XXXXXX[5] = letters[v % 62];

    /* Modified for windows and to unlink */
    //      fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
    int flags = _O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY;
    flags |= _O_TEMPORARY;
    fd = _open (tmpl, flags, _S_IREAD | _S_IWRITE);
    if (fd >= 0)
    {
      errno = save_errno;
      return fd;
    }
    else if (errno != EEXIST)
      return -1;
  }

  /* We got out of the loop because we ran out of combinations to try.  */
  errno = EEXIST;
  return -1;
}
#else
int
mkstemp_and_unlink(char *tmpl) {
  int ret = mkstemp(tmpl);
  if (ret != -1) {
    UTIL_THROW_IF(unlink(tmpl), util::ErrnoException, "Failed to delete " << tmpl);
  }
  return ret;
}
#endif

int TempMaker::Make() const {
  std::string name(base_);
  name.push_back(0);
  int ret;
  UTIL_THROW_IF(-1 == (ret = mkstemp_and_unlink(&name[0])), util::ErrnoException, "Failed to make a temporary based on " << base_);
  return ret;
}

std::FILE *TempMaker::MakeFile() const {
  util::scoped_fd file(Make());
  return FDOpenOrThrow(file);
}

} // namespace util
<|endoftext|>


<commit_before>#include "Snap.h"
#include "dlink.h"
#include "vehicle.h"
#include "dnode.h"
#include "od.h"
#include "factory.h"

#include <deque>
#include <iostream>

int main()
{
	std::cout << "BEGIN multiclass TEST!\n";

	MNM_Destination *d = new MNM_Destination(1);
	MNM_Origin *o = new MNM_Origin(1, 1, 5, 1);
	d -> m_Dest_ID = 11;

	MNM_Dlink *l = new MNM_Dlink_Ctm(0, 0.125, 0.611, 2, 500, 13.33, 5, 1);
	l -> print_info();

	MNM_DMOND *o_node = new MNM_DMOND(1, 5);
	o_node -> hook_up_origin(o);
	o_node -> evolve(4);

	MNM_DMDND *d_node = new MNM_DMDND(1, 5);
	d_node -> hook_up_destination(d);
	d_node -> evolve(4);

	MNM_Veh *v;
	for (int i = 0; i < 4; ++i) {
		v = new MNM_Veh(i, 0);
		v -> set_current_link(l);
		v -> set_destination(d);
		l -> m_incoming_array.push_back(v);
	}

	l -> clear_incoming_array();
	for (int i =0; i < 2; ++i) {
		l -> evolve(i);
		l -> print_info();
		for (int j = 0; j < 4; ++j) {
			v = new MNM_Veh(j, i);
			v -> set_current_link(l);
			v -> set_destination(d);
			l -> m_incoming_array.push_back(v);
		}
		l -> clear_incoming_array();
	}

	return 0;
}<commit_msg>modify test_multiclass<commit_after>#include "Snap.h"
#include "dlink.h"
#include "vehicle.h"
#include "dnode.h"
#include "od.h"
#include "factory.h"

#include <deque>
#include <iostream>

int main()
{
	std::cout << "BEGIN multiclass TEST!\n";

	std::cout << "Add a new destination\n";
	MNM_Destination *d = new MNM_Destination(1);
	std::cout << "Add a new origin\n";
	MNM_Origin *o = new MNM_Origin(1, 1, 5, 1);
	d -> m_Dest_ID = 11;

	std::cout << "Add a new link\n";
	MNM_Dlink *l = new MNM_Dlink_Ctm(0, 0.125, 0.611, 2, 500, 13.33, 5, 1);
	l -> print_info();

	std::cout << "Add a new origin node and hook up origin\n";
	MNM_DMOND *o_node = new MNM_DMOND(1, 5);
	o_node -> hook_up_origin(o);
	o_node -> evolve(4);

	std::cout << "Add a new destination node and hook up destination\n";
	MNM_DMDND *d_node = new MNM_DMDND(1, 5);
	d_node -> hook_up_destination(d);
	d_node -> evolve(4);

	std::cout << "Loop build link\n";
	MNM_Veh *v;
	for (int i = 0; i < 4; ++i) {
		v = new MNM_Veh(i, 0);
		v -> set_current_link(l);
		v -> set_destination(d);
		l -> m_incoming_array.push_back(v);
	}

	std::cout << "Test ctm evolve\n";
	l -> clear_incoming_array();
	for (int i =0; i < 2; ++i) {
		l -> evolve(i);
		l -> print_info();
		for (int j = 0; j < 4; ++j) {
			v = new MNM_Veh(j, i);
			v -> set_current_link(l);
			v -> set_destination(d);
			l -> m_incoming_array.push_back(v);
		}
		l -> clear_incoming_array();
	}
	std::cout << "End test\n";

	return 0;
}<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE utymap_testsuite
<commit_msg>core: fix refactoring issue<commit_after>#define BOOST_TEST_MODULE utymap_testsuite
#include <boost/test/unit_test.hpp>
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2015-2018 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include "volumesequencesource.h"
#include <inviwo/core/io/datareaderfactory.h>
#include <inviwo/core/util/filesystem.h>
#include <inviwo/core/io/datareaderexception.h>

namespace inviwo {

// The Class Identifier has to be globally unique. Use a reverse DNS naming scheme
const ProcessorInfo VolumeSequenceSource::processorInfo_{
    "org.inviwo.VolumeVectorSource",  // Class identifier
    "Volume Sequence Source",         // Display name
    "Data Input",                     // Category
    CodeState::Stable,                // Code state
    Tags::CPU,                        // Tags
};
const ProcessorInfo VolumeSequenceSource::getProcessorInfo() const { return processorInfo_; }

VolumeSequenceSource::VolumeSequenceSource()
    : Processor()
    , outport_("data")
    , inputType_("inputType", "Input type",
                 {{"singlefile", "Single File", InputType::SingleFile},
                  {"folder", "Folder", InputType::Folder}},
                 0)
    , file_("filename", "Volume file")
    , folder_("folder", "Volume folder")
    , filter_("filter_", "Filter", "*.*")
    , reload_("reload", "Reload data")
    , basis_("Basis", "Basis and offset")
    , information_("Information", "Data information") {
    file_.setContentType("volume");
    folder_.setContentType("volume");

    // make sure that we always process even if not connected
    isSink_.setUpdate([]() { return true; });

    addFileNameFilters();

    addPort(outport_);

    addProperty(inputType_);
    addProperty(folder_);
    addProperty(filter_);
    addProperty(file_);
    addProperty(reload_);
    addProperty(information_);
    addProperty(basis_);

    auto updateVisible = [&]() {
        file_.setVisible(inputType_.get() == InputType::SingleFile);
        folder_.setVisible(inputType_.get() == InputType::Folder);
        filter_.setVisible(inputType_.get() == InputType::Folder);
    };

    inputType_.onChange(updateVisible);
    updateVisible();
}

void VolumeSequenceSource::load(bool deserialize) {
    switch (inputType_.get()) {
        case InputType::Folder:
            loadFolder(deserialize);
            break;
        case InputType::SingleFile:
        default:
            loadFile(deserialize);
            break;
    }
}

void VolumeSequenceSource::loadFile(bool deserialize) {
    if (file_.get().empty()) return;

    auto rf = InviwoApplication::getPtr()->getDataReaderFactory();
    std::string ext = filesystem::getFileExtension(file_.get());
    if (auto reader = rf->getReaderForTypeAndExtension<VolumeSequence>(ext)) {
        try {
            volumes_ = reader->readData(file_.get(), this);
        } catch (DataReaderException const& e) {
            LogProcessorError(e.getMessage());
        }
    } else {
        LogProcessorError("Could not find a data reader for file: " << file_.get());
    }

    if (volumes_ && !volumes_->empty() && (*volumes_)[0]) {
        basis_.updateForNewEntity(*(*volumes_)[0], deserialize);
        information_.updateForNewVolume(*(*volumes_)[0], deserialize);
    }
}

void VolumeSequenceSource::loadFolder(bool deserialize) {
    if (folder_.get().empty()) return;

    volumes_ = std::make_shared<VolumeSequence>();
    auto rf = InviwoApplication::getPtr()->getDataReaderFactory();

    auto files = filesystem::getDirectoryContents(folder_.get());
    for (auto f : files) {
        auto file = folder_.get() + "/" + f;
        if (filesystem::wildcardStringMatch(filter_, file)) {
            std::string ext = filesystem::getFileExtension(file);
            try {
                if (auto reader1 = rf->getReaderForTypeAndExtension<Volume>(ext)) {
                    auto volume = reader1->readData(file, this);
                    volume->setMetaData<StringMetaData>("filename", file);
                    volumes_->push_back(volume);

                } else if (auto reader2 = rf->getReaderForTypeAndExtension<VolumeSequence>(ext)) {
                    auto volumes = reader2->readData(file, this);
                    for (auto volume : *volumes) {
                        volume->setMetaData<StringMetaData>("filename", file);
                        volumes_->push_back(volume);
                    }
                } else {
                    LogProcessorError("Could not find a data reader for file: " << file);
                }
            } catch (DataReaderException const& e) {
                LogProcessorError(e.getMessage());
            }
        }
    }

    if (volumes_ && !volumes_->empty()) {
        // store filename in metadata
        for (auto volume : *volumes_) {
            if (!volume->hasMetaData<StringMetaData>("filename"))
                volume->setMetaData<StringMetaData>("filename", file_.get());
        }

        // set basis of first volume
        if ((*volumes_)[0]) {
            basis_.updateForNewEntity(*(*volumes_)[0], deserialize);
            information_.updateForNewVolume(*(*volumes_)[0], deserialize);
        }
    }
}

void VolumeSequenceSource::addFileNameFilters() {
    auto rf = InviwoApplication::getPtr()->getDataReaderFactory();
    file_.clearNameFilters();
    file_.addNameFilter(FileExtension("*", "All Files"));
    file_.addNameFilters(rf->getExtensionsForType<VolumeSequence>());
}

void VolumeSequenceSource::process() {
    if (file_.isModified() || reload_.isModified() || folder_.isModified() ||
        filter_.isModified()) {
        load(deserialized_);
        deserialized_ = false;
    }

    if (volumes_ && !volumes_->empty()) {
        for (auto& vol : *volumes_) {
            basis_.updateEntity(*vol);
            information_.updateVolume(*vol);
        }
        outport_.setData(volumes_);
    }
}

void VolumeSequenceSource::deserialize(Deserializer& d) {
    Processor::deserialize(d);
    addFileNameFilters();
    deserialized_ = true;
}
}  // namespace inviwo
<commit_msg>Base: Made information and basis properties read-only in VolumeSequenceSource and disabled their usage since they where applied to all values no matter if you had changed them or not. it did not make sense to override these settings for all volumes. Still kept for information purposes.<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2015-2018 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include "volumesequencesource.h"
#include <inviwo/core/io/datareaderfactory.h>
#include <inviwo/core/util/filesystem.h>
#include <inviwo/core/io/datareaderexception.h>

namespace inviwo {

// The Class Identifier has to be globally unique. Use a reverse DNS naming scheme
const ProcessorInfo VolumeSequenceSource::processorInfo_{
    "org.inviwo.VolumeVectorSource",  // Class identifier
    "Volume Sequence Source",         // Display name
    "Data Input",                     // Category
    CodeState::Stable,                // Code state
    Tags::CPU,                        // Tags
};
const ProcessorInfo VolumeSequenceSource::getProcessorInfo() const { return processorInfo_; }

VolumeSequenceSource::VolumeSequenceSource()
    : Processor()
    , outport_("data")
    , inputType_("inputType", "Input type",
                 {{"singlefile", "Single File", InputType::SingleFile},
                  {"folder", "Folder", InputType::Folder}},
                 0)
    , file_("filename", "Volume file")
    , folder_("folder", "Volume folder")
    , filter_("filter_", "Filter", "*.*")
    , reload_("reload", "Reload data")
    , basis_("Basis", "Basis and offset")
    , information_("Information", "Data information") {
    file_.setContentType("volume");
    folder_.setContentType("volume");

    // make sure that we always process even if not connected
    isSink_.setUpdate([]() { return true; });

    addFileNameFilters();

    addPort(outport_);

    addProperty(inputType_);
    addProperty(folder_);
    addProperty(filter_);
    addProperty(file_);
    addProperty(reload_);
    addProperty(information_);
    addProperty(basis_);

	// It does not make sense to change these for an entire sequence
	information_.setReadOnly(true);
	basis_.setReadOnly(true);

    auto updateVisible = [&]() {
        file_.setVisible(inputType_.get() == InputType::SingleFile);
        folder_.setVisible(inputType_.get() == InputType::Folder);
        filter_.setVisible(inputType_.get() == InputType::Folder);
    };

    inputType_.onChange(updateVisible);
    updateVisible();
}

void VolumeSequenceSource::load(bool deserialize) {
    switch (inputType_.get()) {
        case InputType::Folder:
            loadFolder(deserialize);
            break;
        case InputType::SingleFile:
        default:
            loadFile(deserialize);
            break;
    }
}

void VolumeSequenceSource::loadFile(bool deserialize) {
    if (file_.get().empty()) return;

    auto rf = InviwoApplication::getPtr()->getDataReaderFactory();
    std::string ext = filesystem::getFileExtension(file_.get());
    if (auto reader = rf->getReaderForTypeAndExtension<VolumeSequence>(ext)) {
        try {
            volumes_ = reader->readData(file_.get(), this);
        } catch (DataReaderException const& e) {
            LogProcessorError(e.getMessage());
        }
    } else {
        LogProcessorError("Could not find a data reader for file: " << file_.get());
    }

    if (volumes_ && !volumes_->empty() && (*volumes_)[0]) {
        basis_.updateForNewEntity(*(*volumes_)[0], deserialize);
        information_.updateForNewVolume(*(*volumes_)[0], deserialize);
    }
}

void VolumeSequenceSource::loadFolder(bool deserialize) {
    if (folder_.get().empty()) return;

    volumes_ = std::make_shared<VolumeSequence>();
    auto rf = InviwoApplication::getPtr()->getDataReaderFactory();

    auto files = filesystem::getDirectoryContents(folder_.get());
    for (auto f : files) {
        auto file = folder_.get() + "/" + f;
        if (filesystem::wildcardStringMatch(filter_, file)) {
            std::string ext = filesystem::getFileExtension(file);
            try {
                if (auto reader1 = rf->getReaderForTypeAndExtension<Volume>(ext)) {
                    auto volume = reader1->readData(file, this);
                    volume->setMetaData<StringMetaData>("filename", file);
                    volumes_->push_back(volume);

                } else if (auto reader2 = rf->getReaderForTypeAndExtension<VolumeSequence>(ext)) {
                    auto volumes = reader2->readData(file, this);
                    for (auto volume : *volumes) {
                        volume->setMetaData<StringMetaData>("filename", file);
                        volumes_->push_back(volume);
                    }
                } else {
                    LogProcessorError("Could not find a data reader for file: " << file);
                }
            } catch (DataReaderException const& e) {
                LogProcessorError(e.getMessage());
            }
        }
    }

    if (volumes_ && !volumes_->empty()) {
        // store filename in metadata
        for (auto volume : *volumes_) {
            if (!volume->hasMetaData<StringMetaData>("filename"))
                volume->setMetaData<StringMetaData>("filename", file_.get());
        }

        // set basis of first volume
        if ((*volumes_)[0]) {
            basis_.updateForNewEntity(*(*volumes_)[0], deserialize);
            information_.updateForNewVolume(*(*volumes_)[0], deserialize);
        }
    }
}

void VolumeSequenceSource::addFileNameFilters() {
    auto rf = InviwoApplication::getPtr()->getDataReaderFactory();
    file_.clearNameFilters();
    file_.addNameFilter(FileExtension("*", "All Files"));
    file_.addNameFilters(rf->getExtensionsForType<VolumeSequence>());
}

void VolumeSequenceSource::process() {
    if (file_.isModified() || reload_.isModified() || folder_.isModified() ||
        filter_.isModified()) {
        load(deserialized_);
        deserialized_ = false;
    }

    if (volumes_ && !volumes_->empty()) {
        outport_.setData(volumes_);
    }
}

void VolumeSequenceSource::deserialize(Deserializer& d) {
    Processor::deserialize(d);
    addFileNameFilters();
	// It does not make sense to change these for an entire sequence
	information_.setReadOnly(true);
	basis_.setReadOnly(true);
    deserialized_ = true;
}
}  // namespace inviwo
<|endoftext|>


<commit_before>/*****************************************************************************
 * Controller_widget.cpp : Controller Widget for the controllers
 ****************************************************************************
 * Copyright (C) 2006-2008 the VideoLAN team
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * ( at your option ) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "controller_widget.hpp"

#include "input_manager.hpp"         /* Get notification of Volume Change */
#include "util/input_slider.hpp"     /* SoundSlider */

#include <vlc_aout.h>                /* Volume functions */

#include <QLabel>
#include <QHBoxLayout>
#include <QSpinBox>
#include <QMenu>
#include <QWidgetAction>

SoundWidget::SoundWidget( QWidget *_parent, intf_thread_t * _p_intf,
                          bool b_shiny, bool b_special )
                         : QWidget( _parent ), b_my_volume( false ),
                           p_intf( _p_intf)
{
    /* We need a layout for this widget */
    QHBoxLayout *layout = new QHBoxLayout( this );
    layout->setSpacing( 0 ); layout->setMargin( 0 );

    /* We need a Label for the pix */
    volMuteLabel = new QLabel;
    volMuteLabel->setPixmap( QPixmap( ":/volume-medium" ) );

    /* We might need a subLayout too */
    QVBoxLayout *subLayout;

    /* Normal View, click on icon mutes */
    if( !b_special )
    {
        volMuteLabel->installEventFilter( this );
        volumeMenu = NULL;
        subLayout = NULL;
    }
    else
    {
        /* Special view, click on button shows the slider */
        b_shiny = false;

        setContextMenuPolicy ( Qt::CustomContextMenu );

        QFrame *volumeControlWidget = new QFrame;
        subLayout = new QVBoxLayout( volumeControlWidget );
        subLayout->setLayoutMargins( 4, 4, 4, 4, 4 );
        volumeMenu = new QMenu( this );

        QWidgetAction *widgetAction = new QWidgetAction( volumeControlWidget );
        widgetAction->setDefaultWidget( volumeControlWidget );
        volumeMenu->addAction( widgetAction );

        /* Speed Label behaviour:
           - right click gives the vertical speed slider */
        CONNECT( this, customContextMenuRequested( QPoint ),
                this, showVolumeMenu( QPoint ) );

    }

    /* And add the label */
    layout->addWidget( volMuteLabel );

    /* Slider creation: shiny or clean */
    if( b_shiny )
    {
        volumeSlider = new SoundSlider( this,
            config_GetInt( p_intf, "volume-step" ),
            config_GetInt( p_intf, "qt-volume-complete" ),
            config_GetPsz( p_intf, "qt-slider-colours" ) );
    }
    else
    {
        volumeSlider = new QSlider( NULL );
        volumeSlider->setOrientation( b_special ? Qt::Vertical
                                                : Qt::Horizontal );
        volumeSlider->setMaximum( config_GetInt( p_intf, "qt-volume-complete" )
                                  ? 400 : 200 );
    }
    if( volumeSlider->orientation() ==  Qt::Horizontal )
    {
        volumeSlider->setMaximumSize( QSize( 200, 40 ) );
        volumeSlider->setMinimumSize( QSize( 85, 30 ) );
    }

    volumeSlider->setFocusPolicy( Qt::NoFocus );
    if( b_special )
        subLayout->addWidget( volumeSlider );
    else
        layout->addWidget( volumeSlider );

    /* Set the volume from the config */
    volumeSlider->setValue( ( config_GetInt( p_intf, "volume" ) ) *
                              VOLUME_MAX / (AOUT_VOLUME_MAX/2) );

    /* Force the update at build time in order to have a muted icon if needed */
    updateVolume( volumeSlider->value() );

    /* Volume control connection */
    CONNECT( volumeSlider, valueChanged( int ), this, updateVolume( int ) );
    CONNECT( THEMIM, volumeChanged( void ), this, updateVolume( void ) );
}

void SoundWidget::showVolumeMenu( QPoint pos )
{
    volumeMenu->exec( QCursor::pos() - pos - QPoint( 0, volumeMenu->height()/2 )
                          + QPoint( width(), height() /2) );
}

bool SoundWidget::eventFilter( QObject *obj, QEvent *e )
{
    VLC_UNUSED( obj );
    if (e->type() == QEvent::MouseButtonPress  )
    {
        aout_VolumeMute( p_intf, NULL );
        audio_volume_t i_volume;
        aout_VolumeGet( p_intf, &i_volume );
        e->accept();
        return true;
    }
    else
    {
        e->ignore();
        return false;
    }
}

void SoundWidget::updateVolume( int i_sliderVolume )
{
    if( !b_my_volume )
    {
        int i_res = i_sliderVolume  * (AOUT_VOLUME_MAX / 2) / VOLUME_MAX;
        aout_VolumeSet( p_intf, i_res );
    }
    if( i_sliderVolume == 0 )
    {
        volMuteLabel->setPixmap( QPixmap(":/volume-muted" ) );
        volMuteLabel->setToolTip( qtr( "Unmute" ) );
        return;
    }

    if( i_sliderVolume < VOLUME_MAX / 3 )
        volMuteLabel->setPixmap( QPixmap( ":/volume-low" ) );
    else if( i_sliderVolume > (VOLUME_MAX * 2 / 3 ) )
        volMuteLabel->setPixmap( QPixmap( ":/volume-high" ) );
    else volMuteLabel->setPixmap( QPixmap( ":/volume-medium" ) );
    volMuteLabel->setToolTip( qtr( "Mute" ) );
}

void SoundWidget::updateVolume()
{
    /* Audio part */
    audio_volume_t i_volume;
    aout_VolumeGet( p_intf, &i_volume );
    i_volume = ( i_volume *  VOLUME_MAX )/ (AOUT_VOLUME_MAX/2);
    int i_gauge = volumeSlider->value();
    b_my_volume = false;
    if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
    {
        b_my_volume = true;
        volumeSlider->setValue( i_volume );
        b_my_volume = false;
    }
}

void TeletextController::enableTeletextButtons( bool b_enabled )
{
    telexOn->setChecked( b_enabled );
    telexTransparent->setEnabled( b_enabled );
    telexPage->setEnabled( b_enabled );
}

void PlayButton::updateButton( bool b_playing )
{
    setIcon( b_playing ? QIcon( ":/pause_b" ) : QIcon( ":/play_b" ) );
    setToolTip( b_playing ? qtr( "Pause the playback" )
                          : qtr( I_PLAY_TOOLTIP ) );
}

void AtoB_Button::setIcons( bool timeA, bool timeB )
{
    if( !timeA && !timeB)
    {
        setIcon( QIcon( ":/atob_nob" ) );
        setToolTip( qtr( "Loop from point A to point B continuously\n"
                         "Click to set point A" ) );
    }
    else if( timeA && !timeB )
    {
        setIcon( QIcon( ":/atob_noa" ) );
        setToolTip( qtr( "Click to set point B" ) );
    }
    else if( timeA && timeB )
    {
        setIcon( QIcon( ":/atob" ) );
        setToolTip( qtr( "Stop the A to B loop" ) );
    }
}

<commit_msg>Qt: simplification of the special volume slider. Any click will show it.<commit_after>/*****************************************************************************
 * Controller_widget.cpp : Controller Widget for the controllers
 ****************************************************************************
 * Copyright (C) 2006-2008 the VideoLAN team
 * $Id$
 *
 * Authors: Jean-Baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * ( at your option ) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "controller_widget.hpp"

#include "input_manager.hpp"         /* Get notification of Volume Change */
#include "util/input_slider.hpp"     /* SoundSlider */

#include <vlc_aout.h>                /* Volume functions */

#include <QLabel>
#include <QHBoxLayout>
#include <QSpinBox>
#include <QMenu>
#include <QWidgetAction>
#include <QMouseEvent>

SoundWidget::SoundWidget( QWidget *_parent, intf_thread_t * _p_intf,
                          bool b_shiny, bool b_special )
                         : QWidget( _parent ), b_my_volume( false ),
                           p_intf( _p_intf)
{
    /* We need a layout for this widget */
    QHBoxLayout *layout = new QHBoxLayout( this );
    layout->setSpacing( 0 ); layout->setMargin( 0 );

    /* We need a Label for the pix */
    volMuteLabel = new QLabel;
    volMuteLabel->setPixmap( QPixmap( ":/volume-medium" ) );

    /* We might need a subLayout too */
    QVBoxLayout *subLayout;

    /* Normal View, click on icon mutes */
    if( !b_special )
    {
        volMuteLabel->installEventFilter( this );
        volumeMenu = NULL;
        subLayout = NULL;
    }
    else
    {
        /* Special view, click on button shows the slider */
        b_shiny = false;

        volMuteLabel->installEventFilter( this );

        QFrame *volumeControlWidget = new QFrame;
        subLayout = new QVBoxLayout( volumeControlWidget );
        subLayout->setLayoutMargins( 4, 4, 4, 4, 4 );
        volumeMenu = new QMenu( this );

        QWidgetAction *widgetAction = new QWidgetAction( volumeControlWidget );
        widgetAction->setDefaultWidget( volumeControlWidget );
        volumeMenu->addAction( widgetAction );

    }

    /* And add the label */
    layout->addWidget( volMuteLabel );

    /* Slider creation: shiny or clean */
    if( b_shiny )
    {
        volumeSlider = new SoundSlider( this,
            config_GetInt( p_intf, "volume-step" ),
            config_GetInt( p_intf, "qt-volume-complete" ),
            config_GetPsz( p_intf, "qt-slider-colours" ) );
    }
    else
    {
        volumeSlider = new QSlider( NULL );
        volumeSlider->setOrientation( b_special ? Qt::Vertical
                                                : Qt::Horizontal );
        volumeSlider->setMaximum( config_GetInt( p_intf, "qt-volume-complete" )
                                  ? 400 : 200 );
    }
    if( volumeSlider->orientation() ==  Qt::Horizontal )
    {
        volumeSlider->setMaximumSize( QSize( 200, 40 ) );
        volumeSlider->setMinimumSize( QSize( 85, 30 ) );
    }

    volumeSlider->setFocusPolicy( Qt::NoFocus );
    if( b_special )
        subLayout->addWidget( volumeSlider );
    else
        layout->addWidget( volumeSlider );

    /* Set the volume from the config */
    volumeSlider->setValue( ( config_GetInt( p_intf, "volume" ) ) *
                              VOLUME_MAX / (AOUT_VOLUME_MAX/2) );

    /* Force the update at build time in order to have a muted icon if needed */
    updateVolume( volumeSlider->value() );

    /* Volume control connection */
    CONNECT( volumeSlider, valueChanged( int ), this, updateVolume( int ) );
    CONNECT( THEMIM, volumeChanged( void ), this, updateVolume( void ) );
}

void SoundWidget::showVolumeMenu( QPoint pos )
{
    volumeMenu->exec( QCursor::pos() - pos - QPoint( 0, volumeMenu->height()/2 )
                          + QPoint( width(), height() /2) );
}

bool SoundWidget::eventFilter( QObject *obj, QEvent *e )
{
    VLC_UNUSED( obj );
    if (e->type() == QEvent::MouseButtonPress  )
    {
        if( volumeSlider->orientation() ==  Qt::Vertical )
        {
            QMouseEvent *event = static_cast<QMouseEvent*>(e);
            showVolumeMenu( event->pos() );
        }
        else
        {
            aout_VolumeMute( p_intf, NULL );
            audio_volume_t i_volume;
            aout_VolumeGet( p_intf, &i_volume );
        }
        e->accept();
        return true;
    }
    else
    {
        e->ignore();
        return false;
    }
}

void SoundWidget::updateVolume( int i_sliderVolume )
{
    if( !b_my_volume )
    {
        int i_res = i_sliderVolume  * (AOUT_VOLUME_MAX / 2) / VOLUME_MAX;
        aout_VolumeSet( p_intf, i_res );
    }
    if( i_sliderVolume == 0 )
    {
        volMuteLabel->setPixmap( QPixmap(":/volume-muted" ) );
        volMuteLabel->setToolTip( qtr( "Unmute" ) );
        return;
    }

    if( i_sliderVolume < VOLUME_MAX / 3 )
        volMuteLabel->setPixmap( QPixmap( ":/volume-low" ) );
    else if( i_sliderVolume > (VOLUME_MAX * 2 / 3 ) )
        volMuteLabel->setPixmap( QPixmap( ":/volume-high" ) );
    else volMuteLabel->setPixmap( QPixmap( ":/volume-medium" ) );
    volMuteLabel->setToolTip( qtr( "Mute" ) );
}

void SoundWidget::updateVolume()
{
    /* Audio part */
    audio_volume_t i_volume;
    aout_VolumeGet( p_intf, &i_volume );
    i_volume = ( i_volume *  VOLUME_MAX )/ (AOUT_VOLUME_MAX/2);
    int i_gauge = volumeSlider->value();
    b_my_volume = false;
    if( i_volume - i_gauge > 1 || i_gauge - i_volume > 1 )
    {
        b_my_volume = true;
        volumeSlider->setValue( i_volume );
        b_my_volume = false;
    }
}

void TeletextController::enableTeletextButtons( bool b_enabled )
{
    telexOn->setChecked( b_enabled );
    telexTransparent->setEnabled( b_enabled );
    telexPage->setEnabled( b_enabled );
}

void PlayButton::updateButton( bool b_playing )
{
    setIcon( b_playing ? QIcon( ":/pause_b" ) : QIcon( ":/play_b" ) );
    setToolTip( b_playing ? qtr( "Pause the playback" )
                          : qtr( I_PLAY_TOOLTIP ) );
}

void AtoB_Button::setIcons( bool timeA, bool timeB )
{
    if( !timeA && !timeB)
    {
        setIcon( QIcon( ":/atob_nob" ) );
        setToolTip( qtr( "Loop from point A to point B continuously\n"
                         "Click to set point A" ) );
    }
    else if( timeA && !timeB )
    {
        setIcon( QIcon( ":/atob_noa" ) );
        setToolTip( qtr( "Click to set point B" ) );
    }
    else if( timeA && timeB )
    {
        setIcon( QIcon( ":/atob" ) );
        setToolTip( qtr( "Stop the A to B loop" ) );
    }
}

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2017 metaverse core developers (see MVS-AUTHORS)
 *
 * This file is part of metaverse.
 *
 * metaverse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/bitcoin/utility/path.hpp>
#include <boost/thread/once.hpp>

#ifdef _WIN32
#include <Shlobj.h>
#endif

namespace libbitcoin{

const boost::filesystem::path& default_data_path()
{
    static boost::filesystem::path default_path("");
    static boost::once_flag once = BOOST_ONCE_INIT;
    auto path_init = []() {
        namespace fs = boost::filesystem;
        // Windows < Vista: C:\Documents and Settings\Username\Application Data\Metaverse
        // Windows >= Vista: C:\Users\Username\AppData\Roaming\Metaverse
        // Mac: ~/Library/Application Support/Metaverse
        // Unix: ~/.metaverse
#ifdef _WIN32
        // Windows
#ifdef UNICODE
        wchar_t file_path[MAX_PATH] = { 0 };
#else
        char file_path[MAX_PATH] = { 0 };
#endif
        SHGetSpecialFolderPath(NULL, file_path, CSIDL_APPDATA, true);
        fs::path pathRet = boost::filesystem::path(file_path) / "Metaverse";
        fs::create_directories(pathRet);
        default_path = pathRet;
#else
        fs::path pathRet;
        char* pszHome = getenv("HOME");
        if (pszHome == nullptr || strlen(pszHome) == 0)
            pathRet = fs::path("/");
        else
            pathRet = fs::path(pszHome);
#ifdef MAC_OSX
        // Mac
        pathRet /= "Library/Application Support";
        fs::create_directories(pathRet / "Metaverse");
        default_path = pathRet / "Metaverse";
#else
        // Unix
        fs::create_directories(pathRet / ".metaverse");
        default_path = pathRet / ".metaverse";
#endif
#endif
    };
    boost::call_once(path_init, once);
    return default_path;
}

boost::filesystem::path webpage_path()
{
#ifdef _WIN32
	return "mvs-htmls";
#else
	return default_data_path() / "mvs-htmls";
#endif
}

}//namespace libbitcoin

<commit_msg>webpath() return absolute path<commit_after>/**
 * Copyright (c) 2016-2017 metaverse core developers (see MVS-AUTHORS)
 *
 * This file is part of metaverse.
 *
 * metaverse is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/bitcoin/utility/path.hpp>
#include <boost/thread/once.hpp>

#ifdef _WIN32
#include <Shlobj.h>
#endif

namespace libbitcoin{

const boost::filesystem::path& default_data_path()
{
    static boost::filesystem::path default_path("");
    static boost::once_flag once = BOOST_ONCE_INIT;
    auto path_init = []() {
        namespace fs = boost::filesystem;
        // Windows < Vista: C:\Documents and Settings\Username\Application Data\Metaverse
        // Windows >= Vista: C:\Users\Username\AppData\Roaming\Metaverse
        // Mac: ~/Library/Application Support/Metaverse
        // Unix: ~/.metaverse
#ifdef _WIN32
        // Windows
#ifdef UNICODE
        wchar_t file_path[MAX_PATH] = { 0 };
#else
        char file_path[MAX_PATH] = { 0 };
#endif
        SHGetSpecialFolderPath(NULL, file_path, CSIDL_APPDATA, true);
        fs::path pathRet = boost::filesystem::path(file_path) / "Metaverse";
        fs::create_directories(pathRet);
        default_path = pathRet;
#else
        fs::path pathRet;
        char* pszHome = getenv("HOME");
        if (pszHome == nullptr || strlen(pszHome) == 0)
            pathRet = fs::path("/");
        else
            pathRet = fs::path(pszHome);
#ifdef MAC_OSX
        // Mac
        pathRet /= "Library/Application Support";
        fs::create_directories(pathRet / "Metaverse");
        default_path = pathRet / "Metaverse";
#else
        // Unix
        fs::create_directories(pathRet / ".metaverse");
        default_path = pathRet / ".metaverse";
#endif
#endif
    };
    boost::call_once(path_init, once);
    return default_path;
}

boost::filesystem::path webpage_path()
{
	return default_data_path() / "mvs-htmls";
}

}//namespace libbitcoin

<|endoftext|>


<commit_before>/*
* TLS Hello Request and Client Hello Messages
* (C) 2004-2011,2015,2016 Jack Lloyd
*     2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/internal/tls_messages.h>
#include <botan/internal/tls_reader.h>
#include <botan/internal/tls_session_key.h>
#include <botan/internal/tls_handshake_io.h>
#include <botan/internal/stl_util.h>
#include <chrono>

namespace Botan {

namespace TLS {

enum {
   TLS_EMPTY_RENEGOTIATION_INFO_SCSV        = 0x00FF,
   TLS_FALLBACK_SCSV                        = 0x5600
};

std::vector<byte> make_hello_random(RandomNumberGenerator& rng,
                                    const Policy& policy)
   {
   std::vector<byte> buf(32);
   rng.randomize(buf.data(), buf.size());

   if(policy.include_time_in_hello_random())
      {
      const u32bit time32 = static_cast<u32bit>(
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));

      store_be(time32, buf.data());
      }

   return buf;
   }

/*
* Create a new Hello Request message
*/
Hello_Request::Hello_Request(Handshake_IO& io)
   {
   io.send(*this);
   }

/*
* Deserialize a Hello Request message
*/
Hello_Request::Hello_Request(const std::vector<byte>& buf)
   {
   if(buf.size())
      throw Decoding_Error("Bad Hello_Request, has non-zero size");
   }

/*
* Serialize a Hello Request message
*/
std::vector<byte> Hello_Request::serialize() const
   {
   return std::vector<byte>();
   }

/*
* Create a new Client Hello message
*/
Client_Hello::Client_Hello(Handshake_IO& io,
                           Handshake_Hash& hash,
                           const Policy& policy,
                           RandomNumberGenerator& rng,
                           const std::vector<byte>& reneg_info,
                           const Client_Hello::Settings& client_settings,
                           const std::vector<std::string>& next_protocols) :
   m_version(client_settings.protocol_version()),
   m_random(make_hello_random(rng, policy)),
   m_suites(policy.ciphersuite_list(m_version,
                                    client_settings.srp_identifier() != "")),
   m_comp_methods(policy.compression())
   {
   m_extensions.add(new Extended_Master_Secret);
   m_extensions.add(new Renegotiation_Extension(reneg_info));
   m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
   m_extensions.add(new Session_Ticket());
   m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));

   if(m_version.supports_negotiable_signature_algorithms())
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
                                                policy.allowed_signature_methods()));

   if(m_version.is_datagram_protocol())
     m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));

   if(reneg_info.empty() && !next_protocols.empty())
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));

#if defined(BOTAN_HAS_SRP6)
   m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
#else
   if(!srp_identifier.empty())
      {
      throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
      }
#endif

   BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()),
                "Our policy accepts the version we are offering");

   if(policy.send_fallback_scsv(client_settings.protocol_version()))
      m_suites.push_back(TLS_FALLBACK_SCSV);

   hash.update(io.send(*this));
   }

/*
* Create a new Client Hello message (session resumption case)
*/
Client_Hello::Client_Hello(Handshake_IO& io,
                           Handshake_Hash& hash,
                           const Policy& policy,
                           RandomNumberGenerator& rng,
                           const std::vector<byte>& reneg_info,
                           const Session& session,
                           const std::vector<std::string>& next_protocols) :
   m_version(session.version()),
   m_session_id(session.session_id()),
   m_random(make_hello_random(rng, policy)),
   m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
   m_comp_methods(policy.compression())
   {
   if(!value_exists(m_suites, session.ciphersuite_code()))
      m_suites.push_back(session.ciphersuite_code());

   if(!value_exists(m_comp_methods, session.compression_method()))
      m_comp_methods.push_back(session.compression_method());

   /*
   We always add the EMS extension, even if not used in the original session.
   If the server understands it and follows the RFC it should reject our resume
   attempt and upgrade us to a new session with the EMS protection.
   */
   m_extensions.add(new Extended_Master_Secret);

   m_extensions.add(new Renegotiation_Extension(reneg_info));
   m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
   m_extensions.add(new Session_Ticket(session.session_ticket()));
   m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));

   if(m_version.supports_negotiable_signature_algorithms())
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
                                                policy.allowed_signature_methods()));

   if(reneg_info.empty() && !next_protocols.empty())
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));

#if defined(BOTAN_HAS_SRP6)
   m_extensions.add(new SRP_Identifier(session.srp_identifier()));
#else
   if(!session.srp_identifier().empty())
      {
      throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
      }
#endif

   hash.update(io.send(*this));
   }

void Client_Hello::update_hello_cookie(const Hello_Verify_Request& hello_verify)
   {
   if(!m_version.is_datagram_protocol())
      throw Exception("Cannot use hello cookie with stream protocol");

   m_hello_cookie = hello_verify.cookie();
   }

/*
* Serialize a Client Hello message
*/
std::vector<byte> Client_Hello::serialize() const
   {
   std::vector<byte> buf;

   buf.push_back(m_version.major_version());
   buf.push_back(m_version.minor_version());
   buf += m_random;

   append_tls_length_value(buf, m_session_id, 1);

   if(m_version.is_datagram_protocol())
      append_tls_length_value(buf, m_hello_cookie, 1);

   append_tls_length_value(buf, m_suites, 2);
   append_tls_length_value(buf, m_comp_methods, 1);

   /*
   * May not want to send extensions at all in some cases. If so,
   * should include SCSV value (if reneg info is empty, if not we are
   * renegotiating with a modern server)
   */

   buf += m_extensions.serialize();

   return buf;
   }

/*
* Read a counterparty client hello
*/
Client_Hello::Client_Hello(const std::vector<byte>& buf)
   {
   if(buf.size() == 0)
      throw Decoding_Error("Client_Hello: Packet corrupted");

   if(buf.size() < 41)
      throw Decoding_Error("Client_Hello: Packet corrupted");

   TLS_Data_Reader reader("ClientHello", buf);

   const byte major_version = reader.get_byte();
   const byte minor_version = reader.get_byte();

   m_version = Protocol_Version(major_version, minor_version);

   m_random = reader.get_fixed<byte>(32);

   m_session_id = reader.get_range<byte>(1, 0, 32);

   if(m_version.is_datagram_protocol())
      m_hello_cookie = reader.get_range<byte>(1, 0, 255);

   m_suites = reader.get_range_vector<u16bit>(2, 1, 32767);

   m_comp_methods = reader.get_range_vector<byte>(1, 1, 255);

   m_extensions.deserialize(reader);

   if(offered_suite(static_cast<u16bit>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
      {
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
         {
         if(!reneg->renegotiation_info().empty())
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                                "Client sent renegotiation SCSV and non-empty extension");
         }
      else
         {
         // add fake extension
         m_extensions.add(new Renegotiation_Extension());
         }
      }
   }

bool Client_Hello::sent_fallback_scsv() const
   {
   return offered_suite(static_cast<u16bit>(TLS_FALLBACK_SCSV));
   }

/*
* Check if we offered this ciphersuite
*/
bool Client_Hello::offered_suite(u16bit ciphersuite) const
   {
   for(size_t i = 0; i != m_suites.size(); ++i)
      if(m_suites[i] == ciphersuite)
         return true;
   return false;
   }

}

}
<commit_msg>Fix TLS build with SRP6 disabled<commit_after>/*
* TLS Hello Request and Client Hello Messages
* (C) 2004-2011,2015,2016 Jack Lloyd
*     2016 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/internal/tls_messages.h>
#include <botan/internal/tls_reader.h>
#include <botan/internal/tls_session_key.h>
#include <botan/internal/tls_handshake_io.h>
#include <botan/internal/stl_util.h>
#include <chrono>

namespace Botan {

namespace TLS {

enum {
   TLS_EMPTY_RENEGOTIATION_INFO_SCSV        = 0x00FF,
   TLS_FALLBACK_SCSV                        = 0x5600
};

std::vector<byte> make_hello_random(RandomNumberGenerator& rng,
                                    const Policy& policy)
   {
   std::vector<byte> buf(32);
   rng.randomize(buf.data(), buf.size());

   if(policy.include_time_in_hello_random())
      {
      const u32bit time32 = static_cast<u32bit>(
         std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));

      store_be(time32, buf.data());
      }

   return buf;
   }

/*
* Create a new Hello Request message
*/
Hello_Request::Hello_Request(Handshake_IO& io)
   {
   io.send(*this);
   }

/*
* Deserialize a Hello Request message
*/
Hello_Request::Hello_Request(const std::vector<byte>& buf)
   {
   if(buf.size())
      throw Decoding_Error("Bad Hello_Request, has non-zero size");
   }

/*
* Serialize a Hello Request message
*/
std::vector<byte> Hello_Request::serialize() const
   {
   return std::vector<byte>();
   }

/*
* Create a new Client Hello message
*/
Client_Hello::Client_Hello(Handshake_IO& io,
                           Handshake_Hash& hash,
                           const Policy& policy,
                           RandomNumberGenerator& rng,
                           const std::vector<byte>& reneg_info,
                           const Client_Hello::Settings& client_settings,
                           const std::vector<std::string>& next_protocols) :
   m_version(client_settings.protocol_version()),
   m_random(make_hello_random(rng, policy)),
   m_suites(policy.ciphersuite_list(m_version,
                                    client_settings.srp_identifier() != "")),
   m_comp_methods(policy.compression())
   {
   m_extensions.add(new Extended_Master_Secret);
   m_extensions.add(new Renegotiation_Extension(reneg_info));
   m_extensions.add(new Server_Name_Indicator(client_settings.hostname()));
   m_extensions.add(new Session_Ticket());
   m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));

   if(m_version.supports_negotiable_signature_algorithms())
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
                                                policy.allowed_signature_methods()));

   if(m_version.is_datagram_protocol())
     m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));

   if(reneg_info.empty() && !next_protocols.empty())
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));

#if defined(BOTAN_HAS_SRP6)
   m_extensions.add(new SRP_Identifier(client_settings.srp_identifier()));
#else
   if(!client_settings.srp_identifier().empty())
      {
      throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled");
      }
#endif

   BOTAN_ASSERT(policy.acceptable_protocol_version(client_settings.protocol_version()),
                "Our policy accepts the version we are offering");

   if(policy.send_fallback_scsv(client_settings.protocol_version()))
      m_suites.push_back(TLS_FALLBACK_SCSV);

   hash.update(io.send(*this));
   }

/*
* Create a new Client Hello message (session resumption case)
*/
Client_Hello::Client_Hello(Handshake_IO& io,
                           Handshake_Hash& hash,
                           const Policy& policy,
                           RandomNumberGenerator& rng,
                           const std::vector<byte>& reneg_info,
                           const Session& session,
                           const std::vector<std::string>& next_protocols) :
   m_version(session.version()),
   m_session_id(session.session_id()),
   m_random(make_hello_random(rng, policy)),
   m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))),
   m_comp_methods(policy.compression())
   {
   if(!value_exists(m_suites, session.ciphersuite_code()))
      m_suites.push_back(session.ciphersuite_code());

   if(!value_exists(m_comp_methods, session.compression_method()))
      m_comp_methods.push_back(session.compression_method());

   /*
   We always add the EMS extension, even if not used in the original session.
   If the server understands it and follows the RFC it should reject our resume
   attempt and upgrade us to a new session with the EMS protection.
   */
   m_extensions.add(new Extended_Master_Secret);

   m_extensions.add(new Renegotiation_Extension(reneg_info));
   m_extensions.add(new Server_Name_Indicator(session.server_info().hostname()));
   m_extensions.add(new Session_Ticket(session.session_ticket()));
   m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves()));

   if(m_version.supports_negotiable_signature_algorithms())
      m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(),
                                                policy.allowed_signature_methods()));

   if(reneg_info.empty() && !next_protocols.empty())
      m_extensions.add(new Application_Layer_Protocol_Notification(next_protocols));

#if defined(BOTAN_HAS_SRP6)
   m_extensions.add(new SRP_Identifier(session.srp_identifier()));
#else
   if(!session.srp_identifier().empty())
      {
      throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled");
      }
#endif

   hash.update(io.send(*this));
   }

void Client_Hello::update_hello_cookie(const Hello_Verify_Request& hello_verify)
   {
   if(!m_version.is_datagram_protocol())
      throw Exception("Cannot use hello cookie with stream protocol");

   m_hello_cookie = hello_verify.cookie();
   }

/*
* Serialize a Client Hello message
*/
std::vector<byte> Client_Hello::serialize() const
   {
   std::vector<byte> buf;

   buf.push_back(m_version.major_version());
   buf.push_back(m_version.minor_version());
   buf += m_random;

   append_tls_length_value(buf, m_session_id, 1);

   if(m_version.is_datagram_protocol())
      append_tls_length_value(buf, m_hello_cookie, 1);

   append_tls_length_value(buf, m_suites, 2);
   append_tls_length_value(buf, m_comp_methods, 1);

   /*
   * May not want to send extensions at all in some cases. If so,
   * should include SCSV value (if reneg info is empty, if not we are
   * renegotiating with a modern server)
   */

   buf += m_extensions.serialize();

   return buf;
   }

/*
* Read a counterparty client hello
*/
Client_Hello::Client_Hello(const std::vector<byte>& buf)
   {
   if(buf.size() == 0)
      throw Decoding_Error("Client_Hello: Packet corrupted");

   if(buf.size() < 41)
      throw Decoding_Error("Client_Hello: Packet corrupted");

   TLS_Data_Reader reader("ClientHello", buf);

   const byte major_version = reader.get_byte();
   const byte minor_version = reader.get_byte();

   m_version = Protocol_Version(major_version, minor_version);

   m_random = reader.get_fixed<byte>(32);

   m_session_id = reader.get_range<byte>(1, 0, 32);

   if(m_version.is_datagram_protocol())
      m_hello_cookie = reader.get_range<byte>(1, 0, 255);

   m_suites = reader.get_range_vector<u16bit>(2, 1, 32767);

   m_comp_methods = reader.get_range_vector<byte>(1, 1, 255);

   m_extensions.deserialize(reader);

   if(offered_suite(static_cast<u16bit>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)))
      {
      if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>())
         {
         if(!reneg->renegotiation_info().empty())
            throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
                                "Client sent renegotiation SCSV and non-empty extension");
         }
      else
         {
         // add fake extension
         m_extensions.add(new Renegotiation_Extension());
         }
      }
   }

bool Client_Hello::sent_fallback_scsv() const
   {
   return offered_suite(static_cast<u16bit>(TLS_FALLBACK_SCSV));
   }

/*
* Check if we offered this ciphersuite
*/
bool Client_Hello::offered_suite(u16bit ciphersuite) const
   {
   for(size_t i = 0; i != m_suites.size(); ++i)
      if(m_suites[i] == ciphersuite)
         return true;
   return false;
   }

}

}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C グループ・A/D 制御 @n
			Copyright 2015 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/vect.h"
#include "adc.hpp"
#include "intr.hpp"
#include "system.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  A/D 制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class adc_io {

	public:
		enum class cnv_type : uint8_t {
			CH0,		//< チャネル０のみ
			CH1,		//< チャネル１のみ
			CH0_CH1		//< ０，１チャネル
		};

		enum class ch_grp : uint8_t {
			AN0_AN1,	//< AN0, AN1
			AN2_AN3,	//< AN2, AN3
			AN4_AN7		//< AN4, AN7
		};

	private:
		// ※同期が必要なら、実装する
		void sleep_() const {
			asm("nop");
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		adc_io() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	ct		変換タイプ
			@param[in]	grp		グループ
			@param[in]	cycle	繰り返し変換の場合「true」
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
		*/
		//-----------------------------------------------------------------//
		void setup(cnv_type ct, ch_grp cg, bool cycle, uint8_t ir_lvl = 0)
		{
			ADCON0.ADST = 0;

			MSTCR.MSTAD = 0;

			uint8_t md = 0;
			if(ct == cnv_type::CH0_CH1) md = 2;
			if(cycle) ++md;
			ADMOD = ADMOD.CKS.b(3) | ADMOD.MD.b(md);

			uint8_t chn = 0;
			if(ct == cnv_type::CH1) chn = 1;
			ADINSEL = ADINSEL.CH0.b(chn) | ADINSEL.ADGSEL.b(static_cast<uint8_t>(cg));
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	f	変換停止の場合「false」
		*/
		//-----------------------------------------------------------------//
		void start(bool f = 1) {
			ADCON0.ADST = f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了検査
			@return 変換終了なら「true」
		*/
		//-----------------------------------------------------------------//
		bool get_state() const {
			bool f = ADICSR.ADF();
			if(f) ADICSR.ADF = 0;
			return f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了を同期
		*/
		//-----------------------------------------------------------------//
		void sync() const {
			while(!get_state()) sleep_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換結果の取得
			@param[in]	chanel	チャネル（０、１）
			@return 変換結果
		*/
		//-----------------------------------------------------------------//
		uint16_t get_value(bool chanel) const {
			if(chanel) {
				return AD1();
			} else {
				return AD0();
			}
		}
	};
}
<commit_msg>update interrupt<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C グループ・A/D 制御 @n
			Copyright 2015 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/vect.h"
#include "adc.hpp"
#include "intr.hpp"
#include "system.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  A/D 制御クラス
		@param[in]	TASK	A/D 変換終了時起動タスク
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class TASK>
	class adc_io {

		static TASK	task_;
		static volatile uint8_t intr_count_;

	public:
		enum class cnv_type : uint8_t {
			CH0,		//< チャネル０のみ
			CH1,		//< チャネル１のみ
			CH0_CH1		//< ０，１チャネル
		};

		enum class ch_grp : uint8_t {
			AN0_AN1,	//< AN0, AN1
			AN2_AN3,	//< AN2, AN3
			AN4_AN7		//< AN4, AN7
		};

		static INTERRUPT_FUNC void itask() {
			++intr_count_;
			task_();
			// IR 関係フラグは必ず mov 命令で・・
			volatile uint8_t r = ADICSR();
			ADICSR = 0x00;
		}

	private:
		uint8_t	level_;
		uint8_t	count_;

		// ※同期が必要なら、実装する
		void sleep_() const {
			asm("nop");
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		adc_io() : level_(0), count_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	ct		変換タイプ
			@param[in]	grp		グループ
			@param[in]	cycle	繰り返し変換の場合「true」
			@param[in]	level	割り込みレベル（０の場合割り込みを使用しない）
		*/
		//-----------------------------------------------------------------//
		void start(cnv_type ct, ch_grp cg, bool cycle, uint8_t level = 0)
		{
			level_ = level;

			MSTCR.MSTAD = 0;

			ADCON0.ADST = 0;

			uint8_t md = 0;
			if(ct == cnv_type::CH0_CH1) md = 2;
			if(cycle) ++md;
			ADMOD = ADMOD.CKS.b(3) | ADMOD.MD.b(md);

			uint8_t chn = 0;
			if(ct == cnv_type::CH1) chn = 1;
			ADINSEL = ADINSEL.CH0.b(chn) | ADINSEL.ADGSEL.b(static_cast<uint8_t>(cg));

			ILVL7.B01 = level_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	f	変換停止の場合「false」
		*/
		//-----------------------------------------------------------------//
		void scan(bool f = 1) {
			count_ = intr_count_;
			if(f && level_ > 0) {
				ADICSR.ADIE = 1;
			}
			ADCON0.ADST = f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了検査
			@return 変換終了なら「true」
		*/
		//-----------------------------------------------------------------//
		bool get_state() const {
			if(level_ == 0) {
				bool f = ADICSR.ADF();
				if(f) ADICSR.ADF = 0;
				return f;
			} else {
				return count_ != intr_count_;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了を同期
		*/
		//-----------------------------------------------------------------//
		void sync() const {
			while(!get_state()) sleep_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換結果の取得
			@param[in]	chanel	チャネル（０、１）
			@return 変換結果
		*/
		//-----------------------------------------------------------------//
		uint16_t get_value(bool chanel) const {
			if(chanel) {
				return AD1();
			} else {
				return AD0();
			}
		}
	};

	// スタティック実態定義
	template<class TASK>
	TASK adc_io<TASK>::task_;

	template<class TASK>
	volatile uint8_t adc_io<TASK>::intr_count_ = 0;
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C グループ・A/D 制御 @n
			Copyright 2015 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/vect.h"
#include "adc.hpp"
#include "intr.hpp"
#include "system.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  A/D 制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class adc_io {

	public:
		enum class cnv_type : uint8_t {
			CH0,		//< チャネル０のみ
			CH1,		//< チャネル１のみ
			CH0_CH1		//< ０，１チャネル
		};

		enum class ch_grp : uint8_t {
			AN0_AN1,	//< AN0, AN1
			AN2_AN3,	//< AN2, AN3
			AN4_AN7		//< AN4, AN7
		};

	private:
		// ※同期が必要なら、実装する
		void sleep_() const {
			asm("nop");
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		adc_io() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	ct		変換タイプ
			@param[in]	grp		グループ
			@param[in]	cycle	繰り返し変換の場合「true」
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
		*/
		//-----------------------------------------------------------------//
		void setup(cnv_type ct, ch_grp cg, bool cycle, uint8_t ir_lvl = 0)
		{
			ADCON0.ADST = 0;

			MSTCR.MSTAD = 0;

			uint8_t md = 0;
			if(ct == cnv_type::CH0_CH1) md = 2;
			if(cycle) ++md;
			ADMOD = ADMOD.CKS.b(3) | ADMOD.MD.b(md);

			uint8_t chn = 0;
			if(ct == cnv_type::CH1) chn = 1;
			ADINSEL = ADINSEL.CH0.b(chn) | ADINSEL.ADGSEL.b(static_cast<uint8_t>(cg));
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	f	変換停止の場合「false」
		*/
		//-----------------------------------------------------------------//
		void start(bool f = 1) {
			ADCON0.ADST = f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了検査
			@return 変換終了なら「true」
		*/
		//-----------------------------------------------------------------//
		bool get_state() const {
			bool f = ADICSR.ADF();
			if(f) ADICSR.ADF = 0;
			return f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了を同期
		*/
		//-----------------------------------------------------------------//
		void sync() const {
			while(!get_state()) sleep_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換結果の取得
			@param[in]	chanel	チャネル（０、１）
			@return 変換結果
		*/
		//-----------------------------------------------------------------//
		uint16_t get_value(uint8_t chanel) const {
			if(chanel) {
				return AD1();
			} else {
				return AD0();
			}
		}
	};
}
<commit_msg>update chanel selector<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	R8C グループ・A/D 制御 @n
			Copyright 2015 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/vect.h"
#include "adc.hpp"
#include "intr.hpp"
#include "system.hpp"

namespace device {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  A/D 制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class adc_io {

	public:
		enum class cnv_type : uint8_t {
			CH0,		//< チャネル０のみ
			CH1,		//< チャネル１のみ
			CH0_CH1		//< ０，１チャネル
		};

		enum class ch_grp : uint8_t {
			AN0_AN1,	//< AN0, AN1
			AN2_AN3,	//< AN2, AN3
			AN4_AN7		//< AN4, AN7
		};

	private:
		// ※同期が必要なら、実装する
		void sleep_() const {
			asm("nop");
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		adc_io() { }

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	ct		変換タイプ
			@param[in]	grp		グループ
			@param[in]	cycle	繰り返し変換の場合「true」
			@param[in]	ir_lvl	割り込みレベル（０の場合割り込みを使用しない）
		*/
		//-----------------------------------------------------------------//
		void setup(cnv_type ct, ch_grp cg, bool cycle, uint8_t ir_lvl = 0)
		{
			ADCON0.ADST = 0;

			MSTCR.MSTAD = 0;

			uint8_t md = 0;
			if(ct == cnv_type::CH0_CH1) md = 2;
			if(cycle) ++md;
			ADMOD = ADMOD.CKS.b(3) | ADMOD.MD.b(md);

			uint8_t chn = 0;
			if(ct == cnv_type::CH1) chn = 1;
			ADINSEL = ADINSEL.CH0.b(chn) | ADINSEL.ADGSEL.b(static_cast<uint8_t>(cg));
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換開始
			@param[in]	f	変換停止の場合「false」
		*/
		//-----------------------------------------------------------------//
		void start(bool f = 1) {
			ADCON0.ADST = f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了検査
			@return 変換終了なら「true」
		*/
		//-----------------------------------------------------------------//
		bool get_state() const {
			bool f = ADICSR.ADF();
			if(f) ADICSR.ADF = 0;
			return f;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換終了を同期
		*/
		//-----------------------------------------------------------------//
		void sync() const {
			while(!get_state()) sleep_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  変換結果の取得
			@param[in]	chanel	チャネル（０、１）
			@return 変換結果
		*/
		//-----------------------------------------------------------------//
		uint16_t get_value(bool chanel) const {
			if(chanel) {
				return AD1();
			} else {
				return AD0();
			}
		}
	};
}
<|endoftext|>


<commit_before>#include "qmljsoutline.h"
#include "qmloutlinemodel.h"

#include <coreplugin/icore.h>
#include <coreplugin/ifile.h>
#include <coreplugin/editormanager/editormanager.h>

#include <QtCore/QDebug>
#include <QtCore/QSettings>
#include <QtGui/QAction>
#include <QtGui/QVBoxLayout>

using namespace QmlJS;

enum {
    debug = false
};

namespace QmlJSEditor {
namespace Internal {

QmlJSOutlineTreeView::QmlJSOutlineTreeView(QWidget *parent) :
    Utils::NavigationTreeView(parent)
{
    // see also CppOutlineTreeView
    setFocusPolicy(Qt::NoFocus);
    setExpandsOnDoubleClick(false);

    setDragEnabled(true);
    viewport()->setAcceptDrops(true);
    setDropIndicatorShown(true);
    setDragDropMode(InternalMove);
}

QmlJSOutlineFilterModel::QmlJSOutlineFilterModel(QObject *parent) :
    QSortFilterProxyModel(parent)
{
}

bool QmlJSOutlineFilterModel::filterAcceptsRow(int sourceRow,
                                               const QModelIndex &sourceParent) const
{
    if (m_filterBindings) {
        QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
        QVariant itemType = sourceIndex.data(QmlOutlineModel::ItemTypeRole);
        Q_ASSERT(itemType.isValid());
        if (itemType.isValid() && itemType == QmlOutlineModel::PropertyType) {
            return false;
        }
    }
    return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}

bool QmlJSOutlineFilterModel::filterBindings() const
{
    return m_filterBindings;
}

void QmlJSOutlineFilterModel::setFilterBindings(bool filterBindings)
{
    m_filterBindings = filterBindings;
    invalidateFilter();
}

QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent) :
    TextEditor::IOutlineWidget(parent),
    m_treeView(new QmlJSOutlineTreeView(this)),
    m_filterModel(new QmlJSOutlineFilterModel(this)),
    m_enableCursorSync(true),
    m_blockCursorSync(false)
{
    m_filterModel->setFilterBindings(false);

    m_treeView->setModel(m_filterModel);

    QVBoxLayout *layout = new QVBoxLayout;

    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addWidget(m_treeView);

    m_showBindingsAction = new QAction(this);
    m_showBindingsAction->setText(tr("Show bindings"));
    m_showBindingsAction->setCheckable(true);
    m_showBindingsAction->setChecked(true);
    connect(m_showBindingsAction, SIGNAL(toggled(bool)), this, SLOT(setShowBindings(bool)));

    setLayout(layout);
}

void QmlJSOutlineWidget::setEditor(QmlJSTextEditor *editor)
{
    m_editor = editor;

    m_filterModel->setSourceModel(m_editor.data()->outlineModel());
    modelUpdated();

    connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(updateSelectionInText(QItemSelection)));

    connect(m_editor.data(), SIGNAL(outlineModelIndexChanged(QModelIndex)),
            this, SLOT(updateSelectionInTree(QModelIndex)));
    connect(m_editor.data()->outlineModel(), SIGNAL(updated()),
            this, SLOT(modelUpdated()));
}

QList<QAction*> QmlJSOutlineWidget::filterMenuActions() const
{
    QList<QAction*> list;
    list.append(m_showBindingsAction);
    return list;
}

void QmlJSOutlineWidget::setCursorSynchronization(bool syncWithCursor)
{
    m_enableCursorSync = syncWithCursor;
    if (m_enableCursorSync)
        updateSelectionInTree(m_editor.data()->outlineModelIndex());
}

void QmlJSOutlineWidget::restoreSettings(int position)
{
    QSettings *settings = Core::ICore::instance()->settings();
    bool showBindings = settings->value("QmlJSOutline."+QString::number(position)+".ShowBindings", true).toBool();
    m_showBindingsAction->setChecked(showBindings);
}

void QmlJSOutlineWidget::saveSettings(int position)
{
    QSettings *settings = Core::ICore::instance()->settings();
    settings->setValue("QmlJSOutline."+QString::number(position)+".ShowBindings",
                       m_showBindingsAction->isChecked());
}

void QmlJSOutlineWidget::modelUpdated()
{
    m_treeView->expandAll();
}

void QmlJSOutlineWidget::updateSelectionInTree(const QModelIndex &index)
{
    if (!syncCursor())
        return;

    m_blockCursorSync = true;
    m_treeView->selectionModel()->select(m_filterModel->mapFromSource(index), QItemSelectionModel::ClearAndSelect);
    m_treeView->scrollTo(index);
    m_blockCursorSync = false;
}

void QmlJSOutlineWidget::updateSelectionInText(const QItemSelection &selection)
{
    if (!syncCursor())
        return;

    if (!selection.indexes().isEmpty()) {
        QModelIndex index = selection.indexes().first();
        AST::SourceLocation location = index.data(QmlOutlineModel::SourceLocationRole).value<AST::SourceLocation>();

        Core::EditorManager *editorManager = Core::EditorManager::instance();
        editorManager->cutForwardNavigationHistory();
        editorManager->addCurrentPositionToNavigationHistory();

        QTextCursor textCursor = m_editor.data()->textCursor();
        m_blockCursorSync = true;
        textCursor.setPosition(location.offset);
        m_editor.data()->setTextCursor(textCursor);
        m_blockCursorSync = false;
    }
}

void QmlJSOutlineWidget::setShowBindings(bool showBindings)
{
    m_filterModel->setFilterBindings(!showBindings);
    modelUpdated();
}

bool QmlJSOutlineWidget::syncCursor()
{
    return m_enableCursorSync && !m_blockCursorSync;
}

bool QmlJSOutlineWidgetFactory::supportsEditor(Core::IEditor *editor) const
{
    if (qobject_cast<QmlJSEditorEditable*>(editor))
        return true;
    return false;
}

TextEditor::IOutlineWidget *QmlJSOutlineWidgetFactory::createWidget(Core::IEditor *editor)
{
    QmlJSOutlineWidget *widget = new QmlJSOutlineWidget;

    QmlJSEditorEditable *qmlJSEditable = qobject_cast<QmlJSEditorEditable*>(editor);
    QmlJSTextEditor *qmlJSEditor = qobject_cast<QmlJSTextEditor*>(qmlJSEditable->widget());
    Q_ASSERT(qmlJSEditor);

    widget->setEditor(qmlJSEditor);

    return widget;
}

} // namespace Internal
} // namespace QmlJSEditor
<commit_msg>QmlOutline: Fix issues when 'filter bindings' is activated<commit_after>#include "qmljsoutline.h"
#include "qmloutlinemodel.h"

#include <coreplugin/icore.h>
#include <coreplugin/ifile.h>
#include <coreplugin/editormanager/editormanager.h>

#include <QtCore/QDebug>
#include <QtCore/QSettings>
#include <QtGui/QAction>
#include <QtGui/QVBoxLayout>

using namespace QmlJS;

enum {
    debug = false
};

namespace QmlJSEditor {
namespace Internal {

QmlJSOutlineTreeView::QmlJSOutlineTreeView(QWidget *parent) :
    Utils::NavigationTreeView(parent)
{
    // see also CppOutlineTreeView
    setFocusPolicy(Qt::NoFocus);
    setExpandsOnDoubleClick(false);

    setDragEnabled(true);
    viewport()->setAcceptDrops(true);
    setDropIndicatorShown(true);
    setDragDropMode(InternalMove);
}

QmlJSOutlineFilterModel::QmlJSOutlineFilterModel(QObject *parent) :
    QSortFilterProxyModel(parent)
{
    setDynamicSortFilter(true);
}

bool QmlJSOutlineFilterModel::filterAcceptsRow(int sourceRow,
                                               const QModelIndex &sourceParent) const
{
    if (m_filterBindings) {
        QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
        QVariant itemType = sourceIndex.data(QmlOutlineModel::ItemTypeRole);
        Q_ASSERT(itemType.isValid());
        if (itemType.isValid() && itemType == QmlOutlineModel::PropertyType) {
            return false;
        }
    }
    return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}

bool QmlJSOutlineFilterModel::filterBindings() const
{
    return m_filterBindings;
}

void QmlJSOutlineFilterModel::setFilterBindings(bool filterBindings)
{
    m_filterBindings = filterBindings;
    invalidateFilter();
}

QmlJSOutlineWidget::QmlJSOutlineWidget(QWidget *parent) :
    TextEditor::IOutlineWidget(parent),
    m_treeView(new QmlJSOutlineTreeView(this)),
    m_filterModel(new QmlJSOutlineFilterModel(this)),
    m_enableCursorSync(true),
    m_blockCursorSync(false)
{
    m_filterModel->setFilterBindings(false);

    m_treeView->setModel(m_filterModel);

    QVBoxLayout *layout = new QVBoxLayout;

    layout->setMargin(0);
    layout->setSpacing(0);
    layout->addWidget(m_treeView);

    m_showBindingsAction = new QAction(this);
    m_showBindingsAction->setText(tr("Show bindings"));
    m_showBindingsAction->setCheckable(true);
    m_showBindingsAction->setChecked(true);
    connect(m_showBindingsAction, SIGNAL(toggled(bool)), this, SLOT(setShowBindings(bool)));

    setLayout(layout);
}

void QmlJSOutlineWidget::setEditor(QmlJSTextEditor *editor)
{
    m_editor = editor;

    m_filterModel->setSourceModel(m_editor.data()->outlineModel());
    modelUpdated();

    connect(m_treeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(updateSelectionInText(QItemSelection)));

    connect(m_editor.data(), SIGNAL(outlineModelIndexChanged(QModelIndex)),
            this, SLOT(updateSelectionInTree(QModelIndex)));
    connect(m_editor.data()->outlineModel(), SIGNAL(updated()),
            this, SLOT(modelUpdated()));
}

QList<QAction*> QmlJSOutlineWidget::filterMenuActions() const
{
    QList<QAction*> list;
    list.append(m_showBindingsAction);
    return list;
}

void QmlJSOutlineWidget::setCursorSynchronization(bool syncWithCursor)
{
    m_enableCursorSync = syncWithCursor;
    if (m_enableCursorSync)
        updateSelectionInTree(m_editor.data()->outlineModelIndex());
}

void QmlJSOutlineWidget::restoreSettings(int position)
{
    QSettings *settings = Core::ICore::instance()->settings();
    bool showBindings = settings->value("QmlJSOutline."+QString::number(position)+".ShowBindings", true).toBool();
    m_showBindingsAction->setChecked(showBindings);
}

void QmlJSOutlineWidget::saveSettings(int position)
{
    QSettings *settings = Core::ICore::instance()->settings();
    settings->setValue("QmlJSOutline."+QString::number(position)+".ShowBindings",
                       m_showBindingsAction->isChecked());
}

void QmlJSOutlineWidget::modelUpdated()
{
    m_treeView->expandAll();
}

void QmlJSOutlineWidget::updateSelectionInTree(const QModelIndex &index)
{
    if (!syncCursor())
        return;

    m_blockCursorSync = true;
    m_treeView->selectionModel()->select(m_filterModel->mapFromSource(index), QItemSelectionModel::ClearAndSelect);
    m_treeView->scrollTo(index);
    m_blockCursorSync = false;
}

void QmlJSOutlineWidget::updateSelectionInText(const QItemSelection &selection)
{
    if (!syncCursor())
        return;

    if (!selection.indexes().isEmpty()) {
        QModelIndex index = selection.indexes().first();
        AST::SourceLocation location = index.data(QmlOutlineModel::SourceLocationRole).value<AST::SourceLocation>();

        Core::EditorManager *editorManager = Core::EditorManager::instance();
        editorManager->cutForwardNavigationHistory();
        editorManager->addCurrentPositionToNavigationHistory();

        QTextCursor textCursor = m_editor.data()->textCursor();
        m_blockCursorSync = true;
        textCursor.setPosition(location.offset);
        m_editor.data()->setTextCursor(textCursor);
        m_blockCursorSync = false;
    }
}

void QmlJSOutlineWidget::setShowBindings(bool showBindings)
{
    m_filterModel->setFilterBindings(!showBindings);
    modelUpdated();
}

bool QmlJSOutlineWidget::syncCursor()
{
    return m_enableCursorSync && !m_blockCursorSync;
}

bool QmlJSOutlineWidgetFactory::supportsEditor(Core::IEditor *editor) const
{
    if (qobject_cast<QmlJSEditorEditable*>(editor))
        return true;
    return false;
}

TextEditor::IOutlineWidget *QmlJSOutlineWidgetFactory::createWidget(Core::IEditor *editor)
{
    QmlJSOutlineWidget *widget = new QmlJSOutlineWidget;

    QmlJSEditorEditable *qmlJSEditable = qobject_cast<QmlJSEditorEditable*>(editor);
    QmlJSTextEditor *qmlJSEditor = qobject_cast<QmlJSTextEditor*>(qmlJSEditable->widget());
    Q_ASSERT(qmlJSEditor);

    widget->setEditor(qmlJSEditor);

    return widget;
}

} // namespace Internal
} // namespace QmlJSEditor
<|endoftext|>