<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "common.h"

// implementation header
#include "CacheManager.h"

// system headers
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _WIN32
#  include <unistd.h>
#endif

// common headers
#include "md5.h"
#include "bzfio.h"
#include "TextUtils.h"
#include "FileManager.h"
#include "StateDatabase.h"
#include "DirectoryNames.h"

// function prototypes
static bool fileExists(const std::string& name);
static void removeDirs(const std::string& path);
static void removeNewlines(char* c);
static std::string partialEncoding(const std::string& string);
static bool compareUsedDate(const CacheManager::CacheRecord& a,
			    const CacheManager::CacheRecord& b);

CacheManager CACHEMGR;

CacheManager::CacheManager()
{
  indexName = getCacheDirName();
  indexName += "CacheIndex.txt";
  return;
}

CacheManager::~CacheManager()
{
  return;
}

bool CacheManager::isCacheFileType(const std::string name) const
{
  if (strncasecmp(name.c_str(), "http://", 7) == 0) {
    return true;
  }
  if (strncasecmp(name.c_str(), "ftp://", 6) == 0) {
    return true;
  }
  return false;
}

std::string CacheManager::getLocalName(const std::string name) const
{
  std::string local = "";
  if (strncasecmp(name.c_str(), "http://", 7) == 0) {
    local = getCacheDirName() + "http/";
    local += partialEncoding(name.substr(7));
  }
  else if (strncasecmp(name.c_str(), "ftp://", 6) == 0) {
    local = getCacheDirName() + "ftp/";
    local += partialEncoding(name.substr(6));
  }
#ifdef _WIN32
  std::replace(local.begin(), local.end(), '/', '\\');
#endif
  return local;
}

bool CacheManager::findURL(const std::string& url, CacheRecord& record)
{
  int pos = findRecord(url);
  if (pos >= 0) {
    CacheRecord* rec = &records[pos];
    rec->usedDate = time(NULL); // update the timestamp
    record = *rec;
    return true;
  }
  return false;
}

bool CacheManager::addFile(CacheRecord& record, const void* data)
{
  if (((data == NULL) && (record.size != 0)) || (record.url.size() <= 0)) {
    return false;
  }

  record.name = getLocalName(record.url);
  std::ostream* out = FILEMGR.createDataOutStream(record.name);
  if (out == NULL) {
    return false;
  }

  bool replacement = false;
  CacheRecord* rec = &record;

  int pos = findRecord(record.url);
  if (pos >= 0) {
    records[pos] = record;
    rec = &records[pos];
    replacement = true;
  }

  out->write((char*)data, rec->size);

  rec->usedDate = time(NULL); // update the timestamp

  MD5 md5;
  md5.update((unsigned char *)data, rec->size);
  md5.finalize();
  rec->key = md5.hexdigest();

  if (!replacement) {
    records.push_back(*rec);
  }

  delete out;
  return true;
}

int CacheManager::findRecord(const std::string& url)
{
  for (unsigned int i = 0; i < records.size(); i++) {
    CacheRecord* rec = &(records[i]);
    if (url == rec->url) {
      return i;
    }
  }
  return -1;
}

bool CacheManager::loadIndex()
{
  records.clear();

  FILE* file = fopen(indexName.c_str(), "r");
  if (file == NULL) {
    return false;
  }

  char buffer[1024];
  while (fgets(buffer, 1024, file) != NULL) {
    removeNewlines(buffer);
    if ((buffer[0] == '\0') || (buffer[0] == '#')) {
      continue;
    }

    CacheRecord rec;
    rec.url = buffer;
    rec.name = getLocalName(rec.url);

    if (fgets(buffer, 1024, file) == NULL) {
      break;
    } else {
      removeNewlines(buffer);
    }
    std::string line = buffer;
    std::vector<std::string> tokens = TextUtils::tokenize(line, " ");
    if (tokens.size() != 4) {
      DEBUG1("loadCacheIndex (bad line): %s\n", buffer);
      continue;
    }
    rec.size = strtoul(tokens[0].c_str(), NULL, 10);
    rec.date = strtoul(tokens[1].c_str(), NULL, 10);
    rec.usedDate = strtoul(tokens[2].c_str(), NULL, 10);
    rec.key = tokens[3];
    if (fileExists(rec.name)) {
      records.push_back(rec);
    }
  }

  fclose(file);
  return true;
}

bool CacheManager::saveIndex()
{
  std::sort(records.begin(), records.end(), compareUsedDate);

  std::string tmpIndexName = indexName + ".tmp";

  FILE* file = fopen(tmpIndexName.c_str(), "w");
  if (file == NULL) {
    return false;
  }

  for (unsigned int i = 0; i < records.size(); i++) {
    const CacheRecord& rec = records[i];
    fprintf(file, "%s\n%u %lu %lu %s\n\n", rec.url.c_str(),
	    rec.size, rec.date, rec.usedDate, rec.key.c_str());
  }

  fclose(file);

  return (rename(tmpIndexName.c_str(), indexName.c_str()) == 0);
}

void CacheManager::limitCacheSize()
{
  int maxSize = BZDB.evalInt("maxCacheMB") * 1024 * 1024;
  if (maxSize < 0) {
    maxSize = 0;
  }

  int currentSize = 0;
  for (unsigned int i = 0; i < records.size(); i++) {
    currentSize += records[i].size;
  }

  std::sort(records.begin(), records.end(), compareUsedDate);

  while ((currentSize > maxSize) && (records.size() > 0)) {
    CacheManager::CacheRecord& rec = records.back();
    currentSize -= rec.size;
    remove(rec.name.c_str());
    removeDirs(rec.name);
    records.pop_back();
  }

  return;
}

std::vector<CacheManager::CacheRecord> CacheManager::getCacheList() const
{
  return records;
}

static bool fileExists (const std::string& name)
{
  struct stat buf;
#ifndef _WIN32
  return (stat(name.c_str(), &buf) == 0);
#else
  // Windows sucks yet again, if there is a trailing  "\"
  // at the end of the filename, _stat will return -1.
  std::string dirname = name;
  while (dirname.find_last_of('\\') == (dirname.size() - 1)) {
    dirname.resize(dirname.size() - 1);
  }
  return (_stat(dirname.c_str(), (struct _stat *) &buf) == 0);
#endif
}

static void removeDirs(const std::string& path)
{
  unsigned int minLen = (unsigned int)getConfigDirName().size();
  std::string tmp = path;
  while (tmp.size() > minLen) {
#ifndef _WIN32
    unsigned int i = (unsigned int)tmp.find_last_of('/');
#else
    unsigned int i = (unsigned int)tmp.find_last_of('\\');
#endif
    tmp = tmp.substr(0, i);
    if (remove(tmp.c_str()) != 0) {
      break;
    }
  }
  return;
}

static void removeNewlines(char* c)
{
  while (*c != '\0') {
    if ((*c == '\n') || (*c == '\r')) {
      *c = '\0';
    }
    c++;
  }
  return;
}

static std::string partialEncoding(const std::string& string)
{
  // URL encoding removes the '/' and '.', which is
  // not acceptable. It is nice to have the directory
  // structure, and to be able to point and click your
  // way through it to view ".png"s.
  std::string tmp;
  char hex[5];
  for (unsigned int i = 0; i < string.size(); i++) {
    const char c = string[i];
    if (TextUtils::isWhitespace(c)) {
      tmp += "%20";
    }
    else if ((c == '%') || (c == '*') || (c == '?') ||
	     (c == ':') || (c == '"') || (c == '\\')) {
      tmp += '%';
      sprintf(hex, "%-2.2X", c);
      tmp += hex;
    }
    else {
      tmp += c;
    }
  }
  return tmp;
}

static bool compareUsedDate(const CacheManager::CacheRecord& a,
			    const CacheManager::CacheRecord& b)
{
  // oldest last
  return (a.usedDate > b.usedDate);
}

/*
 * Local Variables: ***
 * mode:C ***
 * tab-width: 8 ***
 * c-basic-offset: 2 ***
 * indent-tabs-mode: t ***
 * End: ***
 * ex: shiftwidth=2 tabstop=8
 */
<commit_msg>don't include <string> twice, use <string.h><commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "common.h"

// implementation header
#include "CacheManager.h"

// system headers
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _WIN32
#  include <unistd.h>
#endif

// common headers
#include "md5.h"
#include "bzfio.h"
#include "TextUtils.h"
#include "FileManager.h"
#include "StateDatabase.h"
#include "DirectoryNames.h"

// function prototypes
static bool fileExists(const std::string& name);
static void removeDirs(const std::string& path);
static void removeNewlines(char* c);
static std::string partialEncoding(const std::string& string);
static bool compareUsedDate(const CacheManager::CacheRecord& a,
			    const CacheManager::CacheRecord& b);

CacheManager CACHEMGR;

CacheManager::CacheManager()
{
  indexName = getCacheDirName();
  indexName += "CacheIndex.txt";
  return;
}

CacheManager::~CacheManager()
{
  return;
}

bool CacheManager::isCacheFileType(const std::string name) const
{
  if (strncasecmp(name.c_str(), "http://", 7) == 0) {
    return true;
  }
  if (strncasecmp(name.c_str(), "ftp://", 6) == 0) {
    return true;
  }
  return false;
}

std::string CacheManager::getLocalName(const std::string name) const
{
  std::string local = "";
  if (strncasecmp(name.c_str(), "http://", 7) == 0) {
    local = getCacheDirName() + "http/";
    local += partialEncoding(name.substr(7));
  }
  else if (strncasecmp(name.c_str(), "ftp://", 6) == 0) {
    local = getCacheDirName() + "ftp/";
    local += partialEncoding(name.substr(6));
  }
#ifdef _WIN32
  std::replace(local.begin(), local.end(), '/', '\\');
#endif
  return local;
}

bool CacheManager::findURL(const std::string& url, CacheRecord& record)
{
  int pos = findRecord(url);
  if (pos >= 0) {
    CacheRecord* rec = &records[pos];
    rec->usedDate = time(NULL); // update the timestamp
    record = *rec;
    return true;
  }
  return false;
}

