<commit_before>/*
* Copyright 2017 Axel Waggershauser
* Copyright 2013 ZXing authors
*
* 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 "datamatrix/DMWriter.h"
#include "datamatrix/DMDecoder.h"
#include "datamatrix/DMEncoderContext.h"
#include "DecoderResult.h"
#include "DecodeStatus.h"
#include "BitMatrix.h"
#include "BitMatrixUtility.h"
#include "PseudoRandom.h"
#include "ZXContainerAlgorithms.h"

#include "fstream"

namespace testing {
	namespace internal {
		inline bool operator==(const std::string& a, const std::wstring& b) {
			return a.length() == b.length() && std::equal(a.begin(), a.end(), b.begin());
		}
	}
}

#include "gtest/gtest.h"

using namespace ZXing;

namespace {

	void TestEncodeDecode(const std::wstring& data, DataMatrix::SymbolShape shape = DataMatrix::SymbolShape::SQUARE)
	{
		DataMatrix::Writer writer;
		writer.setShapeHint(shape);
		BitMatrix matrix = writer.encode(data, 0, 0);
		ASSERT_EQ(matrix.empty(), false);

		DecoderResult res = DataMatrix::Decoder::Decode(matrix);
#ifndef NDEBUG
		if (!res.isValid() || data != res.text())
			Utility::WriteBitMatrixAsPBM(matrix, std::ofstream("failed-datamatrix.pbm"), 4);
#endif
		ASSERT_EQ(res.isValid(), true) << "text size: " << data.size() << ", code size: " << matrix.height() << "x"
									   << matrix.width() << "\n"
									   << (matrix.width() < 80 ? Utility::ToString(matrix) : std::string());
		EXPECT_EQ(data, res.text()) << "text size: " << data.size() << ", code size: " << matrix.height() << "x"
									<< matrix.width() << "\n"
									<< (matrix.width() < 80 ? Utility::ToString(matrix) : std::string());
	}
}

TEST(DMEncodeDecodeTest, EncodeDecodeSquare)
{
	std::wstring text[] = {
	    L"Abc123!",
	    L"Lorem ipsum. http://test/",
	    L"AAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAAN",
	    L"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384",
	    L"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384756<>/?abc"
		"Four score and seven our forefathers brought forth",
	    L"In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
	    " cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
		" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
		" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
		" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
	    " elementum sapien dolor et diam.",
	    L"In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
	    " cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
		" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
		" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
		" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
		" elementum sapien dolor et diam. Donec ac nunc sodales elit placerat eleifend."
		" Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus"
		" justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu"
		" tristique ac, p.In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus"
		" quis diam cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec"
		" laoreet rutrum est, nec convallis mauris condimentum sit amet. Phasellus gravida,"
		" justo et congue auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec"
		" lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar"
		" nisi, id elementum sapien dolor et diam. Donec ac nunc sodales elit placerat"
		" eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra"
		" fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo"
		" diam, lobortis eu tristique ac, p. In ut magna vel mauris malesuada dictum. Nulla"
		" ullamcorper metus quis diam cursus facilisis. Sed mollis quam id justo rutrum"
		" sagittis. Donec laoreet rutrum est, nec convallis mauris condimentum sit amet."
		" Phasellus gravida, justo et congue auctor, nisi ipsum viverra erat, eget hendrerit"
		" felis turpis nec lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo"
		" erat pulvinar nisi, id elementum sapien dolor et diam.",
	};

	for (auto data : text)
		TestEncodeDecode(data);
}

TEST(DMEncodeDecodeTest, EncodeDecodeRectangle)
{
	std::wstring text[] = {
	    L"Abc123!",
	    L"Lorem ipsum. http://test/",
	    L"AAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAAN",
	    L"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384",
	    L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
	};

	for (auto data : text)
		for (size_t len	= 1; len <= data.size(); ++len)
			TestEncodeDecode(data.substr(0, len), DataMatrix::SymbolShape::RECTANGLE);
}

TEST(DMEncodeDecodeTest, EDIFACTWithEOD)
{
	TestEncodeDecode(L"https://test~[******]_");
	TestEncodeDecode(L"abc<->ABCDE");
}

<commit_msg>DMEncodeDecodeTest: add 3 more test strings<commit_after>/*
* Copyright 2017 Axel Waggershauser
* Copyright 2013 ZXing authors
*
* 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 "datamatrix/DMWriter.h"
#include "datamatrix/DMDecoder.h"
#include "datamatrix/DMEncoderContext.h"
#include "DecoderResult.h"
#include "DecodeStatus.h"
#include "BitMatrix.h"
#include "BitMatrixUtility.h"
#include "PseudoRandom.h"
#include "ZXContainerAlgorithms.h"

#include "fstream"

namespace testing {
	namespace internal {
		inline bool operator==(const std::string& a, const std::wstring& b) {
			return a.length() == b.length() && std::equal(a.begin(), a.end(), b.begin());
		}
	}
}

#include "gtest/gtest.h"

using namespace ZXing;

namespace {

	void TestEncodeDecode(const std::wstring& data, DataMatrix::SymbolShape shape = DataMatrix::SymbolShape::SQUARE)
	{
		DataMatrix::Writer writer;
		writer.setShapeHint(shape);
		BitMatrix matrix = writer.encode(data, 0, 0);
		ASSERT_EQ(matrix.empty(), false);

		DecoderResult res = DataMatrix::Decoder::Decode(matrix);
#ifndef NDEBUG
		if (!res.isValid() || data != res.text())
			Utility::WriteBitMatrixAsPBM(matrix, std::ofstream("failed-datamatrix.pbm"), 4);
#endif
		ASSERT_EQ(res.isValid(), true) << "text size: " << data.size() << ", code size: " << matrix.height() << "x"
									   << matrix.width() << "\n"
									   << (matrix.width() < 80 ? Utility::ToString(matrix) : std::string());
		EXPECT_EQ(data, res.text()) << "text size: " << data.size() << ", code size: " << matrix.height() << "x"
									<< matrix.width() << "\n"
									<< (matrix.width() < 80 ? Utility::ToString(matrix) : std::string());
	}
}

TEST(DMEncodeDecodeTest, EncodeDecodeSquare)
{
	std::wstring text[] = {
	    L"Abc123!",
	    L"Lorem ipsum. http://test/",
	    L"AAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAAN",
	    L"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384",
	    L"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384756<>/?abc"
		"Four score and seven our forefathers brought forth",
	    L"In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
	    " cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
		" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
		" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
		" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
	    " elementum sapien dolor et diam.",
	    L"In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
	    " cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
		" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
		" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
		" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
		" elementum sapien dolor et diam. Donec ac nunc sodales elit placerat eleifend."
		" Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus"
		" justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu"
		" tristique ac, p.In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus"
		" quis diam cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec"
		" laoreet rutrum est, nec convallis mauris condimentum sit amet. Phasellus gravida,"
		" justo et congue auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec"
		" lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar"
		" nisi, id elementum sapien dolor et diam. Donec ac nunc sodales elit placerat"
		" eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra"
		" fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo"
		" diam, lobortis eu tristique ac, p. In ut magna vel mauris malesuada dictum. Nulla"
		" ullamcorper metus quis diam cursus facilisis. Sed mollis quam id justo rutrum"
		" sagittis. Donec laoreet rutrum est, nec convallis mauris condimentum sit amet."
		" Phasellus gravida, justo et congue auctor, nisi ipsum viverra erat, eget hendrerit"
		" felis turpis nec lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo"
		" erat pulvinar nisi, id elementum sapien dolor et diam.",
	};

	for (auto data : text)
		TestEncodeDecode(data);
}

TEST(DMEncodeDecodeTest, EncodeDecodeRectangle)
{
	std::wstring text[] = {
	    L"Abc123!",
	    L"Lorem ipsum. http://test/",
	    L"3i0QnD^RcZO[\\#!]1,9zIJ{1z3qrvsq",
	    L"AAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAAN",
	    L"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384",
	    L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
	};

	for (auto data : text)
		for (size_t len	= 1; len <= data.size(); ++len)
			TestEncodeDecode(data.substr(0, len), DataMatrix::SymbolShape::RECTANGLE);
}

TEST(DMEncodeDecodeTest, EDIFACTWithEOD)
{
	TestEncodeDecode(L"https://test~[******]_");
	TestEncodeDecode(L"abc<->ABCDE");
	TestEncodeDecode(L"<ABCDEFG><ABCDEFGK>");
	TestEncodeDecode(L"*CH/GN1/022/00");
}

<|endoftext|>


<commit_before>// This file is part of The New Aspell
// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
// version 2.0 or 2.1.  You should have received a copy of the LGPL
// license along with this library if you did not you can find
// it at http://www.gnu.org/.

#ifndef ASPELL_STRING__HPP
#define ASPELL_STRING__HPP

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

#include <algorithm>

#include "hash_fun.hpp"
#include "parm_string.hpp"
#include "mutable_string.hpp"
#include "ostream.hpp"
#include "istream.hpp"

namespace acommon {

  template <typename Ret> class PosibErr;

  class String : public OStream
  {
  public:
    typedef const char * const_iterator;
    typedef char *       iterator;
    typedef size_t       size_type;

  private:
    // if begin_ != 0 than storage_end_ - begin_ > 1
    char * begin_;
    char * end_;
    char * storage_end_;
    void assign_only(const char * b, size_t size)
    {
      begin_ = (char *)malloc(size + 1);
      memcpy(begin_, b, size);
      end_   = begin_ + size;
      storage_end_ = end_ + 1;
    }
    void reserve_i(size_t s = 0);
  public:
    void reserve(size_t s)
    {
      if (storage_end_ - begin_ >= (int)s + 1) return;
      reserve_i(s);
    }

    char * begin() {return begin_;}
    char * end() {return end_;}

    const char * begin() const {return begin_;}
    const char * end()   const {return end_;}

    char * pbegin() {return begin_;}
    char * pend() {return end_;}

    const char * pbegin() const {return begin_;}
    const char * pend()   const {return end_;}

    size_t size() const {return end_ - begin_;}
    bool empty() const {return begin_ == end_;}
    size_t max_size() const {return INT_MAX;}
    size_t capacity() const {return storage_end_ ? storage_end_ - begin_ - 1 : 0;}

    void ensure_null_end() const {*end_ = '\0';}

    const char * c_str() const {
      if (begin_) {ensure_null_end(); return begin_;}
      else return "";
    }
    const char * str() const {return c_str();}
    char * mstr()
    {
      if (!begin_) reserve_i();
      ensure_null_end();
      return begin_;
    }

    char * data() {return begin_;}
    const char * data() const {return begin_;}

    char * data(int pos) {return begin_ + pos;}
    char * data_end() {return end_;}

    template <typename U>
    U * datap() {
      return reinterpret_cast<U * >(begin_);
    }
    template <typename U>
    U * datap(int pos) {
      return reinterpret_cast<U * >(begin_ + pos);
    }

    char & operator[] (size_t pos) {return begin_[pos];}
    const char operator[] (size_t pos) const {return begin_[pos];}

    char & back() {return end_[-1];}
    const char back() const {return end_[-1];}

    void clear() {end_ = begin_;}

    //
    // constructors
    //

    String() : begin_(0), end_(0), storage_end_(0) {}
    String(const char * s) {assign_only(s, strlen(s));}
    String(const char * s, unsigned int size) {assign_only(s, size);}
    String(ParmString s) {assign_only(s, s.size());}
    String(MutableString s) {assign_only(s.str, s.size);}
    String(const String & other) {assign_only(other.begin_, other.end_-other.begin_);}
#ifndef __SUNPRO_CC
    // This causes a conflict with the copy constructor on Suns comp
    inline String(const PosibErr<String> & other);
#endif

    //
    // assign
    //

    void assign(const char * b, size_t size)
    {
      clear();
      if (size != 0) {
        reserve(size);
        memcpy(begin_, b, size);
        end_   = begin_ + size;
      }
    }
    void assign(const char * b)
    {
      assign(b, strlen(b));
    }
    String & operator= (const char * s) {
      assign(s);
      return *this;
    }
    inline String & operator= (const PosibErr<const char *> & s);
    String & operator= (ParmString s) {
      assign(s, s.size());
      return *this;
    }
    String & operator= (MutableString s) {
      assign(s.str, s.size);
      return *this;
    }
    String & operator= (const String & s) {
      assign(s.begin_, s.end_ - s.begin_);
      return *this;
    }
    /*inline*/ String & operator= (const PosibErr<String> & s);

    //
    // append
    //

    void append(const void * str, unsigned int sz)
    {
      reserve(size() + sz);
      memcpy(end_, str, sz);
      end_ += sz;
    }
    void append(const void * d, const void * e)
    {
      append(d, (const char *)e - (const char *)d);
    }
    void append(String & str, unsigned int sz)
    {
      append(str.begin_, sz);
    }
    void append(const char * str)
    {
      if (!end_) reserve_i();
      for (; *str && end_ != storage_end_ - 1; ++str, ++end_)
        *end_ = *str;
      if (end_ == storage_end_ - 1) append(str, strlen(str));
    }
    void append(char c)
    {
      reserve(size() + 1);
      *end_ = c;
      ++end_;
    }

    String & operator+= (const char * s) {
      append(s);
      return *this;
    }
    String & operator+= (char c) {
      append(c);
      return *this;
    }
    String & operator+= (ParmString s) {
      if (s.have_size())
        append(s, s.size());
      else
        append(s);
      return *this;
    }
    String & operator+= (MutableString s) {
      append(s.str, s.size);
      return *this;
    }
    String & operator+= (const String & s) {
      append(s.begin_, s.end_ - s.begin_);
      return *this;
    }

    //
    //
    //

    ~String() {if (begin_) free(begin_);}

    void swap(String & other) {
      std::swap(begin_, other.begin_);
      std::swap(end_, other.end_);
      std::swap(storage_end_, other.storage_end_);
    }

    //
    //
    //

    int vprintf(const char * format, va_list ap);

    //
    //
    //

    void push_back(char c) {append(c);}

    void pop_back(size_t p = 1) {end_ -= p;}

    char * insert(size_t p, char c)
    {
      reserve(size() + 1);
      char * pos = begin_ + p;
      size_t to_move = end_ - pos;
      if (to_move) memmove(pos + 1, pos, to_move);
      *pos = c;
      ++end_;
      return pos;
    }
    char * insert(char * pos, char c)
    {
      return insert(pos - begin_, c);
    }
    void insert(size_t p, const char * str, size_t sz)
    {
      reserve(size() + sz);
      char * pos = begin_ + p;
      size_t to_move = end_ - pos;
      if (to_move) memmove(pos + sz, pos, to_move);
      memcpy(pos, str, sz);
      end_ += sz;
    }
    void insert(char * pos, const char * f, const char * l)
    {
      insert(pos - begin_, f, l - f);
    }

    char * erase(char * pos)
    {
      size_t to_move = end_ - pos - 1;
      if (to_move) memmove(pos, pos + 1, to_move);
      --end_;
      return pos;
    }
    char * erase(char * f, char * l)
    {
      if (l >= end_) {
        end_ = f < end_ ? f : end_;
      } else {
        size_t sz = l - f;
        memmove(f, f + sz, end_ - l);
        end_ -= sz;
      }
      return f;
    }
    void erase(size_t pos, size_t s)
    {
      erase(begin_ + pos, begin_ + pos + s);
    }

    //FIXME: Make this more efficent by rewriting the implemenation
    //       to work with raw memory rather than using vector<char>
    template <typename Itr>
    void replace(iterator start, iterator stop, Itr rstart, Itr rstop)
    {
      iterator i = erase(start,stop);
      insert(i, rstart, rstop);
    }

    void replace(size_t pos, size_t n, const char * with, size_t s)
    {
      replace(begin_ + pos, begin_ + pos + n, with, with + s);
    }
    void resize(size_t n)
    {
      reserve(n);
      end_ = begin_ + n;
    }
    void resize(size_t n, char c)
    {
      size_t old_size = size();
      reserve(n);
      end_ = begin_ + n;
      int diff = n - old_size;
      if (diff > 0) memset(begin_ + old_size, c, diff);
    }
    int alloc(int s) {
      int pos = size();
      resize(pos + s);
      return pos;
    }

    bool prefix(ParmString str, size_t offset) const
    {
      if (str.size() > size() - offset) return false;
      return memcmp(begin_ + offset, str.str(), str.size()) == 0;
    };
    bool suffix(ParmString str) const
    {
      if (str.size() > size()) return false;
      return memcmp(end_ - str.size(), str.str(), str.size()) == 0;
    }

    // FIXME: Eventually remove
    static const size_t npos = INT_MAX;
    size_t length() const {return size();}
    size_t find(char c, size_t pos = 0) const {
      char * res = (char *)memchr(begin_ + pos, c, size() - pos);
      if (res == 0) return npos;
      else return res - begin_;
    }
    size_t rfind(char c) const {
      char * res = (char *)memrchr(begin_, c, size());
      if (res == 0) return npos;
      else return res - begin_;
    }
    String substr(size_t pos = 0, size_t n = npos) const
    {
      if (n == npos)
        return String(begin_ + pos, size() - pos);
      else
        return String(begin_ + pos, n);
    }
    // END FIXME

    unsigned short & at16(unsigned int pos)
      {return reinterpret_cast<unsigned short &>(operator[](pos));}
    unsigned int   & at32(unsigned int pos)
      {return reinterpret_cast<unsigned int &>(operator[](pos));}

    void write (char c) {append(c);}
    void write (ParmString str) {operator+=(str);}
    void write (const void * str, unsigned int sz) {append(str,sz);}

    String & operator << (ParmString str) {
      append(str);
      return *this;
    }

    String & operator << (char c) {
      append(c);
      return *this;
    }
  };

  inline String operator+ (ParmString rhs, ParmString lhs)
  {
    String tmp;
    tmp.reserve(rhs.size() + lhs.size());
    tmp += rhs;
    tmp += lhs;
    return tmp;
  }

  inline ParmString::ParmString(const String & s) : str_(s.c_str()), size_(s.size()) {}

  class StringIStream : public IStream {
    const char * in_str;
    char         delem;
  public:
    StringIStream(ParmString s, char d = ';')
      : IStream(d), in_str(s) {}
    bool append_line(String & str, char c);
    bool read(void * data, unsigned int size);
  };

  template <> struct hash<String> : public HashString<String> {};

  inline bool IStream::getline(String & str, char c)
  {
    str.clear();
    return append_line(str,c);
  }

  inline bool IStream::getline(String & str)
  {
    str.clear();
    return append_line(str,delem);
  }

}

namespace std
{
  template<> static inline void swap(acommon::String & x, acommon::String & y) {return x.swap(y);}
}

#endif
<commit_msg>enhanced append methods<commit_after>// This file is part of The New Aspell
// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
// version 2.0 or 2.1.  You should have received a copy of the LGPL
// license along with this library if you did not you can find
// it at http://www.gnu.org/.

#ifndef ASPELL_STRING__HPP
#define ASPELL_STRING__HPP

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

#include <algorithm>

#include "hash_fun.hpp"
#include "parm_string.hpp"
#include "mutable_string.hpp"
#include "ostream.hpp"
#include "istream.hpp"

namespace acommon {

  template <typename Ret> class PosibErr;

  class String : public OStream
  {
  public:
    typedef const char * const_iterator;
    typedef char *       iterator;
    typedef size_t       size_type;

  private:
    // if begin_ != 0 than storage_end_ - begin_ > 1
    char * begin_;
    char * end_;
    char * storage_end_;
    void assign_only(const char * b, size_t size)
    {
      begin_ = (char *)malloc(size + 1);
      memcpy(begin_, b, size);
      end_   = begin_ + size;
      storage_end_ = end_ + 1;
    }
    void reserve_i(size_t s = 0);
  public:
    void reserve(size_t s)
    {
      if (storage_end_ - begin_ >= (int)s + 1) return;
      reserve_i(s);
    }