bool CacheManager::addFile(CacheRecord& record, const void* data)
{
  if (((data == NULL) && (record.size != 0)) || (record.url.size() <= 0)) {
    return false;
  }

  record.name = getLocalName(record.url);
  std::ostream* out = FILEMGR.createDataOutStream(record.name);
  if (out == NULL) {
    return false;
  }

  bool replacement = false;
  CacheRecord* rec = &record;

  int pos = findRecord(record.url);
  if (pos >= 0) {
    records[pos] = record;
    rec = &records[pos];
    replacement = true;
  }

  out->write((char*)data, rec->size);

  rec->usedDate = time(NULL); // update the timestamp

  MD5 md5;
  md5.update((unsigned char *)data, rec->size);
  md5.finalize();
  rec->key = md5.hexdigest();

  if (!replacement) {
    records.push_back(*rec);
  }

  delete out;
  return true;
}

int CacheManager::findRecord(const std::string& url)
{
  for (unsigned int i = 0; i < records.size(); i++) {
    CacheRecord* rec = &(records[i]);
    if (url == rec->url) {
      return i;
    }
  }
  return -1;
}

bool CacheManager::loadIndex()
{
  records.clear();

  FILE* file = fopen(indexName.c_str(), "r");
  if (file == NULL) {
    return false;
  }

  char buffer[1024];
  while (fgets(buffer, 1024, file) != NULL) {
    removeNewlines(buffer);
    if ((buffer[0] == '\0') || (buffer[0] == '#')) {
      continue;
    }

    CacheRecord rec;
    rec.url = buffer;
    rec.name = getLocalName(rec.url);

    if (fgets(buffer, 1024, file) == NULL) {
      break;
    } else {
      removeNewlines(buffer);
    }
    std::string line = buffer;
    std::vector<std::string> tokens = TextUtils::tokenize(line, " ");
    if (tokens.size() != 4) {
      DEBUG1("loadCacheIndex (bad line): %s\n", buffer);
      continue;
    }
    rec.size = strtoul(tokens[0].c_str(), NULL, 10);
    rec.date = strtoul(tokens[1].c_str(), NULL, 10);
    rec.usedDate = strtoul(tokens[2].c_str(), NULL, 10);
    rec.key = tokens[3];
    if (fileExists(rec.name)) {
      records.push_back(rec);
    }
  }

  fclose(file);
  return true;
}

bool CacheManager::saveIndex()
{
  std::sort(records.begin(), records.end(), compareUsedDate);

  std::string tmpIndexName = indexName + ".tmp";

  FILE* file = fopen(tmpIndexName.c_str(), "w");
  if (file == NULL) {
    return false;
  }

  for (unsigned int i = 0; i < records.size(); i++) {
    const CacheRecord& rec = records[i];
    fprintf(file, "%s\n%u %lu %lu %s\n\n", rec.url.c_str(),
	    rec.size, rec.date, rec.usedDate, rec.key.c_str());
  }

  fclose(file);

  return (rename(tmpIndexName.c_str(), indexName.c_str()) == 0);
}

void CacheManager::limitCacheSize()
{
  int maxSize = BZDB.evalInt("maxCacheMB") * 1024 * 1024;
  if (maxSize < 0) {
    maxSize = 0;
  }

  int currentSize = 0;
  for (unsigned int i = 0; i < records.size(); i++) {
    currentSize += records[i].size;
  }

  std::sort(records.begin(), records.end(), compareUsedDate);

  while ((currentSize > maxSize) && (records.size() > 0)) {
    CacheManager::CacheRecord& rec = records.back();
    currentSize -= rec.size;
    remove(rec.name.c_str());
    removeDirs(rec.name);
    records.pop_back();
  }

  return;
}

std::vector<CacheManager::CacheRecord> CacheManager::getCacheList() const
{
  return records;
}

static bool fileExists (const std::string& name)
{
  struct stat buf;
#ifndef _WIN32
  return (stat(name.c_str(), &buf) == 0);
#else
  // Windows sucks yet again, if there is a trailing  "\"
  // at the end of the filename, _stat will return -1.
  std::string dirname = name;
  while (dirname.find_last_of('\\') == (dirname.size() - 1)) {
    dirname.resize(dirname.size() - 1);
  }
  return (_stat(dirname.c_str(), (struct _stat *) &buf) == 0);
#endif
}

static void removeDirs(const std::string& path)
{
  unsigned int minLen = (unsigned int)getConfigDirName().size();
  std::string tmp = path;
  while (tmp.size() > minLen) {
#ifndef _WIN32
    unsigned int i = (unsigned int)tmp.find_last_of('/');
#else
    unsigned int i = (unsigned int)tmp.find_last_of('\\');
#endif
    tmp = tmp.substr(0, i);
    if (remove(tmp.c_str()) != 0) {
      break;
    }
  }
  return;
}

static void removeNewlines(char* c)
{
  while (*c != '\0') {
    if ((*c == '\n') || (*c == '\r')) {
      *c = '\0';
    }
    c++;
  }
  return;
}

static std::string partialEncoding(const std::string& string)
{
  // URL encoding removes the '/' and '.', which is
  // not acceptable. It is nice to have the directory
  // structure, and to be able to point and click your
  // way through it to view ".png"s.
  std::string tmp;
  char hex[5];
  for (unsigned int i = 0; i < string.size(); i++) {
    const char c = string[i];
    if (TextUtils::isWhitespace(c)) {
      tmp += "%20";
    }
    else if ((c == '%') || (c == '*') || (c == '?') ||
	     (c == ':') || (c == '"') || (c == '\\')) {
      tmp += '%';
      sprintf(hex, "%-2.2X", c);
      tmp += hex;
    }
    else {
      tmp += c;
    }
  }
  return tmp;
}

static bool compareUsedDate(const CacheManager::CacheRecord& a,
			    const CacheManager::CacheRecord& b)
{
  // oldest last
  return (a.usedDate > b.usedDate);
}

/*
 * Local Variables: ***
 * mode:C ***
 * tab-width: 8 ***
 * c-basic-offset: 2 ***
 * indent-tabs-mode: t ***
 * End: ***
 * ex: shiftwidth=2 tabstop=8
 */
<|endoftext|>


<commit_before>#include "ge/material_asset.hpp"

#include "ge/shader_asset.hpp"
#include "ge/texture_asset.hpp"

namespace ge
{
struct reassign_from_json_visitor : boost::static_visitor<shader::parameter_type> {
	reassign_from_json_visitor(const nlohmann::json& js, asset_manager& asset_man_arg)
		: json_obj{js}, asset_man{asset_man_arg}
	{
	}
	const nlohmann::json& json_obj;
	asset_manager& asset_man;

	shader::parameter_type operator()(float) { return (float)json_obj; }
	shader::parameter_type operator()(glm::vec2) { return glm::vec2{json_obj[0], json_obj[1]}; }
	shader::parameter_type operator()(glm::vec3)
	{
		return glm::vec3{json_obj[0], json_obj[1], json_obj[2]};
	}

	shader::parameter_type operator()(glm::vec4)
	{
		return glm::vec4{json_obj[0], json_obj[1], json_obj[2], json_obj[3]};
	}

	shader::parameter_type operator()(std::shared_ptr<texture>&)
	{
		std::string asset_path = json_obj;
		return asset_man.get_asset<texture_asset>(asset_path.c_str());
	}
};

material material_asset::load_asset(asset_manager& manager, const char* asset_name,
	const char* filepath, const nlohmann::json& json_data)
{
	std::string shader_asset_name = json_data["shader"];
	auto shader_ass = manager.get_asset<shader_asset>(shader_asset_name.c_str());

	auto ret = material(shader_ass);

	// load parameters
	auto parameter_iter = json_data.find("parameters");
	if (parameter_iter != json_data.end() && parameter_iter->is_array()) {
		for (auto& parameter : *parameter_iter) {
			std::string parameter_name = parameter["name"];
			// get the type from the shader
			auto paramater_iter = ret.m_shader->parameters.find(parameter_name);
			if (parameter_iter == ret.m_shader->parameters.end()) {
				throw std::runtime_error("Could not find property: " + parameter_name +
										 " in shader while loading material asset: " + asset_name);
			}
			auto default_value = *parameter_iter;

			reassign_from_json_visitor vis{parameter["value"], manager};

			try {
				ret.property_values[parameter_name] = default_value.apply_visitor(vis);
			} catch (std::exception& e) {
				std::cerr << "ERROR THROWN: " << e.what() << std::endl;
			}
		}
	}
	return ret;
}
}
<commit_msg>Fix material_asset issue<commit_after>#include "ge/material_asset.hpp"

#include "ge/shader_asset.hpp"
#include "ge/texture_asset.hpp"

namespace ge
{
struct reassign_from_json_visitor : boost::static_visitor<shader::parameter_type> {
	reassign_from_json_visitor(const nlohmann::json& js, asset_manager& asset_man_arg)
		: json_obj{js}, asset_man{asset_man_arg}
	{
	}
	const nlohmann::json& json_obj;
	asset_manager& asset_man;

	shader::parameter_type operator()(float) { return (float)json_obj; }
	shader::parameter_type operator()(glm::vec2) { return glm::vec2{json_obj[0], json_obj[1]}; }
	shader::parameter_type operator()(glm::vec3)
	{
		return glm::vec3{json_obj[0], json_obj[1], json_obj[2]};
	}

	shader::parameter_type operator()(glm::vec4)
	{
		return glm::vec4{json_obj[0], json_obj[1], json_obj[2], json_obj[3]};
	}