    char * begin() {return begin_;}
    char * end() {return end_;}

    const char * begin() const {return begin_;}
    const char * end()   const {return end_;}

    char * pbegin() {return begin_;}
    char * pend() {return end_;}

    const char * pbegin() const {return begin_;}
    const char * pend()   const {return end_;}

    size_t size() const {return end_ - begin_;}
    bool empty() const {return begin_ == end_;}
    size_t max_size() const {return INT_MAX;}
    size_t capacity() const {return storage_end_ ? storage_end_ - begin_ - 1 : 0;}

    void ensure_null_end() const {*end_ = '\0';}

    const char * c_str() const {
      if (begin_) {ensure_null_end(); return begin_;}
      else return "";
    }
    const char * str() const {return c_str();}
    char * mstr()
    {
      if (!begin_) reserve_i();
      ensure_null_end();
      return begin_;
    }

    char * data() {return begin_;}
    const char * data() const {return begin_;}

    char * data(int pos) {return begin_ + pos;}
    char * data_end() {return end_;}

    template <typename U>
    U * datap() {
      return reinterpret_cast<U * >(begin_);
    }
    template <typename U>
    U * datap(int pos) {
      return reinterpret_cast<U * >(begin_ + pos);
    }

    char & operator[] (size_t pos) {return begin_[pos];}
    const char operator[] (size_t pos) const {return begin_[pos];}

    char & back() {return end_[-1];}
    const char back() const {return end_[-1];}

    void clear() {end_ = begin_;}

    //
    // constructors
    //

    String() : begin_(0), end_(0), storage_end_(0) {}
    String(const char * s) {assign_only(s, strlen(s));}
    String(const char * s, unsigned int size) {assign_only(s, size);}
    String(ParmString s) {assign_only(s, s.size());}
    String(MutableString s) {assign_only(s.str, s.size);}
    String(const String & other) {assign_only(other.begin_, other.end_-other.begin_);}
#ifndef __SUNPRO_CC
    // This causes a conflict with the copy constructor on Suns comp
    inline String(const PosibErr<String> & other);
#endif

    //
    // assign
    //

    void assign(const char * b, size_t size)
    {
      clear();
      if (size != 0) {
        reserve(size);
        memcpy(begin_, b, size);
        end_   = begin_ + size;
      }
    }
    void assign(const char * b)
    {
      assign(b, strlen(b));
    }
    String & operator= (const char * s) {
      assign(s);
      return *this;
    }
    inline String & operator= (const PosibErr<const char *> & s);
    String & operator= (ParmString s) {
      assign(s, s.size());
      return *this;
    }
    String & operator= (MutableString s) {
      assign(s.str, s.size);
      return *this;
    }
    String & operator= (const String & s) {
      assign(s.begin_, s.end_ - s.begin_);
      return *this;
    }
    /*inline*/ String & operator= (const PosibErr<String> & s);

    //
    // append
    //

    String & append(const void * str, unsigned int sz)
    {
      reserve(size() + sz);
      memcpy(end_, str, sz);
      end_ += sz;
      return *this;
    }
    String & append(const void * d, const void * e)
    {
      append(d, (const char *)e - (const char *)d);
      return *this;
    }
    String & append(String & str, unsigned int sz)
    {
      append(str.begin_, sz);
      return *this;
    }
    String & append(const char * str)
    {
      if (!end_) reserve_i();
      for (; *str && end_ != storage_end_ - 1; ++str, ++end_)
        *end_ = *str;
      if (end_ == storage_end_ - 1) append(str, strlen(str));
      return *this;
    }
    String & append(char c)
    {
      reserve(size() + 1);
      *end_ = c;
      ++end_;
      return *this;
    }

    String & operator+= (const char * s) {
      append(s);
      return *this;
    }
    String & operator+= (char c) {
      append(c);
      return *this;
    }
    String & operator+= (ParmString s) {
      if (s.have_size())
        append(s, s.size());
      else
        append(s);
      return *this;
    }
    String & operator+= (MutableString s) {
      append(s.str, s.size);
      return *this;
    }
    String & operator+= (const String & s) {
      append(s.begin_, s.end_ - s.begin_);
      return *this;
    }

    //
    //
    //

    ~String() {if (begin_) free(begin_);}

    void swap(String & other) {
      std::swap(begin_, other.begin_);
      std::swap(end_, other.end_);
      std::swap(storage_end_, other.storage_end_);
    }

    //
    //
    //

    int vprintf(const char * format, va_list ap);

    //
    //
    //

    void push_back(char c) {append(c);}

    void pop_back(size_t p = 1) {end_ -= p;}

    char * insert(size_t p, char c)
    {
      reserve(size() + 1);
      char * pos = begin_ + p;
      size_t to_move = end_ - pos;
      if (to_move) memmove(pos + 1, pos, to_move);
      *pos = c;
      ++end_;
      return pos;
    }
    char * insert(char * pos, char c)
    {
      return insert(pos - begin_, c);
    }
    void insert(size_t p, const char * str, size_t sz)
    {
      reserve(size() + sz);
      char * pos = begin_ + p;
      size_t to_move = end_ - pos;
      if (to_move) memmove(pos + sz, pos, to_move);
      memcpy(pos, str, sz);
      end_ += sz;
    }
    void insert(char * pos, const char * f, const char * l)
    {
      insert(pos - begin_, f, l - f);
    }

    char * erase(char * pos)
    {
      size_t to_move = end_ - pos - 1;
      if (to_move) memmove(pos, pos + 1, to_move);
      --end_;
      return pos;
    }
    char * erase(char * f, char * l)
    {
      if (l >= end_) {
        end_ = f < end_ ? f : end_;
      } else {
        size_t sz = l - f;
        memmove(f, f + sz, end_ - l);
        end_ -= sz;
      }
      return f;
    }
    void erase(size_t pos, size_t s)
    {
      erase(begin_ + pos, begin_ + pos + s);
    }

    //FIXME: Make this more efficent by rewriting the implemenation
    //       to work with raw memory rather than using vector<char>
    template <typename Itr>
    void replace(iterator start, iterator stop, Itr rstart, Itr rstop)
    {
      iterator i = erase(start,stop);
      insert(i, rstart, rstop);
    }

    void replace(size_t pos, size_t n, const char * with, size_t s)
    {
      replace(begin_ + pos, begin_ + pos + n, with, with + s);
    }
    void resize(size_t n)
    {
      reserve(n);
      end_ = begin_ + n;
    }
    void resize(size_t n, char c)
    {
      size_t old_size = size();
      reserve(n);
      end_ = begin_ + n;
      int diff = n - old_size;
      if (diff > 0) memset(begin_ + old_size, c, diff);
    }
    int alloc(int s) {
      int pos = size();
      resize(pos + s);
      return pos;
    }

    bool prefix(ParmString str, size_t offset) const
    {
      if (str.size() > size() - offset) return false;
      return memcmp(begin_ + offset, str.str(), str.size()) == 0;
    };
    bool suffix(ParmString str) const
    {
      if (str.size() > size()) return false;
      return memcmp(end_ - str.size(), str.str(), str.size()) == 0;
    }

    // FIXME: Eventually remove
    static const size_t npos = INT_MAX;
    size_t length() const {return size();}
    size_t find(char c, size_t pos = 0) const {
      char * res = (char *)memchr(begin_ + pos, c, size() - pos);
      if (res == 0) return npos;
      else return res - begin_;
    }
    size_t rfind(char c) const {
      char * res = (char *)memrchr(begin_, c, size());
      if (res == 0) return npos;
      else return res - begin_;
    }
    String substr(size_t pos = 0, size_t n = npos) const
    {
      if (n == npos)
        return String(begin_ + pos, size() - pos);
      else
        return String(begin_ + pos, n);
    }
    // END FIXME

    unsigned short & at16(unsigned int pos)
      {return reinterpret_cast<unsigned short &>(operator[](pos));}
    unsigned int   & at32(unsigned int pos)
      {return reinterpret_cast<unsigned int &>(operator[](pos));}

    void write (char c) {append(c);}
    void write (ParmString str) {operator+=(str);}
    void write (const void * str, unsigned int sz) {append(str,sz);}

    String & operator << (ParmString str) {
      append(str);
      return *this;
    }

    String & operator << (char c) {
      append(c);
      return *this;
    }
  };

  inline String operator+ (ParmString rhs, ParmString lhs)
  {
    String tmp;
    tmp.reserve(rhs.size() + lhs.size());
    tmp += rhs;
    tmp += lhs;
    return tmp;
  }

  inline ParmString::ParmString(const String & s) : str_(s.c_str()), size_(s.size()) {}

  class StringIStream : public IStream {
    const char * in_str;
    char         delem;
  public:
    StringIStream(ParmString s, char d = ';')
      : IStream(d), in_str(s) {}
    bool append_line(String & str, char c);
    bool read(void * data, unsigned int size);
  };

  template <> struct hash<String> : public HashString<String> {};

  inline bool IStream::getline(String & str, char c)
  {
    str.clear();
    return append_line(str,c);
  }

  inline bool IStream::getline(String & str)
  {
    str.clear();
    return append_line(str,delem);
  }

}

namespace std
{
  template<> static inline void swap(acommon::String & x, acommon::String & y) {return x.swap(y);}
}

#endif
<|endoftext|>