	shader::parameter_type operator()(std::shared_ptr<texture>&)
	{
		std::string asset_path = json_obj;
		return asset_man.get_asset<texture_asset>(asset_path.c_str());
	}
};

material material_asset::load_asset(asset_manager& manager, const char* asset_name,
	const char* filepath, const nlohmann::json& json_data)
{
	std::string shader_asset_name = json_data["shader"];
	auto shader_ass = manager.get_asset<shader_asset>(shader_asset_name.c_str());

	auto ret = material(shader_ass);

	// load parameters
	auto parameter_iter = json_data.find("parameters");
	if (parameter_iter != json_data.end() && parameter_iter->is_array()) {
		for (auto& parameter : *parameter_iter) {
			std::string parameter_name = parameter["name"];
			// get the type from the shader
			auto default_paramater_iter = ret.m_shader->parameters.find(parameter_name);
			if (default_paramater_iter  == ret.m_shader->parameters.end()) {
				throw std::runtime_error("Could not find property: " + parameter_name +
										 " in shader while loading material asset: " + asset_name);
			}
			auto default_value = default_paramater_iter->second.value;

			reassign_from_json_visitor vis{parameter["value"], manager};

			try {
				ret.property_values[parameter_name] = default_value.apply_visitor(vis);
			} catch (std::exception& e) {
				std::cerr << "ERROR THROWN: " << e.what() << std::endl;
			}
		}
	}
	return ret;
}
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "gui/color_button.h"
#include "gui/lighting_dock.h"
#include "file/config.h"
#include "math/math.h"

namespace MR
{
  namespace GUI
  {
    LightingSettings::LightingSettings (QWidget* parent, GL::Lighting& lighting) :
      QFrame (parent),
      info (lighting)
    {
      QColor C;
      QVBoxLayout* main_box = new QVBoxLayout;
      setLayout (main_box);
      QGridLayout* grid_layout = new QGridLayout;
      main_box->addLayout (grid_layout);
      main_box->addStretch ();

      QSlider* slider;

      QFont f = font();
      f.setPointSize (MR::File::Config::get_int ("MRViewToolFontSize", f.pointSize()-2));
      setFont (f);
      setFrameShadow (QFrame::Sunken);
      setFrameShape (QFrame::Panel);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (0,1000);
      slider->setSliderPosition (int (info.ambient * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (ambient_intensity_slot (int)));
      grid_layout->addWidget (new QLabel ("Ambient intensity"), 0, 0);
      grid_layout->addWidget (slider, 0, 1);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (0,1000);
      slider->setSliderPosition (int (info.diffuse * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (diffuse_intensity_slot (int)));
      grid_layout->addWidget (new QLabel ("Diffuse intensity"), 1, 0);
      grid_layout->addWidget (slider, 1, 1);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (0,1000);
      slider->setSliderPosition (int (info.specular * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (specular_intensity_slot (int)));
      grid_layout->addWidget (new QLabel ("Specular intensity"), 2, 0);
      grid_layout->addWidget (slider, 2, 1);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (10,10000);
      slider->setSliderPosition (int (info.shine * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (shine_slot (int)));
      grid_layout->addWidget (new QLabel ("Specular exponent"), 3, 0);
      grid_layout->addWidget (slider, 3, 1);

      elevation_slider = new QSlider (Qt::Horizontal);
      elevation_slider->setRange (0,1000);
      elevation_slider->setSliderPosition (int ( (1000.0/Math::pi) *acos (-info.lightpos[1]/Eigen::Map<Eigen::Matrix<float, 3, 1>>(info.lightpos).norm())));
      connect (elevation_slider, SIGNAL (valueChanged (int)), this, SLOT (light_position_slot()));
      grid_layout->addWidget (new QLabel ("Light elevation"), 4, 0);
      grid_layout->addWidget (elevation_slider, 4, 1);

      azimuth_slider = new QSlider (Qt::Horizontal);
      azimuth_slider->setRange (-1000,1000);
      azimuth_slider->setSliderPosition (int ( (1000.0/Math::pi) * atan2 (info.lightpos[0], info.lightpos[2])));
      connect (azimuth_slider, SIGNAL (valueChanged (int)), this, SLOT (light_position_slot()));
      grid_layout->addWidget (new QLabel ("Light azimuth"), 5, 0);
      grid_layout->addWidget (azimuth_slider, 5, 1);

      grid_layout->setColumnStretch (0,0);
      grid_layout->setColumnStretch (1,1);
      grid_layout->setColumnMinimumWidth (1, 100);
    }

    void LightingSettings::ambient_intensity_slot (int value)
    {
      info.ambient = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::diffuse_intensity_slot (int value)
    {
      info.diffuse = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::specular_intensity_slot (int value)
    {
      info.specular = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::shine_slot (int value)
    {
      info.shine = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::light_position_slot ()
    {
      float elevation = elevation_slider->value() * (Math::pi/1000.0);
      float azimuth = azimuth_slider->value() * (Math::pi/1000.0);
      info.lightpos[2] = sin (elevation) * cos (azimuth);
      info.lightpos[0] = sin (elevation) * sin (azimuth);
      info.lightpos[1] = -cos (elevation);
      info.update();
    }

    LightingDock::LightingDock (const std::string& title, GL::Lighting& lighting) :
      QDockWidget (QString (title.c_str())),
      settings (new LightingSettings (this, lighting))
    {
      setWidget(settings);
    }
  }
}
<commit_msg>Fix unused variable compiler warning<commit_after>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "gui/color_button.h"
#include "gui/lighting_dock.h"
#include "file/config.h"
#include "math/math.h"

namespace MR
{
  namespace GUI
  {
    LightingSettings::LightingSettings (QWidget* parent, GL::Lighting& lighting) :
      QFrame (parent),
      info (lighting)
    {
      QVBoxLayout* main_box = new QVBoxLayout;
      setLayout (main_box);
      QGridLayout* grid_layout = new QGridLayout;
      main_box->addLayout (grid_layout);
      main_box->addStretch ();

      QSlider* slider;

      QFont f = font();
      f.setPointSize (MR::File::Config::get_int ("MRViewToolFontSize", f.pointSize()-2));
      setFont (f);
      setFrameShadow (QFrame::Sunken);
      setFrameShape (QFrame::Panel);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (0,1000);
      slider->setSliderPosition (int (info.ambient * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (ambient_intensity_slot (int)));
      grid_layout->addWidget (new QLabel ("Ambient intensity"), 0, 0);
      grid_layout->addWidget (slider, 0, 1);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (0,1000);
      slider->setSliderPosition (int (info.diffuse * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (diffuse_intensity_slot (int)));
      grid_layout->addWidget (new QLabel ("Diffuse intensity"), 1, 0);
      grid_layout->addWidget (slider, 1, 1);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (0,1000);
      slider->setSliderPosition (int (info.specular * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (specular_intensity_slot (int)));
      grid_layout->addWidget (new QLabel ("Specular intensity"), 2, 0);
      grid_layout->addWidget (slider, 2, 1);

      slider = new QSlider (Qt::Horizontal);
      slider->setRange (10,10000);
      slider->setSliderPosition (int (info.shine * 1000.0));
      connect (slider, SIGNAL (valueChanged (int)), this, SLOT (shine_slot (int)));
      grid_layout->addWidget (new QLabel ("Specular exponent"), 3, 0);
      grid_layout->addWidget (slider, 3, 1);

      elevation_slider = new QSlider (Qt::Horizontal);
      elevation_slider->setRange (0,1000);
      elevation_slider->setSliderPosition (int ( (1000.0/Math::pi) *acos (-info.lightpos[1]/Eigen::Map<Eigen::Matrix<float, 3, 1>>(info.lightpos).norm())));
      connect (elevation_slider, SIGNAL (valueChanged (int)), this, SLOT (light_position_slot()));
      grid_layout->addWidget (new QLabel ("Light elevation"), 4, 0);
      grid_layout->addWidget (elevation_slider, 4, 1);

      azimuth_slider = new QSlider (Qt::Horizontal);
      azimuth_slider->setRange (-1000,1000);
      azimuth_slider->setSliderPosition (int ( (1000.0/Math::pi) * atan2 (info.lightpos[0], info.lightpos[2])));
      connect (azimuth_slider, SIGNAL (valueChanged (int)), this, SLOT (light_position_slot()));
      grid_layout->addWidget (new QLabel ("Light azimuth"), 5, 0);
      grid_layout->addWidget (azimuth_slider, 5, 1);

      grid_layout->setColumnStretch (0,0);
      grid_layout->setColumnStretch (1,1);
      grid_layout->setColumnMinimumWidth (1, 100);
    }

    void LightingSettings::ambient_intensity_slot (int value)
    {
      info.ambient = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::diffuse_intensity_slot (int value)
    {
      info.diffuse = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::specular_intensity_slot (int value)
    {
      info.specular = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::shine_slot (int value)
    {
      info.shine = float (value) /1000.0;
      info.update();
    }

    void LightingSettings::light_position_slot ()
    {
      float elevation = elevation_slider->value() * (Math::pi/1000.0);
      float azimuth = azimuth_slider->value() * (Math::pi/1000.0);
      info.lightpos[2] = sin (elevation) * cos (azimuth);
      info.lightpos[0] = sin (elevation) * sin (azimuth);
      info.lightpos[1] = -cos (elevation);
      info.update();
    }

    LightingDock::LightingDock (const std::string& title, GL::Lighting& lighting) :
      QDockWidget (QString (title.c_str())),
      settings (new LightingSettings (this, lighting))
    {
      setWidget(settings);
    }
  }
}
<|endoftext|>


<commit_before>#include <QDir>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QSettings>
#include "functions.h"
#include "language-loader.h"
#include "main-screen.h"
#include "models/image.h"
#include "models/profile.h"
#include "settings.h"
#include "share/share-utils.h"
#include "syntax-highlighter-helper.h"

int main(int argc, char *argv[])
{
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

	QGuiApplication app(argc, argv);
	app.setApplicationName("Grabber");
	app.setApplicationVersion(VERSION);
	app.setOrganizationName("Bionus");
	app.setOrganizationDomain("bionus.fr.cr");

	qmlRegisterType<ShareUtils>("Grabber", 1, 0, "ShareUtils");
	qmlRegisterType<SyntaxHighlighterHelper>("Grabber", 1, 0, "SyntaxHighlighterHelper");
	qRegisterMetaType<QSharedPointer<Image>>("QSharedPointer<Image>");
	qRegisterMetaType<Settings*>("Settings*");

	// Copy settings files to writable directory
	const QStringList toCopy { "sites/", "themes/", "webservices/" };
	for (const QString &tgt : toCopy) {
		const QString from = savePath(tgt, true, false);
		const QString to = savePath(tgt, true, true);
		if (!QDir(to).exists() && QDir(from).exists()) {
			copyRecursively(from, to);
		}
	}

	const QUrl url(QStringLiteral("qrc:/main-screen.qml"));

	QQmlApplicationEngine engine;
	QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) {
		if (!obj && url == objUrl) {
			QCoreApplication::exit(-1);
		}
	}, Qt::QueuedConnection);

	// Define a few globals
	engine.rootContext()->setContextProperty("VERSION", QString(VERSION));
	#ifdef NIGHTLY
		engine.rootContext()->setContextProperty("NIGHTLY", true);
		engine.rootContext()->setContextProperty("NIGHTLY_COMMIT", QString(NIGHTLY_COMMIT));
	#else
		engine.rootContext()->setContextProperty("NIGHTLY", false);
		engine.rootContext()->setContextProperty("NIGHTLY_COMMIT", QString());
	#endif

	Profile profile(savePath());
	MainScreen mainScreen(&profile, &engine);
	engine.setObjectOwnership(&mainScreen, QQmlEngine::CppOwnership);
	engine.rootContext()->setContextProperty("backend", &mainScreen);

	Settings settings(profile.getSettings());
	engine.rootContext()->setContextProperty("settings", &settings);

	// Load translations
	LanguageLoader languageLoader(savePath("languages/", true, false));
	languageLoader.install(qApp);
	languageLoader.setLanguage(profile.getSettings()->value("language", "English").toString());
	engine.rootContext()->setContextProperty("languageLoader", &languageLoader);
	#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
		QObject::connect(&languageLoader, &LanguageLoader::languageChanged, &engine, &QQmlEngine::retranslate);
	#endif

	engine.load(url);

	return app.exec();
}
<commit_msg>Add Android permission check on startup<commit_after>#include <QDir>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QSettings>
#include "functions.h"
#include "language-loader.h"
#include "main-screen.h"
#include "models/image.h"
#include "models/profile.h"
#include "settings.h"
#include "share/share-utils.h"
#include "syntax-highlighter-helper.h"

#if defined(Q_OS_ANDROID)
	#include <QtAndroid>
	#include "logger.h"

	bool checkPermission(const QString &perm)
	{
		auto already = QtAndroid::checkPermission(perm);
		if (already == QtAndroid::PermissionResult::Denied) {
			auto results = QtAndroid::requestPermissionsSync(QStringList() << perm);
			if (results[perm] == QtAndroid::PermissionResult::Denied) {
				return false;
			}
		}
		return true;
	}
#endif

int main(int argc, char *argv[])
{
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

	QGuiApplication app(argc, argv);
	app.setApplicationName("Grabber");
	app.setApplicationVersion(VERSION);
	app.setOrganizationName("Bionus");
	app.setOrganizationDomain("bionus.fr.cr");

	qmlRegisterType<ShareUtils>("Grabber", 1, 0, "ShareUtils");
	qmlRegisterType<SyntaxHighlighterHelper>("Grabber", 1, 0, "SyntaxHighlighterHelper");
	qRegisterMetaType<QSharedPointer<Image>>("QSharedPointer<Image>");
	qRegisterMetaType<Settings*>("Settings*");

	// Copy settings files to writable directory
	const QStringList toCopy { "sites/", "themes/", "webservices/" };
	for (const QString &tgt : toCopy) {
		const QString from = savePath(tgt, true, false);
		const QString to = savePath(tgt, true, true);
		if (!QDir(to).exists() && QDir(from).exists()) {
			copyRecursively(from, to);
		}
	}

	const QUrl url(QStringLiteral("qrc:/main-screen.qml"));

	QQmlApplicationEngine engine;
	QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) {
		if (!obj && url == objUrl) {
			QCoreApplication::exit(-1);
		}
	}, Qt::QueuedConnection);

	// Define a few globals
	engine.rootContext()->setContextProperty("VERSION", QString(VERSION));
	#ifdef NIGHTLY
		engine.rootContext()->setContextProperty("NIGHTLY", true);
		engine.rootContext()->setContextProperty("NIGHTLY_COMMIT", QString(NIGHTLY_COMMIT));
	#else
		engine.rootContext()->setContextProperty("NIGHTLY", false);
		engine.rootContext()->setContextProperty("NIGHTLY_COMMIT", QString());
	#endif

	Profile profile(savePath());
	MainScreen mainScreen(&profile, &engine);
	engine.setObjectOwnership(&mainScreen, QQmlEngine::CppOwnership);
	engine.rootContext()->setContextProperty("backend", &mainScreen);

	Settings settings(profile.getSettings());
	engine.rootContext()->setContextProperty("settings", &settings);

	// Load translations
	LanguageLoader languageLoader(savePath("languages/", true, false));
	languageLoader.install(qApp);
	languageLoader.setLanguage(profile.getSettings()->value("language", "English").toString());
	engine.rootContext()->setContextProperty("languageLoader", &languageLoader);
	#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
		QObject::connect(&languageLoader, &LanguageLoader::languageChanged, &engine, &QQmlEngine::retranslate);
	#endif

	#if defined(Q_OS_ANDROID)
		if (!checkPermission("android.permission.WRITE_EXTERNAL_STORAGE")) {
			log(QStringLiteral("Android write permission not granted"), Logger::Error);
		}
	#endif

	engine.load(url);

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


<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "jstreamsconfig.h"
#include "streamindexer.h"
#include "fileinputstream.h"
#include "streamendanalyzer.h"
#include "streamthroughanalyzer.h"
#include "bz2endanalyzer.h"
#include "textendanalyzer.h"
#include "saxendanalyzer.h"
#include "tarendanalyzer.h"
#include "zipendanalyzer.h"
#include "pngendanalyzer.h"
#include "gzipendanalyzer.h"
#include "mailendanalyzer.h"
#include "digestthroughanalyzer.h"
#include "pluginthroughanalyzer.h"
#include "pluginendanalyzer.h"
#include "indexwriter.h"
#include <sys/stat.h>

using namespace std;
using namespace jstreams;

StreamIndexer::StreamIndexer(IndexWriter* w) :writer(w) {

    moduleLoader.loadPlugins("/usr/local/lib/strigi");
    moduleLoader.loadPlugins("/usr/lib/strigi");
    moduleLoader.loadPlugins("/lib/strigi");

    // todo: remove this
    moduleLoader.loadPlugins("D:\\clients\\strigi_svn\\win\\out\\Debug");
    if ( getenv("HOME") != NULL ){
        string homedir = getenv("HOME");
        homedir += "/testinstall/lib/strigi";
        moduleLoader.loadPlugins(homedir.c_str());
    }
}
StreamIndexer::~StreamIndexer() {
    // delete the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    for (tIter = through.begin(); tIter != through.end(); ++tIter) {
        std::vector<StreamThroughAnalyzer*>::iterator t;
        for (t = tIter->begin(); t != tIter->end(); ++t) {
            delete *t;
        }
    }
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    for (eIter = end.begin(); eIter != end.end(); ++eIter) {
        std::vector<StreamEndAnalyzer*>::iterator e;
        for (e = eIter->begin(); e != eIter->end(); ++e) {
            delete *e;
        }
    }
}
char
StreamIndexer::indexFile(const char *filepath) {
    std::string path(filepath);
    return indexFile(path);
}
char
StreamIndexer::indexFile(const std::string& filepath) {
    struct stat s;
    stat(filepath.c_str(), &s);
    FileInputStream file(filepath.c_str());
    // ensure a decent buffer size
    //file.mark(65530);
    return analyze(filepath, s.st_mtime, &file, 0);
}
void
StreamIndexer::addThroughAnalyzers() {
    through.resize(through.size()+1);
    std::vector<std::vector<StreamThroughAnalyzer*> >::reverse_iterator tIter;
    tIter = through.rbegin();
    StreamThroughAnalyzer* ana = new DigestThroughAnalyzer();
    tIter->push_back(ana);
    ana = new PluginThroughAnalyzer(&moduleLoader);
    tIter->push_back(ana);

}
void
StreamIndexer::addEndAnalyzers() {
    end.resize(end.size()+1);
    std::vector<std::vector<StreamEndAnalyzer*> >::reverse_iterator eIter;
    eIter = end.rbegin();
    StreamEndAnalyzer* ana = new BZ2EndAnalyzer();
    eIter->push_back(ana);
    ana = new GZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new TarEndAnalyzer();
    eIter->push_back(ana);
    ana = new MailEndAnalyzer();
    eIter->push_back(ana);
    ana = new ZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new PngEndAnalyzer();
    eIter->push_back(ana);
    ana = new PluginEndAnalyzer(&moduleLoader);
    eIter->push_back(ana);

/*    ana = new PdfEndAnalyzer();
    eIter->push_back(ana);*/
    // add a sax analyzer before the text analyzer
    //ana = new SaxEndAnalyzer();
    //eIter->push_back(ana);
    // add a text analyzer to the end of the queue
    ana = new TextEndAnalyzer();
    eIter->push_back(ana);
}
char
StreamIndexer::analyze(const std::string &path, time_t mtime,
        InputStream *input, uint depth) {
    static int count = 1;
    if (++count % 1000 == 0) {
        printf("file #%i: %s\n", count, path.c_str());
    }
    //printf("depth #%i: %s\n", depth, path.c_str());
    Indexable idx(path, mtime, writer, depth);

    // retrieve or construct the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    while (through.size() < depth+1) {
        addThroughAnalyzers();
        addEndAnalyzers();
    }
    tIter = through.begin() + depth;
    eIter = end.begin() + depth;

    // insert the through analyzers
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        (*ts)->setIndexable(&idx);
        input = (*ts)->connectInputStream(input);
    }
    bool finished = false;
    int32_t headersize = 1024;
    const char* header;
    headersize = input->read(header, headersize, 0);
    if (input->reset(0) != 0) {
        printf("resetting is impossible!! pos: %lli status: %i\n",
            input->getPosition(), input->getStatus());
    }
    if (headersize < 0) finished = true;
    int es = 0, size = eIter->size();
    while (!finished && es != size) {
        StreamEndAnalyzer* sea = (*eIter)[es];
        if (sea->checkHeader(header, headersize)) {
            char ar = sea->analyze(path, input, depth+1, this, &idx);
            if (ar) {
                int64_t pos = input->reset(0);
                if (pos != 0) { // could not reset
                    printf("could not reset stream of %s from pos %lli to 0 "
                        "after reading with %s: %s\n", path.c_str(),
                        input->getPosition(), sea->getName(),
                        sea->getError().c_str());
                    removeIndexable(depth);
                    return -2;
                }
            } else {
                finished = true;
            }
            eIter = end.begin() + depth;
        }
        es++;
    }
    // make sure the entire stream as read
    int64_t nskipped;
    do {
        nskipped = input->skip(1000000);
    } while (input->getStatus() == Ok);
    if (input->getStatus() == Error) {
        printf("Error: %s\n", input->getError());
        removeIndexable(depth);
        return -2;
    }

    // store the size of the stream
    {
        //tmp scope out tmp mem
        char tmp[100];
        sprintf(tmp, "%d", input->getSize());
        idx.setField("size", tmp);
    }

    // remove references to the indexable before it goes out of scope
    removeIndexable(depth);
    return 0;
}
void
StreamIndexer::removeIndexable(uint depth) {
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    tIter = through.begin() + depth;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        // remove references to the indexable before it goes out of scope
        (*ts)->setIndexable(0);
    }
}
<commit_msg>Add support for ar archives which means debian .deb packages can now also be indexed.<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "jstreamsconfig.h"
#include "streamindexer.h"
#include "fileinputstream.h"
#include "streamendanalyzer.h"
#include "streamthroughanalyzer.h"
#include "bz2endanalyzer.h"
#include "textendanalyzer.h"
#include "saxendanalyzer.h"
#include "tarendanalyzer.h"
#include "arendanalyzer.h"
#include "zipendanalyzer.h"
#include "pngendanalyzer.h"
#include "gzipendanalyzer.h"
#include "mailendanalyzer.h"
#include "digestthroughanalyzer.h"
#include "pluginthroughanalyzer.h"
#include "pluginendanalyzer.h"
#include "indexwriter.h"
#include <sys/stat.h>

using namespace std;
using namespace jstreams;

StreamIndexer::StreamIndexer(IndexWriter* w) :writer(w) {

    moduleLoader.loadPlugins("/usr/local/lib/strigi");
    moduleLoader.loadPlugins("/usr/lib/strigi");
    moduleLoader.loadPlugins("/lib/strigi");

    // todo: remove this
    moduleLoader.loadPlugins("D:\\clients\\strigi_svn\\win\\out\\Debug");
    if ( getenv("HOME") != NULL ){
        string homedir = getenv("HOME");
        homedir += "/testinstall/lib/strigi";
        moduleLoader.loadPlugins(homedir.c_str());
    }
}
StreamIndexer::~StreamIndexer() {
    // delete the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    for (tIter = through.begin(); tIter != through.end(); ++tIter) {
        std::vector<StreamThroughAnalyzer*>::iterator t;
        for (t = tIter->begin(); t != tIter->end(); ++t) {
            delete *t;
        }
    }
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    for (eIter = end.begin(); eIter != end.end(); ++eIter) {
        std::vector<StreamEndAnalyzer*>::iterator e;
        for (e = eIter->begin(); e != eIter->end(); ++e) {
            delete *e;
        }
    }
}
char
StreamIndexer::indexFile(const char *filepath) {
    std::string path(filepath);
    return indexFile(path);
}
char
StreamIndexer::indexFile(const std::string& filepath) {
    struct stat s;
    stat(filepath.c_str(), &s);
    FileInputStream file(filepath.c_str());
    // ensure a decent buffer size
    //file.mark(65530);
    return analyze(filepath, s.st_mtime, &file, 0);
}
void
StreamIndexer::addThroughAnalyzers() {
    through.resize(through.size()+1);
    std::vector<std::vector<StreamThroughAnalyzer*> >::reverse_iterator tIter;
    tIter = through.rbegin();
    StreamThroughAnalyzer* ana = new DigestThroughAnalyzer();
    tIter->push_back(ana);
    ana = new PluginThroughAnalyzer(&moduleLoader);
    tIter->push_back(ana);

}
void
StreamIndexer::addEndAnalyzers() {
    end.resize(end.size()+1);
    std::vector<std::vector<StreamEndAnalyzer*> >::reverse_iterator eIter;
    eIter = end.rbegin();
    StreamEndAnalyzer* ana = new BZ2EndAnalyzer();
    eIter->push_back(ana);
    ana = new GZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new TarEndAnalyzer();
    eIter->push_back(ana);
    ana = new ArEndAnalyzer();
    eIter->push_back(ana);
    ana = new MailEndAnalyzer();
    eIter->push_back(ana);
    ana = new ZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new PngEndAnalyzer();
    eIter->push_back(ana);
    ana = new PluginEndAnalyzer(&moduleLoader);
    eIter->push_back(ana);

/*    ana = new PdfEndAnalyzer();
    eIter->push_back(ana);*/
    // add a sax analyzer before the text analyzer
    //ana = new SaxEndAnalyzer();
    //eIter->push_back(ana);
    // add a text analyzer to the end of the queue
    ana = new TextEndAnalyzer();
    eIter->push_back(ana);
}
char
StreamIndexer::analyze(const std::string &path, time_t mtime,
        InputStream *input, uint depth) {
    static int count = 1;
    if (++count % 1000 == 0) {
        printf("file #%i: %s\n", count, path.c_str());
    }
    //printf("depth #%i: %s\n", depth, path.c_str());
    Indexable idx(path, mtime, writer, depth);

    // retrieve or construct the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    while (through.size() < depth+1) {
        addThroughAnalyzers();
        addEndAnalyzers();
    }
    tIter = through.begin() + depth;
    eIter = end.begin() + depth;

    // insert the through analyzers
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        (*ts)->setIndexable(&idx);
        input = (*ts)->connectInputStream(input);
    }
    bool finished = false;
    int32_t headersize = 1024;
    const char* header;
    headersize = input->read(header, headersize, 0);
    if (input->reset(0) != 0) {
        printf("resetting is impossible!! pos: %lli status: %i\n",
            input->getPosition(), input->getStatus());
    }
    if (headersize < 0) finished = true;
    int es = 0, size = eIter->size();
    while (!finished && es != size) {
        StreamEndAnalyzer* sea = (*eIter)[es];
        if (sea->checkHeader(header, headersize)) {
            char ar = sea->analyze(path, input, depth+1, this, &idx);
            if (ar) {
                int64_t pos = input->reset(0);
                if (pos != 0) { // could not reset
                    printf("could not reset stream of %s from pos %lli to 0 "
                        "after reading with %s: %s\n", path.c_str(),
                        input->getPosition(), sea->getName(),
                        sea->getError().c_str());
                    removeIndexable(depth);
                    return -2;
                }
            } else {
                finished = true;
            }
            eIter = end.begin() + depth;
        }
        es++;
    }
    // make sure the entire stream as read
    int64_t nskipped;
    do {
        nskipped = input->skip(1000000);
    } while (input->getStatus() == Ok);
    if (input->getStatus() == Error) {
        printf("Error: %s\n", input->getError());
        removeIndexable(depth);
        return -2;
    }

    // store the size of the stream
    {
        //tmp scope out tmp mem
        char tmp[100];
        sprintf(tmp, "%d", input->getSize());
        idx.setField("size", tmp);
    }

    // remove references to the indexable before it goes out of scope
    removeIndexable(depth);
    return 0;
}
void
StreamIndexer::removeIndexable(uint depth) {
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    tIter = through.begin() + depth;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        // remove references to the indexable before it goes out of scope
        (*ts)->setIndexable(0);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/util/util.hpp>
#include <nix/hdf5/SectionHDF5.hpp>
#include <nix/hdf5/PropertyHDF5.hpp>

using namespace std;

namespace nix {
namespace hdf5 {

SectionHDF5::SectionHDF5(const SectionHDF5 &section)
    : NamedEntityHDF5(section.file(), section.group(), section.id(), section.type(), section.name())
{
    property_group = section.property_group;
    section_group = section.section_group;
}

SectionHDF5::SectionHDF5(const File &file, const Group &group, const string &id,
                         const string &type, const string &name)
    : SectionHDF5(file, nullptr, group, id, type, name)
{
}

SectionHDF5::SectionHDF5(const File &file, const Section &parent, const Group &group,
                         const string &id, const string &type, const string &name)
    : SectionHDF5(file, parent, group, id, type, name, util::getTime())
{
}

SectionHDF5::SectionHDF5(const File &file, const Group &group, const string &id,
                         const string &type, const string &name, time_t time)
    : SectionHDF5(file, nullptr, group, id, type, name, time)
{
}

SectionHDF5::SectionHDF5(const File &file, const Section &parent, const Group &group,
                         const string &id, const string &type, const string &name, time_t time)
    : NamedEntityHDF5(file, group, id, type, name, time), parent_section(parent)
{
    property_group = this->group().openGroup("properties");
    section_group = this->group().openGroup("sections");
}

//--------------------------------------------------
// Attribute getter and setter
//--------------------------------------------------

void SectionHDF5::repository(const string &repository) {
    if(repository.empty()) {
        throw EmptyString("repository");
    } else {
        group().setAttr("repository", repository);
        forceUpdatedAt();
    }
}

boost::optional<string> SectionHDF5::repository() const {
    boost::optional<string> ret;
    string repository;
    if(group().getAttr("repository", repository)) {
        ret = repository;
    }
    return ret;
}

void SectionHDF5::repository(const none_t t) {
    if(group().hasAttr("repository")) {
        group().removeAttr("repository");
    }
    forceUpdatedAt();
}

void SectionHDF5::link(const std::string &id) {
    if(id.empty()) {
        throw EmptyString("mapping");
    } else if (file().hasSection(id)) {
        group().setAttr("link", id);
    } else {
        throw std::runtime_error("Section not found in file!");
    }
}

Section SectionHDF5::link() const {
    string id;
    group().getAttr("link", id);

    vector<Section> found;
    if (id != "") {
        auto filter = [&](const Section &s) {
            return id == s.id();
        };

        found = file().findSections(filter);
    }

    if (found.size() > 0)
        return found[0];
    else
        return Section();
}

void SectionHDF5::link(const none_t t) {
    if(group().hasAttr("link")) {
        group().removeAttr("link");
    }
    forceUpdatedAt();
}

void SectionHDF5::mapping(const string &mapping) {
    if(mapping.empty()) {
        throw EmptyString("mapping");
    } else {
        group().setAttr("mapping", mapping);
        forceUpdatedAt();
    }
}

boost::optional<string> SectionHDF5::mapping() const {
    boost::optional<string> ret;
    string mapping;
    if(group().getAttr("mapping", mapping)) {
        ret = mapping;
    }
    return ret;
}

void SectionHDF5::mapping(const none_t t) {
    if(group().hasAttr("mapping")) {
        group().removeAttr("mapping");
    }
    forceUpdatedAt();
}

//--------------------------------------------------
// Methods for parent access
//--------------------------------------------------

Section SectionHDF5::parent() const {
    return parent_section;
}

//--------------------------------------------------
// Methods for child section access
//--------------------------------------------------

size_t SectionHDF5::sectionCount() const {
    return section_group.objectCount();
}

bool SectionHDF5::hasSection(const string &id) const {
    return section_group.hasGroup(id);
}

Section SectionHDF5::getSection(const string &id) const {
    if (section_group.hasGroup(id)) {
        Group group = section_group.openGroup(id, false);
        std::string type;
        std::string name;
        group.getAttr("type", type);
        group.getAttr("name", name);

        Section parent(const_pointer_cast<SectionHDF5>(shared_from_this()));
        auto tmp = make_shared<SectionHDF5>(file(), parent, group, id, type, name);
        return Section(tmp);
    } else {
        return Section();
    }
}

Section SectionHDF5::getSection(size_t index) const {
    string id = section_group.objectName(index);

    return getSection(id);
}

Section SectionHDF5::createSection(const string &name, const string &type) {
    string new_id = util::createId("section");

    while (section_group.hasObject(new_id)) {
        new_id = util::createId("section");
    }

    Section parent(const_pointer_cast<SectionHDF5>(shared_from_this()));

    Group grp = section_group.openGroup(new_id, true);
    auto tmp = make_shared<SectionHDF5>(file(), parent, grp, new_id, type, name);

    return Section(tmp);
}

bool SectionHDF5::deleteSection(const string &id) {
    if (section_group.hasGroup(id)) {
        section_group.removeGroup(id);
        return true;
    } else {
        return false;
    }
}

//--------------------------------------------------
// Methods for property access
//--------------------------------------------------

size_t SectionHDF5::propertyCount() const {
    return property_group.objectCount();
}

bool SectionHDF5::hasProperty(const string &id) const {
    return property_group.hasObject(id);
}

Property SectionHDF5::getProperty(const string &id) const {
    if (property_group.hasData(id)) {
        DataSet dset = property_group.openData(id);
        string name;
        dset.getAttr("name", name);
        auto tmp = make_shared<PropertyHDF5>(file(), property_group, dset, id, name);
        return Property(tmp);
    } else {
        return Property();
    }
}

Property SectionHDF5::getProperty(size_t index) const {
    string id = property_group.objectName(index);

    return getProperty(id);
}

bool SectionHDF5::hasPropertyWithName(const string &name) const {
    bool found = false;

    for (size_t i = 0; i < propertyCount(); i++) {
        string id = property_group.objectName(i);
        DataSet dset = property_group.openData(id);

        string other_name;
        dset.getAttr("name", other_name);

        if (other_name == name) {
            found = true;
            break;
        }
    }
    return found;
}

Property SectionHDF5::getPropertyByName(const string &name) const {
    Property prop;

    for (size_t i = 0; i < propertyCount(); i++) {
        string id = property_group.objectName(i);
        DataSet dset = property_group.openData(id);

        string other_name;
        dset.getAttr("name", other_name);

        if (other_name == name) {
            string type;
            dset.getAttr("type", type);
            auto tmp = make_shared<PropertyHDF5>(file(), property_group, dset, id, name);
            prop = Property(tmp);
            break;
        }
    }

    // return empty object if not found (since then "prop" is still empty Property)
    return prop;
}

Property SectionHDF5::createProperty(const string &name, const Value & value) {
    if (hasPropertyWithName(name))
        throw runtime_error("Try to create a property with existing name: " + name);

    string new_id = util::createId("property");
    while (property_group.hasData(new_id))
        new_id = util::createId("property");

    NDSize size = {1};
    DataType dtype = value.type();
    H5::DataType fileType = DataSet::fileTypeForValue(dtype);
    DataSet dataset = DataSet::create(property_group.h5Group(), new_id, fileType, size);
    auto tmp = make_shared<PropertyHDF5>(file(), property_group, dataset, new_id, name);
    return Property(tmp);
}

Property SectionHDF5::createProperty(const string &name, const vector<Value> &values) {
    if (values.size() < 1) {
        throw runtime_error("Trying to create a property without a value!");
    }
    Property p = createProperty(name, values[0]);
    p.values(values);
    return p;
}

bool SectionHDF5::deleteProperty(const string &id) {
    if (property_group.hasData(id)) {
        property_group.removeData(id);
        return true;
    } else {
        return false;
    }
}

SectionHDF5::~SectionHDF5() {}

} // namespace hdf5
} // namespace nix
<commit_msg>fixed bug in SectionHDF::createProperty with single values<commit_after>// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include <nix/util/util.hpp>
#include <nix/hdf5/SectionHDF5.hpp>
#include <nix/hdf5/PropertyHDF5.hpp>

using namespace std;

namespace nix {
namespace hdf5 {

SectionHDF5::SectionHDF5(const SectionHDF5 &section)
    : NamedEntityHDF5(section.file(), section.group(), section.id(), section.type(), section.name())
{
    property_group = section.property_group;
    section_group = section.section_group;
}

SectionHDF5::SectionHDF5(const File &file, const Group &group, const string &id,
                         const string &type, const string &name)
    : SectionHDF5(file, nullptr, group, id, type, name)
{
}

SectionHDF5::SectionHDF5(const File &file, const Section &parent, const Group &group,
                         const string &id, const string &type, const string &name)
    : SectionHDF5(file, parent, group, id, type, name, util::getTime())
{
}

SectionHDF5::SectionHDF5(const File &file, const Group &group, const string &id,
                         const string &type, const string &name, time_t time)
    : SectionHDF5(file, nullptr, group, id, type, name, time)
{
}

SectionHDF5::SectionHDF5(const File &file, const Section &parent, const Group &group,
                         const string &id, const string &type, const string &name, time_t time)
    : NamedEntityHDF5(file, group, id, type, name, time), parent_section(parent)
{
    property_group = this->group().openGroup("properties");
    section_group = this->group().openGroup("sections");
}

//--------------------------------------------------
// Attribute getter and setter
//--------------------------------------------------

void SectionHDF5::repository(const string &repository) {
    if(repository.empty()) {
        throw EmptyString("repository");
    } else {
        group().setAttr("repository", repository);
        forceUpdatedAt();
    }
}

boost::optional<string> SectionHDF5::repository() const {
    boost::optional<string> ret;
    string repository;
    if(group().getAttr("repository", repository)) {
        ret = repository;
    }
    return ret;
}

void SectionHDF5::repository(const none_t t) {
    if(group().hasAttr("repository")) {
        group().removeAttr("repository");
    }
    forceUpdatedAt();
}

void SectionHDF5::link(const std::string &id) {
    if(id.empty()) {
        throw EmptyString("mapping");
    } else if (file().hasSection(id)) {
        group().setAttr("link", id);
    } else {
        throw std::runtime_error("Section not found in file!");
    }
}

Section SectionHDF5::link() const {
    string id;
    group().getAttr("link", id);

    vector<Section> found;
    if (id != "") {
        auto filter = [&](const Section &s) {
            return id == s.id();
        };

        found = file().findSections(filter);
    }

    if (found.size() > 0)
        return found[0];
    else
        return Section();
}

void SectionHDF5::link(const none_t t) {
    if(group().hasAttr("link")) {
        group().removeAttr("link");
    }
    forceUpdatedAt();
}

void SectionHDF5::mapping(const string &mapping) {
    if(mapping.empty()) {
        throw EmptyString("mapping");
    } else {
        group().setAttr("mapping", mapping);
        forceUpdatedAt();
    }
}

boost::optional<string> SectionHDF5::mapping() const {
    boost::optional<string> ret;
    string mapping;
    if(group().getAttr("mapping", mapping)) {
        ret = mapping;
    }
    return ret;
}

void SectionHDF5::mapping(const none_t t) {
    if(group().hasAttr("mapping")) {
        group().removeAttr("mapping");
    }
    forceUpdatedAt();
}

//--------------------------------------------------
// Methods for parent access
//--------------------------------------------------

Section SectionHDF5::parent() const {
    return parent_section;
}

//--------------------------------------------------
// Methods for child section access
//--------------------------------------------------

size_t SectionHDF5::sectionCount() const {
    return section_group.objectCount();
}

bool SectionHDF5::hasSection(const string &id) const {
    return section_group.hasGroup(id);
}

Section SectionHDF5::getSection(const string &id) const {
    if (section_group.hasGroup(id)) {
        Group group = section_group.openGroup(id, false);
        std::string type;
        std::string name;
        group.getAttr("type", type);
        group.getAttr("name", name);

        Section parent(const_pointer_cast<SectionHDF5>(shared_from_this()));
        auto tmp = make_shared<SectionHDF5>(file(), parent, group, id, type, name);
        return Section(tmp);
    } else {
        return Section();
    }
}

Section SectionHDF5::getSection(size_t index) const {
    string id = section_group.objectName(index);

    return getSection(id);
}

Section SectionHDF5::createSection(const string &name, const string &type) {
    string new_id = util::createId("section");

    while (section_group.hasObject(new_id)) {
        new_id = util::createId("section");
    }

    Section parent(const_pointer_cast<SectionHDF5>(shared_from_this()));

    Group grp = section_group.openGroup(new_id, true);
    auto tmp = make_shared<SectionHDF5>(file(), parent, grp, new_id, type, name);

    return Section(tmp);
}

bool SectionHDF5::deleteSection(const string &id) {
    if (section_group.hasGroup(id)) {
        section_group.removeGroup(id);
        return true;
    } else {
        return false;
    }
}

//--------------------------------------------------
// Methods for property access
//--------------------------------------------------

size_t SectionHDF5::propertyCount() const {
    return property_group.objectCount();
}

bool SectionHDF5::hasProperty(const string &id) const {
    return property_group.hasObject(id);
}

Property SectionHDF5::getProperty(const string &id) const {
    if (property_group.hasData(id)) {
        DataSet dset = property_group.openData(id);
        string name;
        dset.getAttr("name", name);
        auto tmp = make_shared<PropertyHDF5>(file(), property_group, dset, id, name);
        return Property(tmp);
    } else {
        return Property();
    }
}

Property SectionHDF5::getProperty(size_t index) const {
    string id = property_group.objectName(index);

    return getProperty(id);
}

bool SectionHDF5::hasPropertyWithName(const string &name) const {
    bool found = false;

    for (size_t i = 0; i < propertyCount(); i++) {
        string id = property_group.objectName(i);
        DataSet dset = property_group.openData(id);

        string other_name;
        dset.getAttr("name", other_name);

        if (other_name == name) {
            found = true;
            break;
        }
    }
    return found;
}

Property SectionHDF5::getPropertyByName(const string &name) const {
    Property prop;

    for (size_t i = 0; i < propertyCount(); i++) {
        string id = property_group.objectName(i);
        DataSet dset = property_group.openData(id);

        string other_name;
        dset.getAttr("name", other_name);

        if (other_name == name) {
            string type;
            dset.getAttr("type", type);
            auto tmp = make_shared<PropertyHDF5>(file(), property_group, dset, id, name);
            prop = Property(tmp);
            break;
        }
    }

    // return empty object if not found (since then "prop" is still empty Property)
    return prop;
}

Property SectionHDF5::createProperty(const string &name, const Value &value) {
    if (hasPropertyWithName(name))
        throw runtime_error("Try to create a property with existing name: " + name);

    string new_id = util::createId("property");
    while (property_group.hasData(new_id))
        new_id = util::createId("property");

    NDSize size = {1};
    DataType dtype = value.type();
    H5::DataType fileType = DataSet::fileTypeForValue(dtype);
    DataSet dataset = DataSet::create(property_group.h5Group(), new_id, fileType, size);
    auto tmp = make_shared<PropertyHDF5>(file(), property_group, dataset, new_id, name);
    Property p(tmp);
    vector<Value> val{value};
    p.values(val);
    return p;
}

Property SectionHDF5::createProperty(const string &name, const vector<Value> &values) {
    if (values.size() < 1) {
        throw runtime_error("Trying to create a property without a value!");
    }
    Property p = createProperty(name, values[0]);
    p.values(values);
    return p;
}

bool SectionHDF5::deleteProperty(const string &id) {
    if (property_group.hasData(id)) {
        property_group.removeData(id);
        return true;
    } else {
        return false;
    }
}

SectionHDF5::~SectionHDF5() {}

} // namespace hdf5
} // namespace nix
<|endoftext|>


<commit_before>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtGui module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtheaderview.h"

class QxtHeaderViewPrivate : public QxtPrivate<QxtHeaderView>
{
public:
    QXT_DECLARE_PUBLIC(QxtHeaderView);

    QxtHeaderViewPrivate();

    bool proportional;
    QMap<int, int> factors;
};

QxtHeaderViewPrivate::QxtHeaderViewPrivate() : proportional(false)
{
}

/*!
    \class QxtHeaderView QxtHeaderView
    \inmodule QxtGui
    \brief An extended QHeaderView with optionally proportional section sizes.
 */

/*!
    Constructs a new QxtHeaderView with \a orientation and \a parent.
 */

QxtHeaderView::QxtHeaderView(Qt::Orientation orientation, QWidget* parent)
        : QHeaderView(orientation, parent)
{
    QXT_INIT_PRIVATE(QxtHeaderView);
}

/*!
    \property QxtHeaderView::hasProportionalSectionSizes
    \brief This property holds whether section sizes are proportional.

    The default value is \bold true.

    \bold {Note:} Enabling proportional sections sizes sets resize mode
    \bold QHeaderView::Fixed, which means that the user cannot resize
    sections.
 */
bool QxtHeaderView::hasProportionalSectionSizes() const
{
    return qxt_d().proportional;
}

void QxtHeaderView::setProportionalSectionSizes(bool enabled)
{
    if (qxt_d().proportional != enabled)
    {
        qxt_d().proportional = enabled;
        if (enabled)
            setResizeMode(QHeaderView::Fixed);
    }
}

/*!
    Returns the stretch factor of the section at \a logicalIndex.

    \sa setSectionStretchFactor()
 */
int QxtHeaderView::sectionStretchFactor(int logicalIndex) const
{
    return qxt_d().factors.value(logicalIndex);
}

/*!
    Sets the stretch \a factor of the section at \a logicalIndex.

    \sa sectionStretchFactor()
 */
void QxtHeaderView::setSectionStretchFactor(int logicalIndex, int factor)
{
    qxt_d().factors.insert(logicalIndex, factor);
}

/*!
    \reimp
 */
void QxtHeaderView::resizeEvent(QResizeEvent* event)
{
    QHeaderView::resizeEvent(event);
    if (qxt_d().proportional)
    {
        int total = 0;
        for (int i = 0; i < count(); ++i)
            total += qxt_d().factors.value(i, 1);

        int totalSize = 0;
        for (int i = 0; i < count() - 1; ++i)
        {
            qreal factor = qxt_d().factors.value(i, 1) / static_cast<qreal>(total);
            int sectionSize = factor * (orientation() == Qt::Horizontal ? width() : height());
            sectionSize = qMax(minimumSectionSize(), sectionSize);
            resizeSection(i, sectionSize);
            totalSize += sectionSize;
        }
        // avoid rounding errors, give rest to the last section
        resizeSection(count() - 1, width() - totalSize);
    }
}
<commit_msg>Fixed QxtHeaderView docs.<commit_after>/****************************************************************************
 **
 ** Copyright (C) Qxt Foundation. Some rights reserved.
 **
 ** This file is part of the QxtGui module of the Qxt library.
 **
 ** This library is free software; you can redistribute it and/or modify it
 ** under the terms of the Common Public License, version 1.0, as published
 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 ** version 2.1, as published by the Free Software Foundation.
 **
 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 ** FITNESS FOR A PARTICULAR PURPOSE.
 **
 ** You should have received a copy of the CPL and the LGPL along with this
 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 ** included with the source distribution for more information.
 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 **
 ** <http://libqxt.org>  <foundation@libqxt.org>
 **
 ****************************************************************************/
#include "qxtheaderview.h"

class QxtHeaderViewPrivate : public QxtPrivate<QxtHeaderView>
{
public:
    QXT_DECLARE_PUBLIC(QxtHeaderView);

    QxtHeaderViewPrivate();

    bool proportional;
    QMap<int, int> factors;
};

QxtHeaderViewPrivate::QxtHeaderViewPrivate() : proportional(false)
{
}

/*!
    \class QxtHeaderView QxtHeaderView
    \inmodule QxtGui
    \brief An extended QHeaderView with optionally proportional section sizes.
 */

/*!
    Constructs a new QxtHeaderView with \a orientation and \a parent.
 */

QxtHeaderView::QxtHeaderView(Qt::Orientation orientation, QWidget* parent)
        : QHeaderView(orientation, parent)
{
    QXT_INIT_PRIVATE(QxtHeaderView);
}

/*!
    \property QxtHeaderView::proportionalSectionSizes
    \brief This property holds whether section sizes are proportional.

    The default value is \bold true.

    \bold {Note:} Enabling proportional sections sizes sets resize mode
    \bold QHeaderView::Fixed, which means that the user cannot resize
    sections.
 */
bool QxtHeaderView::hasProportionalSectionSizes() const
{
    return qxt_d().proportional;
}

void QxtHeaderView::setProportionalSectionSizes(bool enabled)
{
    if (qxt_d().proportional != enabled)
    {
        qxt_d().proportional = enabled;
        if (enabled)
            setResizeMode(QHeaderView::Fixed);
    }
}

/*!
    Returns the stretch factor of the section at \a logicalIndex.

    \sa setSectionStretchFactor()
 */
int QxtHeaderView::sectionStretchFactor(int logicalIndex) const
{
    return qxt_d().factors.value(logicalIndex);
}

/*!
    Sets the stretch \a factor of the section at \a logicalIndex.

    \sa sectionStretchFactor()
 */
void QxtHeaderView::setSectionStretchFactor(int logicalIndex, int factor)
{
    qxt_d().factors.insert(logicalIndex, factor);
}

/*!
    \reimp
 */
void QxtHeaderView::resizeEvent(QResizeEvent* event)
{
    QHeaderView::resizeEvent(event);
    if (qxt_d().proportional)
    {
        int total = 0;
        for (int i = 0; i < count(); ++i)
            total += qxt_d().factors.value(i, 1);

        int totalSize = 0;
        for (int i = 0; i < count() - 1; ++i)
        {
            qreal factor = qxt_d().factors.value(i, 1) / static_cast<qreal>(total);
            int sectionSize = factor * (orientation() == Qt::Horizontal ? width() : height());
            sectionSize = qMax(minimumSectionSize(), sectionSize);
            resizeSection(i, sectionSize);
            totalSize += sectionSize;
        }
        // avoid rounding errors, give rest to the last section
        resizeSection(count() - 1, width() - totalSize);
    }
}
<|endoftext|>


<commit_before>/**************************************************************************
   Copyright (c) 2021 sewenew

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 *************************************************************************/

#include "async_connection.h"
#include <hiredis/async.h>
#include "errors.h"

namespace {

using namespace sw::redis;

void prepare_callback(redisAsyncContext *ctx, void *r, void *) {
    assert(ctx != nullptr);

    auto &connection = *(static_cast<AsyncConnectionSPtr *>(ctx->data));

    redisReply *reply = static_cast<redisReply *>(r);
    if (reply == nullptr) {
        // Connection has bee closed.
        //connection->reset();
        // TODO: not sure if we should set this to be DISCONNECTING
        return;
    }

    try {
        if (reply::is_error(*reply)) {
            throw_error(*reply);
        }

        reply::parse<void>(*reply);

        connection->prepare();
    } catch (const Error &e) {
        connection->disconnect(std::make_exception_ptr(e));
    }
}

}

namespace sw {

namespace redis {

FormattedCommand::FormattedCommand(char *data, int len) : _data(data), _size(len) {
    if (data == nullptr || len < 0) {
        throw Error("failed to format command");
    }
}

FormattedCommand::~FormattedCommand() noexcept {
    if (_data != nullptr) {
        redisFreeCommand(_data);
    }
}

void FormattedCommand::_move(FormattedCommand &&that) noexcept {
    _data = that._data;
    _size = that._size;
    that._data = nullptr;
    that._size = 0;
}

AsyncConnection::AsyncConnection(const ConnectionOptions &opts,
        EventLoop *loop) : _opts(opts), _loop(loop) {}

void AsyncConnection::prepare() {
    try {
        switch (_status) {
        case AsyncConnectionStatus::CONNECTED:
            if (_need_auth()) {
                _auth();
            } else if (_need_select_db()) {
                _select_db();
            } else {
                _status = AsyncConnectionStatus::READY;
            }

            break;

        case AsyncConnectionStatus::AUTH:
            if (_need_select_db()) {
                _select_db();
            } else {
                _status = AsyncConnectionStatus::READY;
            }

            break;

        case AsyncConnectionStatus::SELECT_DB:
            _status = AsyncConnectionStatus::READY;
            break;

        default:
            assert(false);
            break;
        }

        if (_status == AsyncConnectionStatus::READY) {
            // In case, there're pending commands.
            _loop->notify();
        }
    } catch (const Error &e) {
        disconnect(std::make_exception_ptr(e));
    }
}

std::exception_ptr AsyncConnection::error() {
    switch (_status) {
    case AsyncConnectionStatus::DISCONNECTED:
        return std::make_exception_ptr(Error("connection has been closed"));

    case AsyncConnectionStatus::UNINITIALIZED:
        return std::make_exception_ptr(Error("connection is uninitialized"));

    default:
        break;
    }

    return _err;
}

void AsyncConnection::reconnect() {
    auto ctx = _connect(_opts);

    assert(ctx && ctx->err == REDIS_OK);

    _loop->attach(*ctx);

    _ctx = ctx.release();

    _status = AsyncConnectionStatus::CONNECTING;
}

void AsyncConnection::disconnect(std::exception_ptr err) {
    // TODO: what if this method throw?
    _loop->unwatch(shared_from_this());

    _err = err;
    _status = AsyncConnectionStatus::DISCONNECTING;
}

bool AsyncConnection::_need_auth() const {
    return !_opts.password.empty() || _opts.user != "default";
}

void AsyncConnection::_auth() {
    assert(!broken());

    if (_opts.user == "default") {
        if (redisAsyncCommand(_ctx, prepare_callback, nullptr, "AUTH %b",
                    _opts.password.data(), _opts.password.size()) != REDIS_OK) {
            throw Error("failed to send auth command");
        }
    } else {
        // Redis 6.0 or latter
        if (redisAsyncCommand(_ctx, prepare_callback, nullptr, "AUTH %b %b",
                    _opts.user.data(), _opts.user.size(),
                    _opts.password.data(), _opts.password.size()) != REDIS_OK) {
            throw Error("failed to send auth command");
        }
    }

    _status = AsyncConnectionStatus::AUTH;
}

bool AsyncConnection::_need_select_db() const {
    return _opts.db != 0;
}

void AsyncConnection::_select_db() {
    assert(!broken());

    if (redisAsyncCommand(_ctx, prepare_callback, nullptr, "SELECT %lld",
            _opts.db) != REDIS_OK) {
        throw Error("failed to send select command");
    }

    _status = AsyncConnectionStatus::SELECT_DB;
}

void AsyncConnection::_clean_async_context(void *data) {
    auto *connection = static_cast<AsyncConnectionSPtr *>(data);

    assert(connection != nullptr);

    delete connection;
}

AsyncConnection::AsyncContextUPtr AsyncConnection::_connect(const ConnectionOptions &opts) {
    redisAsyncContext *context = nullptr;
    switch (opts.type) {
    case ConnectionType::TCP:
        context = redisAsyncConnect(opts.host.c_str(), _opts.port);
        break;

    case ConnectionType::UNIX:
        context = redisAsyncConnectUnix(opts.path.c_str());
        break;

    default:
        // Never goes here.
        throw Error("Unknown connection type");
    }

    if (context == nullptr) {
        throw Error("Failed to allocate memory for connection.");
    }

    auto ctx = AsyncContextUPtr(context);
    if (ctx->err != REDIS_OK) {
        throw_error(ctx->c, "failed to connect to server");
    }

    ctx->data = new AsyncConnectionSPtr(shared_from_this());
    ctx->dataCleanup = _clean_async_context;

    return ctx;
}

}

}
<commit_msg>bug fix: type mismatch when calling redisAsyncCommand<commit_after>/**************************************************************************
   Copyright (c) 2021 sewenew

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 *************************************************************************/

#include "async_connection.h"
#include <hiredis/async.h>
#include "errors.h"

namespace {

using namespace sw::redis;

void prepare_callback(redisAsyncContext *ctx, void *r, void *) {
    assert(ctx != nullptr);

    auto &connection = *(static_cast<AsyncConnectionSPtr *>(ctx->data));

    redisReply *reply = static_cast<redisReply *>(r);
    if (reply == nullptr) {
        // Connection has bee closed.
        //connection->reset();
        // TODO: not sure if we should set this to be DISCONNECTING
        return;
    }

    try {
        if (reply::is_error(*reply)) {
            throw_error(*reply);
        }

        reply::parse<void>(*reply);

        connection->prepare();
    } catch (const Error &e) {
        connection->disconnect(std::make_exception_ptr(e));
    }
}

}

namespace sw {

namespace redis {

FormattedCommand::FormattedCommand(char *data, int len) : _data(data), _size(len) {
    if (data == nullptr || len < 0) {
        throw Error("failed to format command");
    }
}

FormattedCommand::~FormattedCommand() noexcept {
    if (_data != nullptr) {
        redisFreeCommand(_data);
    }
}

void FormattedCommand::_move(FormattedCommand &&that) noexcept {
    _data = that._data;
    _size = that._size;
    that._data = nullptr;
    that._size = 0;
}

AsyncConnection::AsyncConnection(const ConnectionOptions &opts,
        EventLoop *loop) : _opts(opts), _loop(loop) {}

void AsyncConnection::prepare() {
    try {
        switch (_status) {
        case AsyncConnectionStatus::CONNECTED:
            if (_need_auth()) {
                _auth();
            } else if (_need_select_db()) {
                _select_db();
            } else {
                _status = AsyncConnectionStatus::READY;
            }

            break;

        case AsyncConnectionStatus::AUTH:
            if (_need_select_db()) {
                _select_db();
            } else {
                _status = AsyncConnectionStatus::READY;
            }

            break;

        case AsyncConnectionStatus::SELECT_DB:
            _status = AsyncConnectionStatus::READY;
            break;

        default:
            assert(false);
            break;
        }

        if (_status == AsyncConnectionStatus::READY) {
            // In case, there're pending commands.
            _loop->notify();
        }
    } catch (const Error &e) {
        disconnect(std::make_exception_ptr(e));
    }
}

std::exception_ptr AsyncConnection::error() {
    switch (_status) {
    case AsyncConnectionStatus::DISCONNECTED:
        return std::make_exception_ptr(Error("connection has been closed"));

    case AsyncConnectionStatus::UNINITIALIZED:
        return std::make_exception_ptr(Error("connection is uninitialized"));

    default:
        break;
    }

    return _err;
}

void AsyncConnection::reconnect() {
    auto ctx = _connect(_opts);

    assert(ctx && ctx->err == REDIS_OK);

    _loop->attach(*ctx);

    _ctx = ctx.release();

    _status = AsyncConnectionStatus::CONNECTING;
}

void AsyncConnection::disconnect(std::exception_ptr err) {
    // TODO: what if this method throw?
    _loop->unwatch(shared_from_this());

    _err = err;
    _status = AsyncConnectionStatus::DISCONNECTING;
}

bool AsyncConnection::_need_auth() const {
    return !_opts.password.empty() || _opts.user != "default";
}

void AsyncConnection::_auth() {
    assert(!broken());

    if (_opts.user == "default") {
        if (redisAsyncCommand(_ctx, prepare_callback, nullptr, "AUTH %b",
                    _opts.password.data(), _opts.password.size()) != REDIS_OK) {
            throw Error("failed to send auth command");
        }
    } else {
        // Redis 6.0 or latter
        if (redisAsyncCommand(_ctx, prepare_callback, nullptr, "AUTH %b %b",
                    _opts.user.data(), _opts.user.size(),
                    _opts.password.data(), _opts.password.size()) != REDIS_OK) {
            throw Error("failed to send auth command");
        }
    }

    _status = AsyncConnectionStatus::AUTH;
}

bool AsyncConnection::_need_select_db() const {
    return _opts.db != 0;
}

void AsyncConnection::_select_db() {
    assert(!broken());

    if (redisAsyncCommand(_ctx, prepare_callback, nullptr, "SELECT %d",
            _opts.db) != REDIS_OK) {
        throw Error("failed to send select command");
    }

    _status = AsyncConnectionStatus::SELECT_DB;
}

void AsyncConnection::_clean_async_context(void *data) {
    auto *connection = static_cast<AsyncConnectionSPtr *>(data);

    assert(connection != nullptr);

    delete connection;
}

AsyncConnection::AsyncContextUPtr AsyncConnection::_connect(const ConnectionOptions &opts) {
    redisAsyncContext *context = nullptr;
    switch (opts.type) {
    case ConnectionType::TCP:
        context = redisAsyncConnect(opts.host.c_str(), _opts.port);
        break;

    case ConnectionType::UNIX:
        context = redisAsyncConnectUnix(opts.path.c_str());
        break;

    default:
        // Never goes here.
        throw Error("Unknown connection type");
    }

    if (context == nullptr) {
        throw Error("Failed to allocate memory for connection.");
    }

    auto ctx = AsyncContextUPtr(context);
    if (ctx->err != REDIS_OK) {
        throw_error(ctx->c, "failed to connect to server");
    }

    ctx->data = new AsyncConnectionSPtr(shared_from_this());
    ctx->dataCleanup = _clean_async_context;

    return ctx;
}

}

}
<|endoftext|>