<commit_before>/*
 * D-Bus AT-SPI, Qt Adaptor
 *
 * Copyright 2011 Nokia Corporation and/or its subsidiary(-ies).
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qspiaccessibleinterface.h"

#include <qdebug.h>
#include <qdbusmessage.h>
#include <dbusconnection.h>
#include <qaccessible.h>

#include "constant_mappings.h"

QSpiAccessibleInterface::QSpiAccessibleInterface()
{
}

bool QSpiAccessibleInterface::handleMessage(QAccessibleInterface *interface, int child, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
{
    if (function == "GetRole") {
        QVariant v;
        v.setValue((uint) qSpiRoleMapping[interface->role(child)].spiRole());
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetName") {
        sendReply(connection, message, interface->text(QAccessible::Name, child));
        return true;
    } else if (function == "GetRoleName") {
        QVariant v;
        v.setValue(qSpiRoleMapping[interface->role(child)].name());
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetLocalizedRoleName") {
        QVariant v;
        v.setValue(qSpiRoleMapping[interface->role(child)].localizedName());
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetChildCount") {
        int childCount = child ? 0 : interface->childCount();
        sendReply(connection, message, childCount);
        return true;
    } else if (function == "GetIndexInParent") {
        int childIndex = -1;
        if (child) {
            childIndex = child;
        } else {
            QAccessibleInterface *parent = accessibleParent(interface, child);
            if (parent)
                childIndex = parent->indexOfChild(interface);
            delete parent;
        }
        sendReply(connection, message, childIndex);
        return true;
    } else if (function == "GetParent") {
        QAccessibleInterface *parent = accessibleParent(interface, child);

        QString path;
        if (!parent || parent->role(0) == QAccessible::Application) {
            path = QSPI_OBJECT_PATH_ROOT;
        } else {
            path = pathForInterface(parent, 0);
        }
        if (parent != interface)
            delete parent;

        QVariant ref;
        QSpiObjectReference v(connection, QDBusObjectPath(path));
        ref.setValue(v);
        sendReply(connection, message, ref);
        return true;
    } else if (function == "GetChildAtIndex") {
        int index = message.arguments().first().toInt();
        QString path;
        Q_ASSERT(child == 0);
        QAccessibleInterface *childInterface = 0;
        int childIndex = interface->navigate(QAccessible::Child, index+1, &childInterface);
        if (childIndex < 0)
            return false;
        if (childIndex == 0) {
            Q_ASSERT(childInterface);
            path = pathForInterface(childInterface, childIndex);
            delete childInterface;
        } else {
            path = pathForInterface(interface, childIndex);
        }

        QVariant ref;
        QSpiObjectReference v(connection, QDBusObjectPath(path));
        ref.setValue(v);
        QDBusMessage reply = message.createReply(ref);
        connection.send(reply);
        return true;
    } else if (function == "GetInterfaces") {
        QStringList ifaces;
        // FIXME
        ifaces << QSPI_INTERFACE_ACCESSIBLE;
        QVariant v;
        v.setValue(ifaces);
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetDescription") {
        sendReply(connection, message, interface->text(QAccessible::Description, child));
        return true;
    } else if (function == "GetState") {
        quint64 spiState = spiStatesFromQState(interface->state(child));
        if (interface->table2Interface()) {
            setSpiStateBit(&spiState, ATSPI_STATE_MANAGES_DESCENDANTS);
        }
        QVariant v;
        QSpiUIntList l = spiStateSetFromSpiStates(spiState);
        v.setValue(l);
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetAttributes") {
        QVariant attributes;
        attributes.setValue(QSpiAttributeSet());
        QDBusMessage reply = message.createReply(attributes);
        connection.send(reply);
        return true;
    } else if (function == "GetRelationSet") {
        QVariant relations;
        relations.setValue(relationSet(interface, child, connection));
        QDBusMessage reply = message.createReply(relations);
        connection.send(reply);
        return true;
    } else if (function == "GetApplication") {
        QVariant ref;
        QSpiObjectReference v(connection, QDBusObjectPath(QSPI_OBJECT_PATH_ROOT));
        ref.setValue(v);
        QDBusMessage reply = message.createReply(ref);
        connection.send(reply);
        return true;
    } else if (function == "GetChildren") {
        qDebug() << "IMPLEMENT GETCHILDREN";
        //    QSpiObjectReferenceArray ();
        return true;
    } else {
        qWarning() << "WARNING: QSpiAccessibleInterface::handleMessage does not implement " << function << message.path();
    }
    return false;
}

QSpiRelationArray QSpiAccessibleInterface::relationSet(QAccessibleInterface *interface, int child, const QDBusConnection &connection) const
{
    Q_ASSERT(child == 0);
    const QAccessible::RelationFlag relationsToCheck[] = {QAccessible::Label, QAccessible::Labelled, QAccessible::Controller, QAccessible::Controlled, static_cast<QAccessible::RelationFlag>(-1)};
    const AtspiRelationType relationTypes[] = {ATSPI_RELATION_LABELLED_BY, ATSPI_RELATION_LABEL_FOR, ATSPI_RELATION_CONTROLLED_BY, ATSPI_RELATION_CONTROLLER_FOR};

    QSpiRelationArray relations;
    QAccessibleInterface *target;

    for (int i = 0; relationsToCheck[i] >= 0; i++) {
        QList<QSpiObjectReference> related;
        int navigateResult = 1;

        for (int j = 1; navigateResult >= 0; j++) {
            navigateResult = interface->navigate(relationsToCheck[i], j, &target);

            if (navigateResult >= 0) {
                QDBusObjectPath path = QDBusObjectPath(pathForInterface(target ? target : interface, navigateResult));
                related.append(QSpiObjectReference(connection, path));
                delete target;
            }
        }
        if (!related.isEmpty())
            relations.append(QSpiRelationArrayEntry(relationTypes[i], related));
    }
    return relations;
}

void QSpiAccessibleInterface::sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QVariant &argument)
{
    sendReply(connection, message, QDBusVariant(argument));
}

void QSpiAccessibleInterface::sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QDBusVariant &argument)
{
    QDBusMessage reply = message.createReply(QVariant::fromValue(argument));
    connection.send(reply);
//    qDebug() << "SIGNATURE " << message.member() << reply.signature() << message.signature();
}

QAccessibleInterface *QSpiAccessibleInterface::accessibleParent(QAccessibleInterface *iface, int child)
{
    if (child)
        return iface;
    QAccessibleInterface *parent = 0;
    iface->navigate(QAccessible::Ancestor, 1, &parent);
    return parent;
}

QString QSpiAccessibleInterface::pathForObject(QObject *object)
{
    Q_ASSERT(object);
    return QSPI_OBJECT_PATH_PREFIX + QString::number(reinterpret_cast<size_t>(object));
}

QString QSpiAccessibleInterface::pathForInterface(QAccessibleInterface *interface, int childIndex)
{
    QString path;
    QAccessibleInterface* interfaceWithObject = interface;
    while(!interfaceWithObject->object()) {
        QAccessibleInterface* parentInterface;
        interfaceWithObject->navigate(QAccessible::Ancestor, 1, &parentInterface);
        Q_ASSERT(parentInterface->isValid());
        int index = parentInterface->indexOfChild(interfaceWithObject);
        //Q_ASSERT(index >= 0);
        // FIXME: This should never happen!
        if (index < 0) {

            index = 999;
            path.prepend("/BROKEN_OBJECT_HIERARCHY");
            qWarning() << "Object claims to have child that we cannot navigate to. FIX IT!" << parentInterface->object();

            qDebug() << "Original interface: " << interface->object() << index;
            qDebug() << "Parent interface: " << parentInterface->object() << " childcount:" << parentInterface->childCount();
            QObject* p = parentInterface->object();
            qDebug() << p->children();

            QAccessibleInterface* tttt;
            int id = parentInterface->navigate(QAccessible::Child, 1, &tttt);
            qDebug() << "Nav child: " << id << tttt->object();
        }
        path.prepend('/' + QString::number(index));
        interfaceWithObject = parentInterface;
    }
    path.prepend(QSPI_OBJECT_PATH_PREFIX + QString::number(reinterpret_cast<quintptr>(interfaceWithObject->object())));

    if (childIndex > 0) {
        path.append('/' + QString::number(childIndex));
    }
    return path;
}

<commit_msg>Don't assert when asking for relations for child==0.<commit_after>/*
 * D-Bus AT-SPI, Qt Adaptor
 *
 * Copyright 2011 Nokia Corporation and/or its subsidiary(-ies).
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qspiaccessibleinterface.h"

#include <qdebug.h>
#include <qdbusmessage.h>
#include <dbusconnection.h>
#include <qaccessible.h>

#include "constant_mappings.h"

QSpiAccessibleInterface::QSpiAccessibleInterface()
{
}

bool QSpiAccessibleInterface::handleMessage(QAccessibleInterface *interface, int child, const QString &function, const QDBusMessage &message, const QDBusConnection &connection)
{
    if (function == "GetRole") {
        QVariant v;
        v.setValue((uint) qSpiRoleMapping[interface->role(child)].spiRole());
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetName") {
        sendReply(connection, message, interface->text(QAccessible::Name, child));
        return true;
    } else if (function == "GetRoleName") {
        QVariant v;
        v.setValue(qSpiRoleMapping[interface->role(child)].name());
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetLocalizedRoleName") {
        QVariant v;
        v.setValue(qSpiRoleMapping[interface->role(child)].localizedName());
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetChildCount") {
        int childCount = child ? 0 : interface->childCount();
        sendReply(connection, message, childCount);
        return true;
    } else if (function == "GetIndexInParent") {
        int childIndex = -1;
        if (child) {
            childIndex = child;
        } else {
            QAccessibleInterface *parent = accessibleParent(interface, child);
            if (parent)
                childIndex = parent->indexOfChild(interface);
            delete parent;
        }
        sendReply(connection, message, childIndex);
        return true;
    } else if (function == "GetParent") {
        QAccessibleInterface *parent = accessibleParent(interface, child);

        QString path;
        if (!parent || parent->role(0) == QAccessible::Application) {
            path = QSPI_OBJECT_PATH_ROOT;
        } else {
            path = pathForInterface(parent, 0);
        }
        if (parent != interface)
            delete parent;

        QVariant ref;
        QSpiObjectReference v(connection, QDBusObjectPath(path));
        ref.setValue(v);
        sendReply(connection, message, ref);
        return true;
    } else if (function == "GetChildAtIndex") {
        int index = message.arguments().first().toInt();
        QString path;
        Q_ASSERT(child == 0);
        QAccessibleInterface *childInterface = 0;
        int childIndex = interface->navigate(QAccessible::Child, index+1, &childInterface);
        if (childIndex < 0)
            return false;
        if (childIndex == 0) {
            Q_ASSERT(childInterface);
            path = pathForInterface(childInterface, childIndex);
            delete childInterface;
        } else {
            path = pathForInterface(interface, childIndex);
        }

        QVariant ref;
        QSpiObjectReference v(connection, QDBusObjectPath(path));
        ref.setValue(v);
        QDBusMessage reply = message.createReply(ref);
        connection.send(reply);
        return true;
    } else if (function == "GetInterfaces") {
        QStringList ifaces;
        // FIXME
        ifaces << QSPI_INTERFACE_ACCESSIBLE;
        QVariant v;
        v.setValue(ifaces);
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetDescription") {
        sendReply(connection, message, interface->text(QAccessible::Description, child));
        return true;
    } else if (function == "GetState") {
        quint64 spiState = spiStatesFromQState(interface->state(child));
        if (interface->table2Interface()) {
            setSpiStateBit(&spiState, ATSPI_STATE_MANAGES_DESCENDANTS);
        }
        QVariant v;
        QSpiUIntList l = spiStateSetFromSpiStates(spiState);
        v.setValue(l);
        QDBusMessage reply = message.createReply(v);
        connection.send(reply);
        return true;
    } else if (function == "GetAttributes") {
        QVariant attributes;
        attributes.setValue(QSpiAttributeSet());
        QDBusMessage reply = message.createReply(attributes);
        connection.send(reply);
        return true;
    } else if (function == "GetRelationSet") {
        QVariant relations;
        relations.setValue(relationSet(interface, child, connection));
        QDBusMessage reply = message.createReply(relations);
        connection.send(reply);
        return true;
    } else if (function == "GetApplication") {
        QVariant ref;
        QSpiObjectReference v(connection, QDBusObjectPath(QSPI_OBJECT_PATH_ROOT));
        ref.setValue(v);
        QDBusMessage reply = message.createReply(ref);
        connection.send(reply);
        return true;
    } else if (function == "GetChildren") {
        qDebug() << "IMPLEMENT GETCHILDREN";
        //    QSpiObjectReferenceArray ();
        return true;
    } else {
        qWarning() << "WARNING: QSpiAccessibleInterface::handleMessage does not implement " << function << message.path();
    }
    return false;
}

QSpiRelationArray QSpiAccessibleInterface::relationSet(QAccessibleInterface *interface, int child, const QDBusConnection &connection) const
{
    QSpiRelationArray relations;
    if (child == 0) {
        qDebug() << "QSpiAccessibleInterface::relationSet currently has a problem with child ids.";
        // FIXME for example trees need to express their child relations here.
        return relations;
    }

    const QAccessible::RelationFlag relationsToCheck[] = {QAccessible::Label, QAccessible::Labelled, QAccessible::Controller, QAccessible::Controlled, static_cast<QAccessible::RelationFlag>(-1)};
    const AtspiRelationType relationTypes[] = {ATSPI_RELATION_LABELLED_BY, ATSPI_RELATION_LABEL_FOR, ATSPI_RELATION_CONTROLLED_BY, ATSPI_RELATION_CONTROLLER_FOR};

    for (int i = 0; relationsToCheck[i] >= 0; i++) {
        QList<QSpiObjectReference> related;
        int navigateResult = 1;

        for (int j = 1; navigateResult >= 0; j++) {
            QAccessibleInterface *target;
            navigateResult = interface->navigate(relationsToCheck[i], j, &target);

            if (navigateResult >= 0) {
                QDBusObjectPath path = QDBusObjectPath(pathForInterface(target ? target : interface, navigateResult));
                related.append(QSpiObjectReference(connection, path));
                delete target;
            }
        }
        if (!related.isEmpty())
            relations.append(QSpiRelationArrayEntry(relationTypes[i], related));
    }
    return relations;
}

void QSpiAccessibleInterface::sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QVariant &argument)
{
    sendReply(connection, message, QDBusVariant(argument));
}

void QSpiAccessibleInterface::sendReply(const QDBusConnection &connection, const QDBusMessage &message, const QDBusVariant &argument)
{
    QDBusMessage reply = message.createReply(QVariant::fromValue(argument));
    connection.send(reply);
//    qDebug() << "SIGNATURE " << message.member() << reply.signature() << message.signature();
}

QAccessibleInterface *QSpiAccessibleInterface::accessibleParent(QAccessibleInterface *iface, int child)
{
    if (child)
        return iface;
    QAccessibleInterface *parent = 0;
    iface->navigate(QAccessible::Ancestor, 1, &parent);
    return parent;
}

QString QSpiAccessibleInterface::pathForObject(QObject *object)
{
    Q_ASSERT(object);
    return QSPI_OBJECT_PATH_PREFIX + QString::number(reinterpret_cast<size_t>(object));
}

QString QSpiAccessibleInterface::pathForInterface(QAccessibleInterface *interface, int childIndex)
{
    QString path;
    QAccessibleInterface* interfaceWithObject = interface;
    while(!interfaceWithObject->object()) {
        QAccessibleInterface* parentInterface;
        interfaceWithObject->navigate(QAccessible::Ancestor, 1, &parentInterface);
        Q_ASSERT(parentInterface->isValid());
        int index = parentInterface->indexOfChild(interfaceWithObject);
        //Q_ASSERT(index >= 0);
        // FIXME: This should never happen!
        if (index < 0) {

            index = 999;
            path.prepend("/BROKEN_OBJECT_HIERARCHY");
            qWarning() << "Object claims to have child that we cannot navigate to. FIX IT!" << parentInterface->object();

            qDebug() << "Original interface: " << interface->object() << index;
            qDebug() << "Parent interface: " << parentInterface->object() << " childcount:" << parentInterface->childCount();
            QObject* p = parentInterface->object();
            qDebug() << p->children();

            QAccessibleInterface* tttt;
            int id = parentInterface->navigate(QAccessible::Child, 1, &tttt);
            qDebug() << "Nav child: " << id << tttt->object();
        }
        path.prepend('/' + QString::number(index));
        interfaceWithObject = parentInterface;
    }
    path.prepend(QSPI_OBJECT_PATH_PREFIX + QString::number(reinterpret_cast<quintptr>(interfaceWithObject->object())));

    if (childIndex > 0) {
        path.append('/' + QString::number(childIndex));
    }
    return path;
}

<|endoftext|>


<commit_before>#include <qt/derivationpathdialog.h>
#include <qt/forms/ui_derivationpathdialog.h>
#include <qt/qtumhwitool.h>
#include <outputtype.h>
#include <QRegularExpression>

#define paternDerivationPath "^m/[0-9]{1,9}'/[0-9]{1,9}'/[0-9]{1,9}'$"
QString toHWIPath(const QString& path)
{
    if(path.isEmpty())
        return "";
    QString hwiPath = path;
    hwiPath.replace("'", "h");
    return hwiPath;
}

DerivationPathDialog::DerivationPathDialog(QWidget *parent, WalletModel* model, bool _create) :
    QDialog(parent),
    create(_create),
    ui(new Ui::DerivationPathDialog)
{
    ui->setupUi(this);

    // Connect signal and slots
    QObject::connect(ui->cbRescan, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->cbLegacy, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->cbP2SH, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->cbSegWit, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->txtLegacy, &QValidatedLineEdit::textChanged, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->txtP2SH, &QValidatedLineEdit::textChanged, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->txtSegWit, &QValidatedLineEdit::textChanged, this, &DerivationPathDialog::updateWidgets);

    // Set contract address validator
    QRegularExpression regEx;
    regEx.setPattern(paternDerivationPath);

    QRegularExpressionValidator *legacyValidator = new QRegularExpressionValidator(ui->txtLegacy);
    legacyValidator->setRegularExpression(regEx);
    ui->txtLegacy->setCheckValidator(legacyValidator);
    ui->txtLegacy->setText(QtumHwiTool::derivationPathPKH());
    ui->txtLegacy->setPlaceholderText(QtumHwiTool::derivationPathPKH());

    QRegularExpressionValidator *P2SHValidator = new QRegularExpressionValidator(ui->txtP2SH);
    P2SHValidator->setRegularExpression(regEx);
    ui->txtP2SH->setCheckValidator(P2SHValidator);
    ui->txtP2SH->setText(QtumHwiTool::derivationPathP2SH());
    ui->txtP2SH->setPlaceholderText(QtumHwiTool::derivationPathP2SH());

    QRegularExpressionValidator *segWitValidator = new QRegularExpressionValidator(ui->txtSegWit);
    segWitValidator->setRegularExpression(regEx);
    ui->txtSegWit->setCheckValidator(segWitValidator);
    ui->txtSegWit->setText(QtumHwiTool::derivationPathBech32());
    ui->txtSegWit->setPlaceholderText(QtumHwiTool::derivationPathBech32());

    if(model && create)
    {
        ui->cbRescan->setChecked(true);
        ui->cbRescan->setEnabled(false);

        OutputType type = model->wallet().getDefaultAddressType();
        switch (type) {
        case OutputType::LEGACY:
            ui->cbLegacy->setChecked(true);
            ui->cbLegacy->setEnabled(false);
            break;
        case OutputType::P2SH_SEGWIT:
            ui->cbP2SH->setChecked(true);
            ui->cbP2SH->setEnabled(false);
            break;
        case OutputType::BECH32:
            ui->cbSegWit->setChecked(true);
            ui->cbSegWit->setEnabled(false);
            break;
        default:
            break;
        }
    }

    updateWidgets();
}

DerivationPathDialog::~DerivationPathDialog()
{
    delete ui;
}

void DerivationPathDialog::on_cancelButton_clicked()
{
    QDialog::reject();
}

void DerivationPathDialog::on_okButton_clicked()
{
    QDialog::accept();
}

bool DerivationPathDialog::importAddressesData(bool &rescan, bool &importPKH, bool &importP2SH, bool &importBech32, QString& pathPKH, QString& pathP2SH, QString& pathBech32)
{
    rescan = ui->cbRescan->isChecked();
    importPKH = ui->cbLegacy->isChecked();
    importP2SH = ui->cbP2SH->isChecked();
    importBech32 = ui->cbSegWit->isChecked();
    pathPKH = toHWIPath(ui->txtLegacy->text());
    pathP2SH = toHWIPath(ui->txtP2SH->text());
    pathBech32 = toHWIPath(ui->txtSegWit->text());
    return isDataValid() && isDataSelected(rescan, importPKH, importP2SH, importBech32);
}

void DerivationPathDialog::updateWidgets()
{
    bool legacy = ui->cbLegacy->isChecked();
    bool p2sh = ui->cbP2SH->isChecked();
    bool segWit = ui->cbSegWit->isChecked();
    bool rescan = ui->cbRescan->isChecked();
    bool enabled = isDataValid() && isDataSelected(rescan, legacy, p2sh, segWit);

    widgetEnabled(ui->okButton, enabled);
    widgetEnabled(ui->txtLegacy, legacy);
    widgetEnabled(ui->txtP2SH, p2sh);
    widgetEnabled(ui->txtSegWit, segWit);
}

void DerivationPathDialog::widgetEnabled(QWidget *widget, bool enabled)
{
    if(widget && widget->isEnabled() != enabled)
    {
        widget->setEnabled(enabled);
    }
}

bool DerivationPathDialog::isDataValid()
{
    ui->txtLegacy->checkValidity();
    ui->txtP2SH->checkValidity();
    ui->txtSegWit->checkValidity();
    return ui->txtLegacy->isValid() && ui->txtP2SH->isValid() && ui->txtSegWit->isValid();
}

bool DerivationPathDialog::isDataSelected(bool rescan, bool importPKH, bool importP2SH, bool importBech32)
{
    bool hasDerivation = importPKH || importP2SH || importBech32;
    if(create) return hasDerivation;
    return rescan || hasDerivation;
}
<commit_msg>Add missing include QRegularExpressionValidator<commit_after>#include <qt/derivationpathdialog.h>
#include <qt/forms/ui_derivationpathdialog.h>
#include <qt/qtumhwitool.h>
#include <outputtype.h>
#include <QRegularExpression>
#include <QRegularExpressionValidator>

#define paternDerivationPath "^m/[0-9]{1,9}'/[0-9]{1,9}'/[0-9]{1,9}'$"
QString toHWIPath(const QString& path)
{
    if(path.isEmpty())
        return "";
    QString hwiPath = path;
    hwiPath.replace("'", "h");
    return hwiPath;
}

DerivationPathDialog::DerivationPathDialog(QWidget *parent, WalletModel* model, bool _create) :
    QDialog(parent),
    create(_create),
    ui(new Ui::DerivationPathDialog)
{
    ui->setupUi(this);

    // Connect signal and slots
    QObject::connect(ui->cbRescan, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->cbLegacy, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->cbP2SH, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->cbSegWit, &QCheckBox::clicked, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->txtLegacy, &QValidatedLineEdit::textChanged, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->txtP2SH, &QValidatedLineEdit::textChanged, this, &DerivationPathDialog::updateWidgets);
    QObject::connect(ui->txtSegWit, &QValidatedLineEdit::textChanged, this, &DerivationPathDialog::updateWidgets);

    // Set contract address validator
    QRegularExpression regEx;
    regEx.setPattern(paternDerivationPath);

    QRegularExpressionValidator *legacyValidator = new QRegularExpressionValidator(ui->txtLegacy);
    legacyValidator->setRegularExpression(regEx);
    ui->txtLegacy->setCheckValidator(legacyValidator);
    ui->txtLegacy->setText(QtumHwiTool::derivationPathPKH());
    ui->txtLegacy->setPlaceholderText(QtumHwiTool::derivationPathPKH());

    QRegularExpressionValidator *P2SHValidator = new QRegularExpressionValidator(ui->txtP2SH);
    P2SHValidator->setRegularExpression(regEx);
    ui->txtP2SH->setCheckValidator(P2SHValidator);
    ui->txtP2SH->setText(QtumHwiTool::derivationPathP2SH());
    ui->txtP2SH->setPlaceholderText(QtumHwiTool::derivationPathP2SH());

    QRegularExpressionValidator *segWitValidator = new QRegularExpressionValidator(ui->txtSegWit);
    segWitValidator->setRegularExpression(regEx);
    ui->txtSegWit->setCheckValidator(segWitValidator);
    ui->txtSegWit->setText(QtumHwiTool::derivationPathBech32());
    ui->txtSegWit->setPlaceholderText(QtumHwiTool::derivationPathBech32());

    if(model && create)
    {
        ui->cbRescan->setChecked(true);
        ui->cbRescan->setEnabled(false);

        OutputType type = model->wallet().getDefaultAddressType();
        switch (type) {
        case OutputType::LEGACY:
            ui->cbLegacy->setChecked(true);
            ui->cbLegacy->setEnabled(false);
            break;
        case OutputType::P2SH_SEGWIT:
            ui->cbP2SH->setChecked(true);
            ui->cbP2SH->setEnabled(false);
            break;
        case OutputType::BECH32:
            ui->cbSegWit->setChecked(true);
            ui->cbSegWit->setEnabled(false);
            break;
        default:
            break;
        }
    }

    updateWidgets();
}

DerivationPathDialog::~DerivationPathDialog()
{
    delete ui;
}

void DerivationPathDialog::on_cancelButton_clicked()
{
    QDialog::reject();
}

void DerivationPathDialog::on_okButton_clicked()
{
    QDialog::accept();
}

bool DerivationPathDialog::importAddressesData(bool &rescan, bool &importPKH, bool &importP2SH, bool &importBech32, QString& pathPKH, QString& pathP2SH, QString& pathBech32)
{
    rescan = ui->cbRescan->isChecked();
    importPKH = ui->cbLegacy->isChecked();
    importP2SH = ui->cbP2SH->isChecked();
    importBech32 = ui->cbSegWit->isChecked();
    pathPKH = toHWIPath(ui->txtLegacy->text());
    pathP2SH = toHWIPath(ui->txtP2SH->text());
    pathBech32 = toHWIPath(ui->txtSegWit->text());
    return isDataValid() && isDataSelected(rescan, importPKH, importP2SH, importBech32);
}

void DerivationPathDialog::updateWidgets()
{
    bool legacy = ui->cbLegacy->isChecked();
    bool p2sh = ui->cbP2SH->isChecked();
    bool segWit = ui->cbSegWit->isChecked();
    bool rescan = ui->cbRescan->isChecked();
    bool enabled = isDataValid() && isDataSelected(rescan, legacy, p2sh, segWit);

    widgetEnabled(ui->okButton, enabled);
    widgetEnabled(ui->txtLegacy, legacy);
    widgetEnabled(ui->txtP2SH, p2sh);
    widgetEnabled(ui->txtSegWit, segWit);
}

void DerivationPathDialog::widgetEnabled(QWidget *widget, bool enabled)
{
    if(widget && widget->isEnabled() != enabled)
    {
        widget->setEnabled(enabled);
    }
}

bool DerivationPathDialog::isDataValid()
{
    ui->txtLegacy->checkValidity();
    ui->txtP2SH->checkValidity();
    ui->txtSegWit->checkValidity();
    return ui->txtLegacy->isValid() && ui->txtP2SH->isValid() && ui->txtSegWit->isValid();
}

bool DerivationPathDialog::isDataSelected(bool rescan, bool importPKH, bool importP2SH, bool importBech32)
{
    bool hasDerivation = importPKH || importP2SH || importBech32;
    if(create) return hasDerivation;
    return rescan || hasDerivation;
}
<|endoftext|>


<commit_before>#include <chili/task.h>
#include <chili/plugin.xpm>
#include <chili/qclightbox.h>
#include <chili/qclightboxmanager.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qptrlist.h>
#include <qbuttongroup.h>
#include <mitkDataTree.h>
#include <QmitkStdMultiWidget.h>
#include <mitkLightBoxImageReader.h>
#include "SampleApp.h"
#include "QcMITKSamplePlugin.h"
#include "mitkDataTreeNodeFactory.h"
#include "mitkProperties.h"
#include "mitkLevelWindowProperty.h"
#include "mitkStringProperty.h"
#include "ToolBar.h"
#include <mitkChiliPlugin.h>

#include <qmessagebox.h>

#include <ipPic.h>
#include <ipFunc.h>
#include <ipDicom/ipDicom.h>

QcPlugin* QcMITKSamplePlugin::s_PluginInstance = NULL;

QcMITKSamplePlugin::QcMITKSamplePlugin( QWidget *parent )
  : QcPlugin( parent ), ap(NULL)
{
  task = new QcTask( xpm(), parent, name() );

  toolbar =new ToolBar(task,this);

  QButtonGroup* tb;
  tb=toolbar->GetToolBar();

  connect(toolbar,SIGNAL(LightboxSelected(QcLightbox*)),this,SLOT(selectSerie(QcLightbox*)));
  connect(toolbar,SIGNAL(ChangeWidget()),this,SLOT(CreateNewSampleApp()));
  activated =false;

  s_PluginInstance = this;

  mitk::ChiliPlugin::SetPluginInstance(s_PluginInstance);
}

QString
QcMITKSamplePlugin::name()
{
  return QString( "MITK PlugIn" );
}

const char **
QcMITKSamplePlugin::xpm()
{
  return (const char **)plugin_xpm;
}

QcMITKSamplePlugin::~QcMITKSamplePlugin ()
{
  task->deleteLater();
}

extern "C" QcEXPORT QObject *
create( QWidget *parent )
{
return new QcMITKSamplePlugin( parent );
}

void 	QcMITKSamplePlugin::lightboxFilled (QcLightbox* lightbox)
{
  /////itkGenericOutputMacro(<<"lightbox filled");
  QcLightboxManager *lbm=lightboxManager();
  QPtrList<QcLightbox> list;
  list=lbm->getLightboxes();
  QButtonGroup* tb;
  tb=toolbar->GetToolBar();
  int id=tb->id(tb->selected());
  if (id>0)
  {
    if (!tb->find(6)->isOn())
      if (activated&&(list.take(id-1))->isActive())
          selectSerie(lightbox);
  }
  else
    if (tb->find((list.find(lightbox))+1)->isOn())
          selectSerie(lightbox);

}

void 	QcMITKSamplePlugin::lightboxTiles (QcLightboxManager *lbm, int tiles)
{
  /////itkGenericOutputMacro(<<"lightbox tiles: "<<tiles);
  toolbar->ConnectButton(tiles);

}

void QcMITKSamplePlugin::selectSerie (QcLightbox* lightbox)
{
  /////itkGenericOutputMacro(<<"selectSerie");
  activated=true;
  if(lightbox->getFrames()==0)
    return;

  mitk::Image::Pointer image = mitk::Image::New();

  mitk::LightBoxImageReader::Pointer reader=mitk::LightBoxImageReader::New();
  reader->SetLightBox(lightbox);

  image=reader->GetOutput();
  image->Update();

  if ( image.IsNotNull() )
  {
    unsigned long initTime = ap->GetMultiWidget()->GetRenderWindow1()->GetRenderer()->GetMTime();

    mitk::DataTree::Pointer tree = ap->GetTree();
    mitk::DataTreePreOrderIterator it(tree);
    mitk::DataTreeNode::Pointer node = mitk::DataTreeNode::New();
    node->SetData(image);
    it.Add(node);
    mitk::LevelWindowProperty::Pointer levWinProp = new mitk::LevelWindowProperty();
    mitk::LevelWindow levelwindow;
    levelwindow.SetAuto( reader->GetOutput() );
    levWinProp->SetLevelWindow( levelwindow );
    node->GetPropertyList()->SetProperty( "levelwindow", levWinProp );
    node->SetProperty("LoadedFromChili", new mitk::BoolProperty( true ) );
    mitk::DataTreeNodeFactory::SetDefaultImageProperties(node);

    ipPicDescriptor *pic = reader->GetOutput()->GetPic();

    ipPicTSV_t* uid= ipPicQueryTag(pic, "IMAGE INSTANCE UID");
    ipPicTSV_t* description= ipPicQueryTag(pic, "SERIES DESCRIPTION");
    ipPicTSV_t* patientName= ipPicQueryTag(pic, "PATIENT NAME");

    if (description)
      node->SetProperty("name", new mitk::StringProperty( (char*)uid->value ));
    else if (uid)
      node->SetProperty("name", new mitk::StringProperty( (char*)description->value ));

    else if (patientName)
      node->SetProperty("name", new mitk::StringProperty( (char*)patientName->value ));
    else
      node->SetProperty("name", new mitk::StringProperty( lightbox->name() ));

    ipPicTSV_t* tsv = ipPicQueryTag(pic, "SOURCE HEADER");
    void* data;
    ipUInt4_t len;
    if (tsv)
    {
      //0x0018, 0x1030 : Protocol Name - ist bei Morphologie/Phase gleich
      //0x0008, 0x103e : Series Description - ist der in der unter "Beschreibung" stehende name (_bh/_bh_P)
      // aber: wahrscheinlich unsicher, da vom Benutzer eingegeben
      //eventuell brauchbar: 0x0018, 0x0024 : Sequence Name
      dicomFindElement((unsigned char*) tsv->value, 0x0018, 0x1030, &data, &len);
      char * tmp = new char[len+1];
      strncpy(tmp, (char*)data, len);
      tmp[len]=0;
      node->SetProperty("protocol", new mitk::StringProperty( tmp ));
      delete [] tmp;

      dicomFindElement((unsigned char*) tsv->value, 0x0008, 0x103e, &data, &len);
      tmp = new char[len+1];
      strncpy(tmp, (char*)data, len);
      tmp[len]=0;
      node->SetProperty("series description", new mitk::StringProperty( tmp ));
      delete [] tmp;
    }
        //dicomFindElement((unsigned char*) tsv->value, 0x0020, 0x0013, &data, &len);
        //sscanf( (char *) data, "%d", &imageNumber );
        //info.imageNumber=imageNumber;

    if((ap->GetMultiWidget()->GetRenderWindow1()->GetRenderer()->GetMTime()==initTime) && (ap->GetStandardViewsInitialized()==false))
    {
      ap->SetStandardViewsInitialized(ap->GetMultiWidget()->InitializeStandardViews(&it));
    }

    ap->GetMultiWidget()->Repaint();
    ap->GetMultiWidget()->Fit();

  }

}

void QcMITKSamplePlugin::CreateNewSampleApp()
{
  if(ap!=NULL)
    delete ap;
  ap = new SampleApp(task,"sample",0);
  toolbar->SetWidget(ap);
}
<commit_msg>FIX: data tree nodes have now correct names<commit_after>#include <chili/task.h>
#include <chili/plugin.xpm>
#include <chili/qclightbox.h>
#include <chili/qclightboxmanager.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qptrlist.h>
#include <qbuttongroup.h>
#include <mitkDataTree.h>
#include <QmitkStdMultiWidget.h>
#include <mitkLightBoxImageReader.h>
#include "SampleApp.h"
#include "QcMITKSamplePlugin.h"
#include "mitkDataTreeNodeFactory.h"
#include "mitkProperties.h"
#include "mitkLevelWindowProperty.h"
#include "mitkStringProperty.h"
#include "ToolBar.h"
#include <mitkChiliPlugin.h>

#include <qmessagebox.h>

#include <ipPic.h>
#include <ipFunc.h>
#include <ipDicom/ipDicom.h>

#include "QmitkCommonFunctionality.h"

QcPlugin* QcMITKSamplePlugin::s_PluginInstance = NULL;

QcMITKSamplePlugin::QcMITKSamplePlugin( QWidget *parent )
  : QcPlugin( parent ), ap(NULL)
{
  task = new QcTask( xpm(), parent, name() );

  toolbar =new ToolBar(task,this);

  QButtonGroup* tb;
  tb=toolbar->GetToolBar();

  connect(toolbar,SIGNAL(LightboxSelected(QcLightbox*)),this,SLOT(selectSerie(QcLightbox*)));
  connect(toolbar,SIGNAL(ChangeWidget()),this,SLOT(CreateNewSampleApp()));
  activated =false;

  s_PluginInstance = this;

  mitk::ChiliPlugin::SetPluginInstance(s_PluginInstance);
}

QString
QcMITKSamplePlugin::name()
{
  return QString( "MITK PlugIn" );
}

const char **
QcMITKSamplePlugin::xpm()
{
  return (const char **)plugin_xpm;
}

QcMITKSamplePlugin::~QcMITKSamplePlugin ()
{
  task->deleteLater();
}

extern "C" QcEXPORT QObject *
create( QWidget *parent )
{
return new QcMITKSamplePlugin( parent );
}

void 	QcMITKSamplePlugin::lightboxFilled (QcLightbox* lightbox)
{
  /////itkGenericOutputMacro(<<"lightbox filled");
  QcLightboxManager *lbm=lightboxManager();
  QPtrList<QcLightbox> list;
  list=lbm->getLightboxes();
  QButtonGroup* tb;
  tb=toolbar->GetToolBar();
  int id=tb->id(tb->selected());
  if (id>0)
  {
    if (!tb->find(6)->isOn())
      if (activated&&(list.take(id-1))->isActive())
          selectSerie(lightbox);
  }
  else
    if (tb->find((list.find(lightbox))+1)->isOn())
          selectSerie(lightbox);

}

void 	QcMITKSamplePlugin::lightboxTiles (QcLightboxManager *lbm, int tiles)
{
  /////itkGenericOutputMacro(<<"lightbox tiles: "<<tiles);
  toolbar->ConnectButton(tiles);

}

void QcMITKSamplePlugin::selectSerie (QcLightbox* lightbox)
{
  /////itkGenericOutputMacro(<<"selectSerie");
  activated=true;
  if(lightbox->getFrames()==0)
    return;

  QObject * parent = this->parent();
  QWidget * parentWidget = (QWidget *)parent;

  if (parentWidget->isVisible()) {
    itkGenericOutputMacro(<<"plugin active");
  } else
  {
    itkGenericOutputMacro(<<"plugin not active");
  }

  mitk::Image::Pointer image = mitk::Image::New();

  mitk::LightBoxImageReader::Pointer reader=mitk::LightBoxImageReader::New();
  reader->SetLightBox(lightbox);

  image=reader->GetOutput();
  image->Update();

  if ( image.IsNotNull() )
  {
    unsigned long initTime = ap->GetMultiWidget()->GetRenderWindow1()->GetRenderer()->GetMTime();

    mitk::DataTree::Pointer tree = ap->GetTree();
    mitk::DataTreePreOrderIterator it(tree);
    mitk::DataTreeNode::Pointer node = mitk::DataTreeNode::New();
    node->SetData(image);

    mitk::LevelWindowProperty::Pointer levWinProp = new mitk::LevelWindowProperty();
    mitk::LevelWindow levelwindow;
    levelwindow.SetAuto( reader->GetOutput() );
    levWinProp->SetLevelWindow( levelwindow );
    node->GetPropertyList()->SetProperty( "levelwindow", levWinProp );
    node->SetProperty("LoadedFromChili", new mitk::BoolProperty( true ) );
    mitk::DataTreeNodeFactory::SetDefaultImageProperties(node);

    ipPicDescriptor *pic = reader->GetOutput()->GetPic();

    ipPicTSV_t* uid= ipPicQueryTag(pic, "IMAGE INSTANCE UID");
    ipPicTSV_t* description= ipPicQueryTag(pic, "SERIES DESCRIPTION");
    ipPicTSV_t* patientName= ipPicQueryTag(pic, "PATIENT NAME");

    int laenge = patientName->n[0];
    char* patName = new char[laenge+1];
    strncpy(patName, (char*)(patientName->value), laenge);
    patName[laenge] = 0;
    //char a;
    //while (*patName != 0)
    //{
    //  a = *patName;
    //  patName++;
    //}

    std::string test((char*)patientName->value );
    int lenght = test.length();

   if (description)
      node->SetProperty("name", new mitk::StringProperty( (char*)uid->value ));
    else if (uid)
      node->SetProperty("name", new mitk::StringProperty( (char*)description->value ));

    else if (patientName)
      //node->SetProperty("name", new mitk::StringProperty( (char*)patientName->value ));
      //node->SetProperty("name", new mitk::StringProperty( test.c_str() ));
      node->SetProperty("name", new mitk::StringProperty( patName ));
    else
      node->SetProperty("name", new mitk::StringProperty( lightbox->name() ));

    bool notAlreadyInDataTree = true;

    ipPicTSV_t* tsv = ipPicQueryTag(pic, "SOURCE HEADER");
    void* data;
    ipUInt4_t len;
    if (tsv)
    {
      //0x0018, 0x1030 : Protocol Name - ist bei Morphologie/Phase gleich
      //0x0008, 0x103e : Series Description - ist der in der unter "Beschreibung" stehende name (_bh/_bh_P)
      // aber: wahrscheinlich unsicher, da vom Benutzer eingegeben
      //eventuell brauchbar: 0x0018, 0x0024 : Sequence Name
      char * tmp;
      if (dicomFindElement((unsigned char*) tsv->value, 0x0018, 0x1030, &data, &len))
      {
        tmp = new char[len+1];
        strncpy(tmp, (char*)data, len);
        tmp[len]=0;
        node->SetProperty("protocol", new mitk::StringProperty( tmp ));
        delete [] tmp;
      }

      if (dicomFindElement((unsigned char*) tsv->value, 0x0020, 0x000e, &data, &len))
      {
        dicomFindElement((unsigned char*) tsv->value, 0x0020, 0x000e, &data, &len);
        tmp = new char[len+1];
        strncpy(tmp, (char*)data, len);
        tmp[len]=0;
        node->SetProperty("series uid", new mitk::StringProperty( tmp ));

        mitk::DataTreeNode* existingNode = CommonFunctionality::GetFirstNodeByProperty(it,"series uid", new mitk::StringProperty( tmp ));

        if ( existingNode )
        {
          notAlreadyInDataTree = false;
        }

        delete [] tmp;
      }

      if ( dicomFindElement((unsigned char*) tsv->value, 0x0008, 0x103e, &data, &len) )
      {
        tmp = new char[len+1];
        strncpy(tmp, (char*)data, len);
        tmp[len]=0;
        node->SetProperty("series description", new mitk::StringProperty( tmp ));
        delete [] tmp;
      }
    }
        //dicomFindElement((unsigned char*) tsv->value, 0x0020, 0x0013, &data, &len);
        //sscanf( (char *) data, "%d", &imageNumber );
        //info.imageNumber=imageNumber;

    if (notAlreadyInDataTree)
    {
      it.Add(node);
    }

    if((ap->GetMultiWidget()->GetRenderWindow1()->GetRenderer()->GetMTime()==initTime) && (ap->GetStandardViewsInitialized()==false))
    {
      ap->SetStandardViewsInitialized(ap->GetMultiWidget()->InitializeStandardViews(&it));
    }

    ap->GetMultiWidget()->Repaint();
    ap->GetMultiWidget()->Fit();

  }

}

void QcMITKSamplePlugin::CreateNewSampleApp()
{
  if(ap!=NULL)
    delete ap;
  ap = new SampleApp(task,"sample",0);
  toolbar->SetWidget(ap);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestTranslucentLUTDepthPeeling.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This test covers rendering of an actor with a translucent LUT and depth
// peeling. The mapper uses color interpolation (poor quality).
//
// The command line arguments are:
// -I        => run in interactive mode; unless this is used, the program will
//              not allow interaction and exit

#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"

#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkActor.h"

#include "vtkImageSinusoidSource.h"
#include "vtkImageData.h"
#include "vtkImageDataGeometryFilter.h"
#include "vtkDataSetSurfaceFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkLookupTable.h"
#include "vtkCamera.h"

int TestTranslucentLUTDepthPeeling(int argc, char* argv[])
{
  vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->SetAlphaBitPlanes(1);
  iren->SetRenderWindow(renWin);
  renWin->Delete();

  vtkRenderer *renderer = vtkRenderer::New();
  renWin->AddRenderer(renderer);
  renderer->Delete();
  renderer->SetUseDepthPeeling(1);
  renderer->SetMaximumNumberOfPeels(200);
  renderer->SetOcclusionRatio(0.1);

  vtkImageSinusoidSource *imageSource=vtkImageSinusoidSource::New();
  imageSource->SetWholeExtent(0,9,0,9,0,9);
  imageSource->SetPeriod(5);
  imageSource->Update();

  vtkImageData *image=imageSource->GetOutput();
  double range[2];
  image->GetScalarRange(range);

  vtkDataSetSurfaceFilter *surface=vtkDataSetSurfaceFilter::New();

  surface->SetInputConnection(imageSource->GetOutputPort());
  imageSource->Delete();

  vtkPolyDataMapper *mapper=vtkPolyDataMapper::New();
  mapper->SetInputConnection(surface->GetOutputPort());
  surface->Delete();

  vtkLookupTable *lut=vtkLookupTable::New();
  lut->SetTableRange(range);
  lut->SetAlphaRange(0.5,0.5);
  lut->SetHueRange(0.2,0.7);
  lut->SetNumberOfTableValues(256);
  lut->Build();

  mapper->SetScalarVisibility(1);
  mapper->SetLookupTable(lut);
  lut->Delete();

  vtkActor *actor=vtkActor::New();
  renderer->AddActor(actor);
  actor->Delete();
  actor->SetMapper(mapper);
  mapper->Delete();

  renderer->SetBackground(0.1,0.3,0.0);
  renWin->SetSize(400,400);

  renWin->Render();
  if(renderer->GetLastRenderingUsedDepthPeeling())
    {
    cout<<"depth peeling was used"<<endl;
    }
  else
    {
    cout<<"depth peeling was not used (alpha blending instead)"<<endl;
    }
  vtkCamera *camera=renderer->GetActiveCamera();
  camera->Azimuth(-40.0);
  camera->Elevation(20.0);
  renWin->Render();

  int retVal = vtkRegressionTestImage( renWin );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }
  iren->Delete();

  return !retVal;
}
<commit_msg>BUG:Workaround for nVidia bug. See vtk bug report 0007774.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestTranslucentLUTDepthPeeling.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// This test covers rendering of an actor with a translucent LUT and depth
// peeling. The mapper uses color interpolation (poor quality).
//
// The command line arguments are:
// -I        => run in interactive mode; unless this is used, the program will
//              not allow interaction and exit

#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"

#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkActor.h"

#include "vtkImageSinusoidSource.h"
#include "vtkImageData.h"
#include "vtkImageDataGeometryFilter.h"
#include "vtkDataSetSurfaceFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkLookupTable.h"
#include "vtkCamera.h"

int TestTranslucentLUTDepthPeeling(int argc, char* argv[])
{
  vtkRenderWindowInteractor *iren=vtkRenderWindowInteractor::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->SetMultiSamples(0);

  renWin->SetAlphaBitPlanes(1);
  iren->SetRenderWindow(renWin);
  renWin->Delete();

  vtkRenderer *renderer = vtkRenderer::New();
  renWin->AddRenderer(renderer);
  renderer->Delete();
  renderer->SetUseDepthPeeling(1);
  renderer->SetMaximumNumberOfPeels(200);
  renderer->SetOcclusionRatio(0.1);

  vtkImageSinusoidSource *imageSource=vtkImageSinusoidSource::New();
  imageSource->SetWholeExtent(0,9,0,9,0,9);
  imageSource->SetPeriod(5);
  imageSource->Update();

  vtkImageData *image=imageSource->GetOutput();
  double range[2];
  image->GetScalarRange(range);

  vtkDataSetSurfaceFilter *surface=vtkDataSetSurfaceFilter::New();

  surface->SetInputConnection(imageSource->GetOutputPort());
  imageSource->Delete();

  vtkPolyDataMapper *mapper=vtkPolyDataMapper::New();
  mapper->SetInputConnection(surface->GetOutputPort());
  surface->Delete();

  vtkLookupTable *lut=vtkLookupTable::New();
  lut->SetTableRange(range);
  lut->SetAlphaRange(0.5,0.5);
  lut->SetHueRange(0.2,0.7);
  lut->SetNumberOfTableValues(256);
  lut->Build();

  mapper->SetScalarVisibility(1);
  mapper->SetLookupTable(lut);
  lut->Delete();

  vtkActor *actor=vtkActor::New();
  renderer->AddActor(actor);
  actor->Delete();
  actor->SetMapper(mapper);
  mapper->Delete();

  renderer->SetBackground(0.1,0.3,0.0);
  renWin->SetSize(400,400);

  renWin->Render();
  if(renderer->GetLastRenderingUsedDepthPeeling())
    {
    cout<<"depth peeling was used"<<endl;
    }
  else
    {
    cout<<"depth peeling was not used (alpha blending instead)"<<endl;
    }
  vtkCamera *camera=renderer->GetActiveCamera();
  camera->Azimuth(-40.0);
  camera->Elevation(20.0);
  renWin->Render();

  int retVal = vtkRegressionTestImage( renWin );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    iren->Start();
    }
  iren->Delete();

  return !retVal;
}
<|endoftext|>