<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: RelationDesignView.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef DBAUI_RELATIONDESIGNVIEW_HXX
#define DBAUI_RELATIONDESIGNVIEW_HXX

#ifndef DBAUI_JOINDESIGNVIEW_HXX
#include "JoinDesignView.hxx"
#endif
#ifndef _VECTOR_
#include <vector>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif
#ifndef DBAUI_RELATION_TABLEVIEW_HXX
#include "RelationTableView.hxx"
#endif

namespace dbaui
{
    class OAddTableDlg;
    class OTableConnection;
    class ORelationTableConnectionData;
    class OConnectionLineData;
    class ORelationController;

    class ORelationDesignView : public OJoinDesignView
    {
    public:
        ORelationDesignView(Window* pParent, ORelationController* _pController,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
        virtual ~ORelationDesignView();

        // set the statement for representation
        /// late construction
        virtual void Construct();
        virtual void initialize();

        virtual long PreNotify( NotifyEvent& rNEvt );
        virtual void GetFocus();
    };
}
#endif // DBAUI_RELATIONDESIGNVIEW_HXX

<commit_msg>INTEGRATION: CWS dba30d (1.6.30); FILE MERGED 2008/05/29 11:25:58 fs 1.6.30.1: during #i80943#: refactoring: IController now passed around as reference, not as pointer<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: RelationDesignView.hxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef DBAUI_RELATIONDESIGNVIEW_HXX
#define DBAUI_RELATIONDESIGNVIEW_HXX

#ifndef DBAUI_JOINDESIGNVIEW_HXX
#include "JoinDesignView.hxx"
#endif
#ifndef _VECTOR_
#include <vector>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef DBAUI_ENUMTYPES_HXX
#include "QEnumTypes.hxx"
#endif
#ifndef DBAUI_RELATION_TABLEVIEW_HXX
#include "RelationTableView.hxx"
#endif

namespace dbaui
{
    class OAddTableDlg;
    class OTableConnection;
    class ORelationTableConnectionData;
    class OConnectionLineData;
    class ORelationController;

    class ORelationDesignView : public OJoinDesignView
    {
    public:
        ORelationDesignView(Window* pParent, ORelationController& _rController,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
        virtual ~ORelationDesignView();

        // set the statement for representation
        /// late construction
        virtual void Construct();
        virtual void initialize();

        virtual long PreNotify( NotifyEvent& rNEvt );
        virtual void GetFocus();
    };
}
#endif // DBAUI_RELATIONDESIGNVIEW_HXX

<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
#ifndef itkPyBuffer_hxx
#define itkPyBuffer_hxx

#include "itkPyBuffer.h"

#include "itkImportImageContainer.h"

namespace itk
{

template <class TImage>
PyObject *
PyBuffer<TImage>::_GetArrayViewFromImage(ImageType * image)
{
  PyObject * memoryView = NULL;
  Py_buffer  pyBuffer;
  memset(&pyBuffer, 0, sizeof(Py_buffer));

  Py_ssize_t len = 1;
  size_t     pixelSize = sizeof(ComponentType);
  int        res = 0;

  if (!image)
  {
    throw std::runtime_error("Input image is null");
  }

  image->Update();

  ComponentType * buffer =
    const_cast<ComponentType *>(reinterpret_cast<const ComponentType *>(image->GetBufferPointer()));

  void * itkImageBuffer = (void *)(buffer);

  // Computing the length of data
  const int numberOfComponents = image->GetNumberOfComponentsPerPixel();
  SizeType  size = image->GetBufferedRegion().GetSize();

  for (unsigned int dim = 0; dim < ImageDimension; ++dim)
  {
    len *= size[dim];
  }

  len *= numberOfComponents;
  len *= pixelSize;

  res = PyBuffer_FillInfo(&pyBuffer, NULL, (void *)itkImageBuffer, len, 0, PyBUF_CONTIG);
  memoryView = PyMemoryView_FromBuffer(&pyBuffer);

  PyBuffer_Release(&pyBuffer);

  return memoryView;
}

template <class TImage>
const typename PyBuffer<TImage>::OutputImagePointer
PyBuffer<TImage>::_GetImageViewFromArray(PyObject * arr, PyObject * shape, PyObject * numOfComponent)
{
  PyObject * shapeseq = NULL;
  PyObject * item = NULL;

  Py_ssize_t bufferLength;
  Py_buffer  pyBuffer;
  memset(&pyBuffer, 0, sizeof(Py_buffer));

  SizeType      size;
  SizeType      sizeFortran;
  SizeValueType numberOfPixels = 1;

  const void * buffer;

  long         numberOfComponents = 1;
  unsigned int dimension = 0;

  size_t pixelSize = sizeof(ComponentType);
  size_t len = 1;

  if (PyObject_GetBuffer(arr, &pyBuffer, PyBUF_ND | PyBUF_ANY_CONTIGUOUS) == -1)
  {
    PyErr_SetString(PyExc_RuntimeError, "Cannot get an instance of NumPy array.");
    PyBuffer_Release(&pyBuffer);
    return nullptr;
  }
  else
  {
    bufferLength = pyBuffer.len;
    buffer = pyBuffer.buf;
  }
  PyBuffer_Release(&pyBuffer);

  shapeseq = PySequence_Fast(shape, "expected sequence");
  dimension = PySequence_Size(shape);

  numberOfComponents = PyInt_AsLong(numOfComponent);

  for (unsigned int i = 0; i < dimension; ++i)
  {
    item = PySequence_Fast_GET_ITEM(shapeseq, i);
    size[i] = (SizeValueType)PyInt_AsLong(item);
    sizeFortran[dimension - 1 - i] = (SizeValueType)PyInt_AsLong(item);
    numberOfPixels *= size[i];
  }

  bool isFortranContiguous = false;
  if (pyBuffer.strides != NULL && pyBuffer.itemsize == pyBuffer.strides[0])
  {
    isFortranContiguous = true;
  }

  len = numberOfPixels * numberOfComponents * pixelSize;
  if (bufferLength != len)
  {
    PyErr_SetString(PyExc_RuntimeError, "Size mismatch of image and Buffer.");
    PyBuffer_Release(&pyBuffer);
    Py_DECREF(shapeseq);
    return nullptr;
  }

  IndexType start;
  start.Fill(0);

  RegionType region;
  region.SetIndex(start);
  region.SetSize(size);
  if (isFortranContiguous)
  {
    region.SetSize(sizeFortran);
  }
  else
  {
    region.SetSize(size);
  }

  PointType origin;
  origin.Fill(0.0);

  SpacingType spacing;
  spacing.Fill(1.0);

  using InternalPixelType = typename TImage::InternalPixelType;
  using ImporterType = ImportImageContainer<SizeValueType, InternalPixelType>;
  typename ImporterType::Pointer importer = ImporterType::New();
  const bool                     importImageFilterWillOwnTheBuffer = false;
  InternalPixelType *            data = (InternalPixelType *)buffer;
  importer->SetImportPointer(data, numberOfPixels, importImageFilterWillOwnTheBuffer);

  OutputImagePointer output = TImage::New();
  output->SetRegions(region);
  output->SetOrigin(origin);
  output->SetSpacing(spacing);
  output->SetPixelContainer(importer);
  output->SetNumberOfComponentsPerPixel(numberOfComponents);

  Py_DECREF(shapeseq);
  PyBuffer_Release(&pyBuffer);

  return output;
}

} // namespace itk

#endif
<commit_msg>PERF: PyBuffer importImageFilterWillOwnTheBuffer is constexpr<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/
#ifndef itkPyBuffer_hxx
#define itkPyBuffer_hxx

#include "itkPyBuffer.h"

#include "itkImportImageContainer.h"

namespace itk
{

template <class TImage>
PyObject *
PyBuffer<TImage>::_GetArrayViewFromImage(ImageType * image)
{
  PyObject * memoryView = NULL;
  Py_buffer  pyBuffer;
  memset(&pyBuffer, 0, sizeof(Py_buffer));

  Py_ssize_t len = 1;
  size_t     pixelSize = sizeof(ComponentType);
  int        res = 0;

  if (!image)
  {
    throw std::runtime_error("Input image is null");
  }

  image->Update();

  ComponentType * buffer =
    const_cast<ComponentType *>(reinterpret_cast<const ComponentType *>(image->GetBufferPointer()));

  void * itkImageBuffer = (void *)(buffer);

  // Computing the length of data
  const int numberOfComponents = image->GetNumberOfComponentsPerPixel();
  SizeType  size = image->GetBufferedRegion().GetSize();

  for (unsigned int dim = 0; dim < ImageDimension; ++dim)
  {
    len *= size[dim];
  }

  len *= numberOfComponents;
  len *= pixelSize;

  res = PyBuffer_FillInfo(&pyBuffer, NULL, (void *)itkImageBuffer, len, 0, PyBUF_CONTIG);
  memoryView = PyMemoryView_FromBuffer(&pyBuffer);

  PyBuffer_Release(&pyBuffer);

  return memoryView;
}

template <class TImage>
const typename PyBuffer<TImage>::OutputImagePointer
PyBuffer<TImage>::_GetImageViewFromArray(PyObject * arr, PyObject * shape, PyObject * numOfComponent)
{
  PyObject * shapeseq = NULL;
  PyObject * item = NULL;

  Py_ssize_t bufferLength;
  Py_buffer  pyBuffer;
  memset(&pyBuffer, 0, sizeof(Py_buffer));

  SizeType      size;
  SizeType      sizeFortran;
  SizeValueType numberOfPixels = 1;

  const void * buffer;

  long         numberOfComponents = 1;
  unsigned int dimension = 0;

  size_t pixelSize = sizeof(ComponentType);
  size_t len = 1;

  if (PyObject_GetBuffer(arr, &pyBuffer, PyBUF_ND | PyBUF_ANY_CONTIGUOUS) == -1)
  {
    PyErr_SetString(PyExc_RuntimeError, "Cannot get an instance of NumPy array.");
    PyBuffer_Release(&pyBuffer);
    return nullptr;
  }
  else
  {
    bufferLength = pyBuffer.len;
    buffer = pyBuffer.buf;
  }
  PyBuffer_Release(&pyBuffer);

  shapeseq = PySequence_Fast(shape, "expected sequence");
  dimension = PySequence_Size(shape);

  numberOfComponents = PyInt_AsLong(numOfComponent);

  for (unsigned int i = 0; i < dimension; ++i)
  {
    item = PySequence_Fast_GET_ITEM(shapeseq, i);
    size[i] = (SizeValueType)PyInt_AsLong(item);
    sizeFortran[dimension - 1 - i] = (SizeValueType)PyInt_AsLong(item);
    numberOfPixels *= size[i];
  }

  bool isFortranContiguous = false;
  if (pyBuffer.strides != NULL && pyBuffer.itemsize == pyBuffer.strides[0])
  {
    isFortranContiguous = true;
  }

  len = numberOfPixels * numberOfComponents * pixelSize;
  if (bufferLength != len)
  {
    PyErr_SetString(PyExc_RuntimeError, "Size mismatch of image and Buffer.");
    PyBuffer_Release(&pyBuffer);
    Py_DECREF(shapeseq);
    return nullptr;
  }

  IndexType start;
  start.Fill(0);

  RegionType region;
  region.SetIndex(start);
  region.SetSize(size);
  if (isFortranContiguous)
  {
    region.SetSize(sizeFortran);
  }
  else
  {
    region.SetSize(size);
  }

  PointType origin;
  origin.Fill(0.0);

  SpacingType spacing;
  spacing.Fill(1.0);

  using InternalPixelType = typename TImage::InternalPixelType;
  using ImporterType = ImportImageContainer<SizeValueType, InternalPixelType>;
  typename ImporterType::Pointer importer = ImporterType::New();
  constexpr bool                 importImageFilterWillOwnTheBuffer = false;
  InternalPixelType *            data = (InternalPixelType *)buffer;
  importer->SetImportPointer(data, numberOfPixels, importImageFilterWillOwnTheBuffer);

  OutputImagePointer output = TImage::New();
  output->SetRegions(region);
  output->SetOrigin(origin);
  output->SetSpacing(spacing);
  output->SetPixelContainer(importer);
  output->SetNumberOfComponentsPerPixel(numberOfComponents);

  Py_DECREF(shapeseq);
  PyBuffer_Release(&pyBuffer);

  return output;
}

} // namespace itk

#endif
<|endoftext|>


<commit_before>/*
* This is the cpp file for the StringFunctions class of cPlusPlusPlusLib
* cPPPLib - A library of functions that should be in the C++ Standard Library
* (C) - Charles Machalow - MIT License
*/

#ifndef StringFunctions_CPP
#define StringFunctions_CPP

#include "StringFunctions.h"

/// <summary>
/// Splits the original_str into a std::vector by delimiter
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="delim">The delimiter.</param>
/// <returns>std::vector<string> where each item is a string that has been delimited</returns>
std::vector<std::string> StringFunctions::splitIntoVector(const std::string &original_str, const std::string &delim)
{
	std::string working_str = original_str;
	std::vector<std::string> ret_vec;

	while (!working_str.empty())
	{
		unsigned int loc = working_str.find(delim);
		// found in string
		if (loc != std::string::npos)
		{
			ret_vec.push_back(working_str.substr(0, loc));
			working_str = working_str.substr(loc + 1);
		}
		else
		{
			ret_vec.push_back(working_str);
			break;
		}
	}

	return ret_vec;
}

/// <summary>
/// Splits the original string into a vector using all delims
/// </summary>
/// <param name="original_str">The original std::string to split.</param>
/// <param name="delims">std::vector<std::string> of delimiters.</param>
/// <returns>std::vector<std::string> of the original_str split by all delims</returns>
std::vector<std::string> StringFunctions::splitIntoVector(const std::string &original_str, const std::vector<std::string> &delims)
{
	std::vector<std::string> working_delims = delims;
	std::vector<std::string> ret_vec;

	if (working_delims.empty())
	{
		return ret_vec;
	}

	ret_vec = StringFunctions::splitIntoVector(original_str, working_delims.front());
	working_delims.erase(working_delims.begin());

	while (!working_delims.empty())
	{
		std::vector<std::string> tmp_vec;
		for (const std::string cur : ret_vec)
		{
			std::vector<std::string> inner_vec = StringFunctions::splitIntoVector(cur, working_delims.front());

			for (const std::string cur_in : inner_vec)
			{
				tmp_vec.push_back(cur_in);
			}
		}
		working_delims.erase(working_delims.begin());
		ret_vec = tmp_vec;
	}

	return ret_vec;
}

/// <summary>
/// Splits the original_str into a std::vector by whitespace.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>std::vector<string> where each item is a string that has been delimited by whitespace</returns>
std::vector<std::string> StringFunctions::splitIntoVectorByWhitespace(const std::string &original_str)
{
	std::string working_str = original_str;
	std::vector<std::string> ret_vec;

	while (!working_str.empty())
	{
		unsigned int loc = working_str.find(" ");
		// found in string
		if (loc != std::string::npos)
		{
			if (working_str.substr(0, loc) != "")
			{
				ret_vec.push_back(working_str.substr(0, loc));
			}
			working_str = working_str.substr(loc + 1);
		}
		else
		{
			if (working_str != "")
			{
				ret_vec.push_back(working_str);
			}
			break;
		}
	}

	return ret_vec;
}

/// <summary>
/// Returns a copy of the given string in Title Case
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>Copy of original_str in Title Case</returns>
std::string StringFunctions::toTitleCase(const std::string &original_str)
{
	char last_char = ' ';
	std::string ret_str = "";

	for (char c : original_str)
	{
		if (last_char == ' ')
		{
			ret_str += toupper(c);
		}
		else
		{
			ret_str += c;
		}
		last_char = c;
	}

	return ret_str;
}

/// <summary>
/// Returns a copy of the given string in UPPERCASE
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>Copy of original_str in UPPERCASE</returns>
std::string StringFunctions::toUpperCase(const std::string &original_str)
{
	std::string ret_str = "";

	for (char c : original_str)
	{
		ret_str += toupper(c);
	}

	return ret_str;
}

/// <summary>
/// Returns a copy of the given string in lowercase
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>Copy of original_str in lowercase</returns>
std::string StringFunctions::toLowerCase(const std::string &original_str)
{
	std::string ret_str = "";

	for (char c : original_str)
	{
		ret_str += tolower(c);
	}

	return ret_str;
}

/// <summary>
/// Returns a string where all cases are flipped from original_str
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>original_str with flipped case</returns>
std::string StringFunctions::swapCase(const std::string &original_str)
{
	std::string ret_str = "";

	for (char c : original_str)
	{
		if (islower(c))
		{
			ret_str += toupper(c);
		}
		else
		{
			ret_str += tolower(c);
		}
	}

	return ret_str;
}

/// <summary>
/// Slices the specified original_str between x and y using a python-style slice
/// </summary>
/// <param name="original_str">The original_str.</param>
/// <param name="slice_str">slicing info as string ex: "[1:3]"</param>
/// <returns>std::string slice from original_str. Returns "" on error</returns>
std::string StringFunctions::slice(const std::string &original_str, const std::string &slice_str)
{
	if (slice_str.size() < 3)
	{
		std::cerr << "ERROR: Improper slice string " << slice_str << ". Good Examples: \"[1]\", \"[1:2]\", \"[-1, 5]\", \"[:]\"" << std::endl;
		return "";
	}

	if (slice_str.front() != '[' || slice_str.back() != ']')
	{
		std::cerr << "ERROR: Improper slice string " << slice_str << ". Should start with \"[\" and end with \"]\"" << std::endl;
		return "";
	}

	if (slice_str == "[:]")
	{
		return std::string(original_str);
	}

	std::string working_slice = slice_str;

	//remove []s
	working_slice.erase(0, 1);
	working_slice.erase(working_slice.size() - 1, 1);

	// look for colon
	int colon_loc = working_slice.find(":");

	// colon not found, try to cast to int
	// example [1]
	if (colon_loc == std::string::npos)
	{
		int ret_index = std::stoi(working_slice);
		if ((unsigned int)abs(ret_index) > original_str.size())
		{
			std::cerr << "ERROR: Index " << ret_index << " is out of range" << std::endl;
			return "";
		}
		else if (ret_index < 0)
		{
			ret_index = original_str.size() - abs(ret_index);
		}

		return original_str.substr(ret_index, 1);
	}
	else
	{
		int l_index = 0;
		int r_index = 0;
		try
		{
			l_index = std::stoi(working_slice.substr(0, colon_loc));
		}
		catch (const std::invalid_argument &ia)
		{
			ia.what();

			//something wrong with l_index
			//it might be empty
			if (StringFunctions::isOnlyWhitespace(working_slice.substr(0, colon_loc)))
			{
				l_index = 0;
			}
		}

		try
		{
			r_index = std::stoi(working_slice.substr(colon_loc + 1));
		}
		catch (const std::invalid_argument &ia)
		{
			ia.what();

			//something wrong with r_index
			//it might be empty
			if (StringFunctions::isOnlyWhitespace(working_slice.substr(colon_loc + 1)))
			{
				r_index = original_str.size();
			}
		}

		if (l_index < 0)
		{
			l_index = std::max((int)original_str.size() - abs(l_index), (int)0);
		}

		if (r_index < 0)
		{
			r_index = original_str.size() - abs(r_index);
		}

		if (l_index == r_index || l_index >= r_index || (unsigned int) l_index > original_str.size())
		{
			return "";
		}

		return original_str.substr(l_index, (r_index - l_index));
	}
}

/// <summary>
/// Performs a left and right trim on the specified original_str.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="removal_chars">Chars to be trimmed (Defaults to all whitespace)</param>
/// <returns>A copy of the original std::string without leading and trailing whitespace</returns>
std::string StringFunctions::trim(const std::string & original_str, const std::string &removal_chars)
{
	std::string working_str = original_str;
	int rtrim_loc = working_str.find_last_not_of(removal_chars) + 1;
	int ltrim_loc = working_str.find_first_not_of(removal_chars);

	if (ltrim_loc == std::string::npos)
	{
		return "";
	}
	else
	{
		return working_str.erase(rtrim_loc).substr(ltrim_loc);
	}
}

/// <summary>
/// Performs a left trim on the specified original_str.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="removal_chars">Chars to be trimmed (Defaults to all whitespace)</param>
/// <returns>A copy of the original std::string without leading whitespace</returns>
std::string StringFunctions::ltrim(const std::string & original_str, const std::string &removal_chars)
{
	std::string working_str = original_str;
	int ltrim_loc = working_str.find_first_not_of(removal_chars);

	if (ltrim_loc == std::string::npos)
	{
		return "";
	}
	else
	{
		return working_str.substr(ltrim_loc);
	}
}

/// <summary>
/// Performs a right trim on the specified original_str.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="removal_chars">Chars to be trimmed (Defaults to all whitespace)</param>
/// <returns>A copy of the original std::string without trailing whitespace</returns>
std::string StringFunctions::rtrim(const std::string & original_str, const std::string &removal_chars)
{
	std::string working_str = original_str;
	int rtrim_loc = working_str.find_last_not_of(removal_chars) + 1;

	return working_str.erase(rtrim_loc);
}

/// <summary>
/// Determines if a given std::string only contains whitespace or is empty
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>True if the original_str only contains whitespace</returns>
bool StringFunctions::isOnlyWhitespace(const std::string &original_str)
{
	return original_str.find_first_not_of("\t\n\v\f\r ") == std::string::npos;
}

#endif StringFunctions_CPP<commit_msg>Go through vectors by reference in for each.<commit_after>/*
* This is the cpp file for the StringFunctions class of cPlusPlusPlusLib
* cPPPLib - A library of functions that should be in the C++ Standard Library
* (C) - Charles Machalow - MIT License
*/

#ifndef StringFunctions_CPP
#define StringFunctions_CPP

#include "StringFunctions.h"

/// <summary>
/// Splits the original_str into a std::vector by delimiter
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="delim">The delimiter.</param>
/// <returns>std::vector<string> where each item is a string that has been delimited</returns>
std::vector<std::string> StringFunctions::splitIntoVector(const std::string &original_str, const std::string &delim)
{
	std::string working_str = original_str;
	std::vector<std::string> ret_vec;

	while (!working_str.empty())
	{
		unsigned int loc = working_str.find(delim);
		// found in string
		if (loc != std::string::npos)
		{
			ret_vec.push_back(working_str.substr(0, loc));
			working_str = working_str.substr(loc + 1);
		}
		else
		{
			ret_vec.push_back(working_str);
			break;
		}
	}

	return ret_vec;
}

/// <summary>
/// Splits the original string into a vector using all delims
/// </summary>
/// <param name="original_str">The original std::string to split.</param>
/// <param name="delims">std::vector<std::string> of delimiters.</param>
/// <returns>std::vector<std::string> of the original_str split by all delims</returns>
std::vector<std::string> StringFunctions::splitIntoVector(const std::string &original_str, const std::vector<std::string> &delims)
{
	std::vector<std::string> working_delims = delims;
	std::vector<std::string> ret_vec;

	if (working_delims.empty())
	{
		return ret_vec;
	}

	ret_vec = StringFunctions::splitIntoVector(original_str, working_delims.front());
	working_delims.erase(working_delims.begin());

	while (!working_delims.empty())
	{
		std::vector<std::string> tmp_vec;
		for (const std::string &cur : ret_vec)
		{
			std::vector<std::string> inner_vec = StringFunctions::splitIntoVector(cur, working_delims.front());

			for (const std::string &cur_in : inner_vec)
			{
				tmp_vec.push_back(cur_in);
			}
		}
		working_delims.erase(working_delims.begin());
		ret_vec = tmp_vec;
	}

	return ret_vec;
}

/// <summary>
/// Splits the original_str into a std::vector by whitespace.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>std::vector<string> where each item is a string that has been delimited by whitespace</returns>
std::vector<std::string> StringFunctions::splitIntoVectorByWhitespace(const std::string &original_str)
{
	std::string working_str = original_str;
	std::vector<std::string> ret_vec;

	while (!working_str.empty())
	{
		unsigned int loc = working_str.find(" ");
		// found in string
		if (loc != std::string::npos)
		{
			if (working_str.substr(0, loc) != "")
			{
				ret_vec.push_back(working_str.substr(0, loc));
			}
			working_str = working_str.substr(loc + 1);
		}
		else
		{
			if (working_str != "")
			{
				ret_vec.push_back(working_str);
			}
			break;
		}
	}

	return ret_vec;
}

/// <summary>
/// Returns a copy of the given string in Title Case
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>Copy of original_str in Title Case</returns>
std::string StringFunctions::toTitleCase(const std::string &original_str)
{
	char last_char = ' ';
	std::string ret_str = "";

	for (char c : original_str)
	{
		if (last_char == ' ')
		{
			ret_str += toupper(c);
		}
		else
		{
			ret_str += c;
		}
		last_char = c;
	}

	return ret_str;
}

/// <summary>
/// Returns a copy of the given string in UPPERCASE
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>Copy of original_str in UPPERCASE</returns>
std::string StringFunctions::toUpperCase(const std::string &original_str)
{
	std::string ret_str = "";

	for (char c : original_str)
	{
		ret_str += toupper(c);
	}

	return ret_str;
}

/// <summary>
/// Returns a copy of the given string in lowercase
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>Copy of original_str in lowercase</returns>
std::string StringFunctions::toLowerCase(const std::string &original_str)
{
	std::string ret_str = "";

	for (char c : original_str)
	{
		ret_str += tolower(c);
	}

	return ret_str;
}

/// <summary>
/// Returns a string where all cases are flipped from original_str
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>original_str with flipped case</returns>
std::string StringFunctions::swapCase(const std::string &original_str)
{
	std::string ret_str = "";

	for (char c : original_str)
	{
		if (islower(c))
		{
			ret_str += toupper(c);
		}
		else
		{
			ret_str += tolower(c);
		}
	}

	return ret_str;
}

/// <summary>
/// Slices the specified original_str between x and y using a python-style slice
/// </summary>
/// <param name="original_str">The original_str.</param>
/// <param name="slice_str">slicing info as string ex: "[1:3]"</param>
/// <returns>std::string slice from original_str. Returns "" on error</returns>
std::string StringFunctions::slice(const std::string &original_str, const std::string &slice_str)
{
	if (slice_str.size() < 3)
	{
		std::cerr << "ERROR: Improper slice string " << slice_str << ". Good Examples: \"[1]\", \"[1:2]\", \"[-1, 5]\", \"[:]\"" << std::endl;
		return "";
	}

	if (slice_str.front() != '[' || slice_str.back() != ']')
	{
		std::cerr << "ERROR: Improper slice string " << slice_str << ". Should start with \"[\" and end with \"]\"" << std::endl;
		return "";
	}

	if (slice_str == "[:]")
	{
		return std::string(original_str);
	}

	std::string working_slice = slice_str;

	//remove []s
	working_slice.erase(0, 1);
	working_slice.erase(working_slice.size() - 1, 1);

	// look for colon
	int colon_loc = working_slice.find(":");

	// colon not found, try to cast to int
	// example [1]
	if (colon_loc == std::string::npos)
	{
		int ret_index = std::stoi(working_slice);
		if ((unsigned int)abs(ret_index) > original_str.size())
		{
			std::cerr << "ERROR: Index " << ret_index << " is out of range" << std::endl;
			return "";
		}
		else if (ret_index < 0)
		{
			ret_index = original_str.size() - abs(ret_index);
		}

		return original_str.substr(ret_index, 1);
	}
	else
	{
		int l_index = 0;
		int r_index = 0;
		try
		{
			l_index = std::stoi(working_slice.substr(0, colon_loc));
		}
		catch (const std::invalid_argument &ia)
		{
			ia.what();

			//something wrong with l_index
			//it might be empty
			if (StringFunctions::isOnlyWhitespace(working_slice.substr(0, colon_loc)))
			{
				l_index = 0;
			}
		}

		try
		{
			r_index = std::stoi(working_slice.substr(colon_loc + 1));
		}
		catch (const std::invalid_argument &ia)
		{
			ia.what();

			//something wrong with r_index
			//it might be empty
			if (StringFunctions::isOnlyWhitespace(working_slice.substr(colon_loc + 1)))
			{
				r_index = original_str.size();
			}
		}

		if (l_index < 0)
		{
			l_index = std::max((int)original_str.size() - abs(l_index), (int)0);
		}

		if (r_index < 0)
		{
			r_index = original_str.size() - abs(r_index);
		}

		if (l_index == r_index || l_index >= r_index || (unsigned int) l_index > original_str.size())
		{
			return "";
		}

		return original_str.substr(l_index, (r_index - l_index));
	}
}

/// <summary>
/// Performs a left and right trim on the specified original_str.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="removal_chars">Chars to be trimmed (Defaults to all whitespace)</param>
/// <returns>A copy of the original std::string without leading and trailing whitespace</returns>
std::string StringFunctions::trim(const std::string & original_str, const std::string &removal_chars)
{
	std::string working_str = original_str;
	int rtrim_loc = working_str.find_last_not_of(removal_chars) + 1;
	int ltrim_loc = working_str.find_first_not_of(removal_chars);

	if (ltrim_loc == std::string::npos)
	{
		return "";
	}
	else
	{
		return working_str.erase(rtrim_loc).substr(ltrim_loc);
	}
}

/// <summary>
/// Performs a left trim on the specified original_str.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="removal_chars">Chars to be trimmed (Defaults to all whitespace)</param>
/// <returns>A copy of the original std::string without leading whitespace</returns>
std::string StringFunctions::ltrim(const std::string & original_str, const std::string &removal_chars)
{
	std::string working_str = original_str;
	int ltrim_loc = working_str.find_first_not_of(removal_chars);

	if (ltrim_loc == std::string::npos)
	{
		return "";
	}
	else
	{
		return working_str.substr(ltrim_loc);
	}
}

/// <summary>
/// Performs a right trim on the specified original_str.
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <param name="removal_chars">Chars to be trimmed (Defaults to all whitespace)</param>
/// <returns>A copy of the original std::string without trailing whitespace</returns>
std::string StringFunctions::rtrim(const std::string & original_str, const std::string &removal_chars)
{
	std::string working_str = original_str;
	int rtrim_loc = working_str.find_last_not_of(removal_chars) + 1;

	return working_str.erase(rtrim_loc);
}

/// <summary>
/// Determines if a given std::string only contains whitespace or is empty
/// </summary>
/// <param name="original_str">The original std::string</param>
/// <returns>True if the original_str only contains whitespace</returns>
bool StringFunctions::isOnlyWhitespace(const std::string &original_str)
{
	return original_str.find_first_not_of("\t\n\v\f\r ") == std::string::npos;
}

#endif StringFunctions_CPP<|endoftext|>


<commit_before><commit_msg>Added test for mitkLabel<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkLabel.h"
#include "mitkStringProperty.h"
#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>

class mitkLabelTestSuite : public mitk::TestFixture
{
  CPPUNIT_TEST_SUITE(mitkLabelTestSuite);
  MITK_TEST(TestSetLock);
  MITK_TEST(TestSetVisibility);
  MITK_TEST(TestSetOpacity);
  MITK_TEST(TestSetName);
  MITK_TEST(TestSetCenterOfMassIndex);
  MITK_TEST(TestSetCenterOfMassCoordinates);
  MITK_TEST(TestSetColor);
  MITK_TEST(TestSetValue);
  MITK_TEST(TestSetLayer);
  MITK_TEST(TestSetProperty);
  CPPUNIT_TEST_SUITE_END();

public:

  void TestSetLock()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    CPPUNIT_ASSERT_MESSAGE("Initial label not locked", label->GetLocked() == true);

    label->SetLocked(false);
    CPPUNIT_ASSERT_MESSAGE("Label should not be locked", label->GetLocked() == false);
  }

  void TestSetVisibility()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    CPPUNIT_ASSERT_MESSAGE("Initial label not visible", label->GetVisible() == true);

    label->SetVisible(false);
    CPPUNIT_ASSERT_MESSAGE("Label should not be visible", label->GetVisible() == false);
  }

  void TestSetOpacity()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong opacity", mitk::Equal(label->GetOpacity(), 0.6f));

    label->SetOpacity(0.32f);
    CPPUNIT_ASSERT_MESSAGE("Label has wrong opacity", mitk::Equal(label->GetOpacity(), 0.32f));
  }

  void TestSetName()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    std::string initialName("noName!");
    std::string labelName = label->GetName();
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong name", initialName.compare(labelName) == 0);

    label->SetName("AwesomeLabel");
    labelName = label->GetName();
    CPPUNIT_ASSERT_MESSAGE("Label has wrong name", labelName.compare("AwesomeLabel") == 0);
  }

  void TestSetCenterOfMassIndex()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    mitk::Point3D currentIndex = label->GetCenterOfMassIndex();
    mitk::Point3D indexToBeCompared;
    indexToBeCompared.Fill(0);
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong center of mass index", mitk::Equal(currentIndex, indexToBeCompared));

    indexToBeCompared.SetElement(1, 234.3f);
    indexToBeCompared.SetElement(2, -53);
    indexToBeCompared.SetElement(3, 120);
    label->SetCenterOfMassIndex(indexToBeCompared);
    currentIndex = label->GetCenterOfMassIndex();
    CPPUNIT_ASSERT_MESSAGE("Label has wrong center of mass index", mitk::Equal(currentIndex, indexToBeCompared));
  }

  void TestSetCenterOfMassCoordinates()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    mitk::Point3D currentPoint = label->GetCenterOfMassCoordinates();
    mitk::Point3D pointToBeCompared;
    pointToBeCompared.Fill(0);
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong center of mass index", mitk::Equal(currentPoint, pointToBeCompared));

    pointToBeCompared.SetElement(1, 234.3f);
    pointToBeCompared.SetElement(2, -53);
    pointToBeCompared.SetElement(3, 120);
    label->SetCenterOfMassCoordinates(pointToBeCompared);
    currentPoint = label->GetCenterOfMassCoordinates();
    CPPUNIT_ASSERT_MESSAGE("Label has wrong center of mass index", mitk::Equal(currentPoint, pointToBeCompared));
  }

  void TestSetColor()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    mitk::Color currentColor = label->GetColor();
    mitk::Color colorToBeCompared;
    colorToBeCompared.Set(0,0,0);
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong color", currentColor.GetBlue() == colorToBeCompared.GetBlue());
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong color", currentColor.GetGreen() == colorToBeCompared.GetGreen());
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong color", currentColor.GetRed() == colorToBeCompared.GetRed());

    colorToBeCompared.Set(0.4f,0.3f,1.0f);
    label->SetColor(colorToBeCompared);
    currentColor = label->GetColor();
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong color", currentColor.GetBlue() == colorToBeCompared.GetBlue());
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong color", currentColor.GetGreen() == colorToBeCompared.GetGreen());
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong color", currentColor.GetRed() == colorToBeCompared.GetRed());
  }

  void TestSetValue()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    int initialValue(-1);
    int valueToBeCompared = label->GetValue();
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong value", initialValue == valueToBeCompared);

    label->SetValue(12345);
    valueToBeCompared = 12345;
    initialValue = label->GetValue();
    CPPUNIT_ASSERT_MESSAGE("Label has wrong value", initialValue == valueToBeCompared);
  }

  void TestSetLayer()
  {
    mitk::Label::Pointer label = mitk::Label::New();
    int initialLayer(-1);
    int valueToBeCompared = label->GetValue();
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong value", initialLayer == valueToBeCompared);

    label->SetLayer(2);
    valueToBeCompared = 2;
    initialLayer = label->GetLayer();
    CPPUNIT_ASSERT_MESSAGE("Label has wrong value", initialLayer == valueToBeCompared);
  }

  void TestSetProperty()
  {
    mitk::Label::Pointer label = mitk::Label::New();

    mitk::StringProperty::Pointer prop = mitk::StringProperty::New("abc");
    label->SetProperty("cba",prop);
    std::string propVal("");
    label->GetStringProperty("cba", propVal);
    CPPUNIT_ASSERT_MESSAGE("Initial label has wrong value", propVal.compare("abc") == 0);
  }
};

MITK_TEST_SUITE_REGISTRATION(mitkLabel)
<|endoftext|>


<commit_before>/*
 *  lineedit.cpp  -  Line edit widget with extra drag and drop options
 *  Program:  kalarm
 *  Copyright (c) 2003 - 2005 by David Jarvie <software@astrojar.org.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "kalarm.h"

#include <QRegExp>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFocusEvent>

#include <k3urldrag.h>
#include <kurlcompletion.h>

#include <libkdepim/maillistdrag.h>
#include <libkdepim/kvcarddrag.h>
#include <libkcal/icaldrag.h>

#include "lineedit.moc"

/*=============================================================================
= Class LineEdit
= Line edit which accepts drag and drop of text, URLs and/or email addresses.
* It has an option to prevent its contents being selected when it receives
= focus.
=============================================================================*/
LineEdit::LineEdit(Type type, QWidget* parent)
	: KLineEdit(parent),
	  mType(type),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

LineEdit::LineEdit(QWidget* parent)
	: KLineEdit(parent),
	  mType(Text),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

void LineEdit::init()
{
	if (mType == Url)
	{
		setCompletionMode(KGlobalSettings::CompletionShell);
		KURLCompletion* comp = new KURLCompletion(KURLCompletion::FileCompletion);
		comp->setReplaceHome(true);
		setCompletionObject(comp);
		setAutoDeleteCompletionObject(true);
	}
	else
		setCompletionMode(KGlobalSettings::CompletionNone);
}

/******************************************************************************
*  Called when the line edit receives focus.
*  If 'noSelect' is true, prevent the contents being selected.
*/
void LineEdit::focusInEvent(QFocusEvent* e)
{
	QFocusEvent newe(QEvent::FocusIn, (mNoSelect ? Qt::OtherFocusReason : e->reason()));
	KLineEdit::focusInEvent(&newe);
	mNoSelect = false;
}

void LineEdit::setText(const QString& text)
{
	KLineEdit::setText(text);
	setCursorPosition(mSetCursorAtEnd ? text.length() : 0);
}

void LineEdit::dragEnterEvent(QDragEnterEvent* e)
{
	const QMimeData* data = e->mimeData();
	bool ok;
	if (KCal::ICalDrag::canDecode(e))
		ok = false;   // don't accept "text/calendar" objects
	else
		ok = (data->hasText()
		   || K3URLDrag::canDecode(e)
		   || mType != Url && KPIM::MailListDrag::canDecode(e)
		   || mType == Emails && KVCardDrag::canDecode(e));
	if (ok)
		e->accept(rect());
	else
		e->ignore(rect());
}

void LineEdit::dropEvent(QDropEvent* e)
{
	const QMimeData* data = e->mimeData();
	QString               newText;
	QStringList           newEmails;
	KPIM::MailList        mailList;
	KURL::List            files;
	KABC::Addressee::List addrList;

	if (mType != Url
	&&  data->hasFormat(KPIM::MailListDrag::format())
	&&  KPIM::MailListDrag::decode(e, mailList))
	{
		// KMail message(s) - ignore all but the first
		if (mailList.count())
		{
			if (mType == Emails)
				newText = mailList.first().from();
			else
				setText(mailList.first().subject());    // replace any existing text
		}
	}
	// This must come before K3URLDrag
	else if (mType == Emails
	&&  KVCardDrag::canDecode(e)  &&  KVCardDrag::decode(e, addrList))
	{
		// KAddressBook entries
		for (KABC::Addressee::List::Iterator it = addrList.begin();  it != addrList.end();  ++it)
		{
			QString em((*it).fullEmail());
			if (!em.isEmpty())
				newEmails.append(em);
		}
	}
	else if (K3URLDrag::decode(e, files)  &&  files.count())
	{
		// URL(s)
		switch (mType)
		{
			case Url:
				// URL entry field - ignore all but the first dropped URL
				setText(files.first().prettyURL());    // replace any existing text
				break;
			case Emails:
			{
				// Email entry field - ignore all but mailto: URLs
				QString mailto = QString::fromLatin1("mailto");
				for (KURL::List::Iterator it = files.begin();  it != files.end();  ++it)
				{
					if ((*it).protocol() == mailto)
						newEmails.append((*it).path());
				}
				break;
			}
			case Text:
				newText = files.first().prettyURL();
				break;
		}
	}
	else if (data->hasText())
	{
		// Plain text
		QString txt = data->text();
		if (mType == Emails)
		{
			// Remove newlines from a list of email addresses, and allow an eventual mailto: protocol
			QString mailto = QString::fromLatin1("mailto:");
			newEmails = txt.split(QRegExp("[\r\n]+"), QString::SkipEmptyParts);
			for (QStringList::Iterator it = newEmails.begin();  it != newEmails.end();  ++it)
			{
				if ((*it).startsWith(mailto))
				{
					KURL url(*it);
					*it = url.path();
				}
			}
		}
		else
		{
			int newline = txt.indexOf(QChar('\n'));
			newText = (newline >= 0) ? txt.left(newline) : txt;
		}
	}

	if (newEmails.count())
	{
		newText = newEmails.join(",");
		int c = cursorPosition();
		if (c > 0)
			newText.prepend(",");
		if (c < static_cast<int>(text().length()))
			newText.append(",");
	}
	if (!newText.isEmpty())
		insert(newText);
}
<commit_msg>Remove KDE 3 compatibility code<commit_after>/*
 *  lineedit.cpp  -  Line edit widget with extra drag and drop options
 *  Program:  kalarm
 *  Copyright (c) 2003 - 2005 by David Jarvie <software@astrojar.org.uk>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "kalarm.h"

#include <QRegExp>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFocusEvent>

#include <kurl.h>
#include <kurlcompletion.h>

#include <libkdepim/maillistdrag.h>
#include <libkdepim/kvcarddrag.h>
#include <libkcal/icaldrag.h>

#include "lineedit.moc"

/*=============================================================================
= Class LineEdit
= Line edit which accepts drag and drop of text, URLs and/or email addresses.
* It has an option to prevent its contents being selected when it receives
= focus.
=============================================================================*/
LineEdit::LineEdit(Type type, QWidget* parent)
	: KLineEdit(parent),
	  mType(type),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

LineEdit::LineEdit(QWidget* parent)
	: KLineEdit(parent),
	  mType(Text),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

void LineEdit::init()
{
	if (mType == Url)
	{
		setCompletionMode(KGlobalSettings::CompletionShell);
		KURLCompletion* comp = new KURLCompletion(KURLCompletion::FileCompletion);
		comp->setReplaceHome(true);
		setCompletionObject(comp);
		setAutoDeleteCompletionObject(true);
	}
	else
		setCompletionMode(KGlobalSettings::CompletionNone);
}

/******************************************************************************
*  Called when the line edit receives focus.
*  If 'noSelect' is true, prevent the contents being selected.
*/
void LineEdit::focusInEvent(QFocusEvent* e)
{
	QFocusEvent newe(QEvent::FocusIn, (mNoSelect ? Qt::OtherFocusReason : e->reason()));
	KLineEdit::focusInEvent(&newe);
	mNoSelect = false;
}

void LineEdit::setText(const QString& text)
{
	KLineEdit::setText(text);
	setCursorPosition(mSetCursorAtEnd ? text.length() : 0);
}

void LineEdit::dragEnterEvent(QDragEnterEvent* e)
{
	const QMimeData* data = e->mimeData();
	bool ok;
	if (KCal::ICalDrag::canDecode(e))
		ok = false;   // don't accept "text/calendar" objects
	else
		ok = (data->hasText()
		   || KURL::List::canDecode(data)
		   || mType != Url && KPIM::MailListDrag::canDecode(e)
		   || mType == Emails && KVCardDrag::canDecode(e));
	if (ok)
		e->accept(rect());
	else
		e->ignore(rect());
}

void LineEdit::dropEvent(QDropEvent* e)
{
	const QMimeData* data = e->mimeData();
	QString               newText;
	QStringList           newEmails;
	KPIM::MailList        mailList;
	KURL::List            files;
	KABC::Addressee::List addrList;

	if (mType != Url
	&&  data->hasFormat(KPIM::MailListDrag::format())
	&&  KPIM::MailListDrag::decode(e, mailList))
	{
		// KMail message(s) - ignore all but the first
		if (mailList.count())
		{
			if (mType == Emails)
				newText = mailList.first().from();
			else
				setText(mailList.first().subject());    // replace any existing text
		}
	}
	// This must come before KURL
	else if (mType == Emails
	&&  KVCardDrag::canDecode(e)  &&  KVCardDrag::decode(e, addrList))
	{
		// KAddressBook entries
		for (KABC::Addressee::List::Iterator it = addrList.begin();  it != addrList.end();  ++it)
		{
			QString em((*it).fullEmail());
			if (!em.isEmpty())
				newEmails.append(em);
		}
	}
	else if (!(files = KURL::List::fromMimeData(data)).isEmpty())
	{
		// URL(s)
		switch (mType)
		{
			case Url:
				// URL entry field - ignore all but the first dropped URL
				setText(files.first().prettyURL());    // replace any existing text
				break;
			case Emails:
			{
				// Email entry field - ignore all but mailto: URLs
				QString mailto = QString::fromLatin1("mailto");
				for (KURL::List::Iterator it = files.begin();  it != files.end();  ++it)
				{
					if ((*it).protocol() == mailto)
						newEmails.append((*it).path());
				}
				break;
			}
			case Text:
				newText = files.first().prettyURL();
				break;
		}
	}
	else if (data->hasText())
	{
		// Plain text
		QString txt = data->text();
		if (mType == Emails)
		{
			// Remove newlines from a list of email addresses, and allow an eventual mailto: protocol
			QString mailto = QString::fromLatin1("mailto:");
			newEmails = txt.split(QRegExp("[\r\n]+"), QString::SkipEmptyParts);
			for (QStringList::Iterator it = newEmails.begin();  it != newEmails.end();  ++it)
			{
				if ((*it).startsWith(mailto))
				{
					KURL url(*it);
					*it = url.path();
				}
			}
		}
		else
		{
			int newline = txt.indexOf(QChar('\n'));
			newText = (newline >= 0) ? txt.left(newline) : txt;
		}
	}

	if (newEmails.count())
	{
		newText = newEmails.join(",");
		int c = cursorPosition();
		if (c > 0)
			newText.prepend(",");
		if (c < static_cast<int>(text().length()))
			newText.append(",");
	}
	if (!newText.isEmpty())
		insert(newText);
}
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2005 Till Adam <adam@kde.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of this program with any edition of
 *  the Qt library by Trolltech AS, Norway (or with modified versions
 *  of Qt that use the same license as Qt), and distribute linked
 *  combinations including the two.  You must obey the GNU General
 *  Public License in all respects for all of the code used other than
 *  Qt.  If you modify this file, you may extend this exception to
 *  your version of the file, but you are not obligated to do so.  If
 *  you do not wish to do so, delete this exception statement from
 *  your version.
 */

#include "copyfolderjob.h"
#include "folderstorage.h"
#include "kmacctcachedimap.h"
#include "kmfoldercachedimap.h"
#include "kmfolder.h"
#include "kmfolderdir.h"
#include "kmfoldertype.h"
#include "kmfoldermgr.h"
#include "kmcommands.h"
#include "kmmsgbase.h"
#include "undostack.h"

#include <kconfiggroup.h>
#include <kdebug.h>
#include <klocale.h>

using namespace KMail;

CopyFolderJob::CopyFolderJob( FolderStorage* const storage, KMFolderDir* const newParent )
 : FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
   mStorage( storage ), mNewParent( newParent ),
   mNewFolder( 0 ), mNextChildFolder( 0 )
{
  if ( mStorage->folder()->child() &&
       mStorage->folder()->child()->size() > 0 ) {
    mHasChildFolders = true;
    mChildFolderNodeIterator = mStorage->folder()->child()->begin();
  }
  else
    mHasChildFolders = false;

  mStorage->open( "copyfolder" );
}

CopyFolderJob::~CopyFolderJob()
{
  kDebug(5006) << k_funcinfo << endl;
  if ( mNewFolder )
    mNewFolder->setMoveInProgress( false );
  if ( mStorage )
    mStorage->close( "copyfolder" );
}

/*
 * The basic strategy is to first create the target folder, then copy all the mail
 * from the source to the target folder, then recurse for each of the folder's children
 */
void CopyFolderJob::execute()
{
  if ( createTargetDir() ) {
    copyMessagesToTargetDir();
  }
}

void CopyFolderJob::copyMessagesToTargetDir()
{
  // Hmmmm. Tasty hack. Can I have fries with that?
  mStorage->blockSignals( true );
  // move all messages to the new folder
  QList<KMMsgBase*> msgList;
  for ( int i = 0; i < mStorage->count(); i++ )
  {
    KMMsgBase* msgBase = mStorage->getMsgBase( i );
    assert( msgBase );
    msgList.append( msgBase );
  }
  if ( msgList.count() == 0 ) {
    slotCopyNextChild(); // no contents, check subfolders
    mStorage->blockSignals( false );
  } else {
    KMCommand *command = new KMCopyCommand( mNewFolder, msgList );
    connect( command, SIGNAL( completed( KMCommand * ) ),
        this, SLOT( slotCopyCompleted( KMCommand * ) ) );
    command->start();
  }
}

void CopyFolderJob::slotCopyCompleted( KMCommand* command )
{
  kDebug(5006) << k_funcinfo << (command?command->result():0) << endl;
  disconnect( command, SIGNAL( completed( KMCommand * ) ),
      this, SLOT( slotCopyCompleted( KMCommand * ) ) );

  mStorage->blockSignals( false );

  if ( command && command->result() != KMCommand::OK ) {
    rollback();
    return;
  }
  // if we have children, recurse
  if ( mHasChildFolders )
    slotCopyNextChild();
  else {
    emit folderCopyComplete( true );
    deleteLater();
  }
}

void CopyFolderJob::slotCopyNextChild( bool success )
{
  if ( mNextChildFolder )
    mNextChildFolder->close( "copyfolder" ); // refcount
  // previous sibling failed
  if ( !success ) {
    kDebug(5006) << "Failed to copy one subfolder, let's not continue:  " << mNewFolder->prettyUrl() << endl;
    rollback();
    emit folderCopyComplete( false );
    deleteLater();
  }

  //Attempt to find the next child folder which is not a directory
  KMFolderNode* node = 0;
  bool folderFound = false;
  if ( mHasChildFolders )
    for ( ; mChildFolderNodeIterator != mStorage->folder()->child()->end();
          ++mChildFolderNodeIterator ) {
      node = *mChildFolderNodeIterator;
      if ( !node->isDir() ) {
        folderFound = true;
        break;
      }
    }

  if ( folderFound ) {
    mNextChildFolder = static_cast<KMFolder*>(node);
    ++mChildFolderNodeIterator;
  } else {
    // no more children, we are done
    emit folderCopyComplete( true );
    deleteLater();
    return;
  }

  KMFolderDir * const dir = mNewFolder->createChildFolder();
  if ( !dir ) {
    kDebug(5006) << "Failed to create subfolders of:  " << mNewFolder->prettyUrl() << endl;
    emit folderCopyComplete( false );
    deleteLater();
    return;
  }
  // let it do its thing and report back when we are ready to do the next sibling
  mNextChildFolder->open( "copyfolder" ); // refcount
  FolderJob* job = new CopyFolderJob( mNextChildFolder->storage(), dir);
  connect( job, SIGNAL( folderCopyComplete( bool ) ),
           this, SLOT( slotCopyNextChild( bool ) ) );
  job->start();
}

// FIXME factor into CreateFolderJob and make async, so it works with online imap
// (create folder code taken from newfolderdialog.cpp)
bool CopyFolderJob::createTargetDir()
{
  // get the default mailbox type
  KConfig * const config = KMKernel::config();
  KConfigGroup saver(config, "General");
  int deftype = saver.readEntry("default-mailbox-format", 1);
  if ( deftype < 0 || deftype > 1 ) deftype = 1;

  // the type of the new folder
  KMFolderType typenew =
    ( deftype == 0 ) ? KMFolderTypeMbox : KMFolderTypeMaildir;
  if ( mNewParent->owner() )
    typenew = mNewParent->owner()->folderType();

  bool success = false, waitForFolderCreation = false;

  if ( mNewParent->owner() && mNewParent->owner()->folderType() == KMFolderTypeImap ) {
    KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mNewParent->owner()->storage() );
    KMAcctImap *anAccount = selectedStorage->account();
    // check if a connection is available BEFORE creating the folder
    if (anAccount->makeConnection() == ImapAccountBase::Connected) {
      mNewFolder = kmkernel->imapFolderMgr()->createFolder( mStorage->folder()->name(), false, typenew, mNewParent );
      if ( mNewFolder ) {
        QString imapPath;
        imapPath = anAccount->createImapPath( selectedStorage->imapPath(), mStorage->folder()->name() );
        KMFolderImap* newStorage = static_cast<KMFolderImap*>( mNewFolder->storage() );
        connect( selectedStorage, SIGNAL(folderCreationResult(const QString&, bool)),
                 this, SLOT(folderCreationDone(const QString&, bool)) );
        selectedStorage->createFolder( mStorage->folder()->name(), QString() ); // create it on the server
        newStorage->initializeFrom( selectedStorage, imapPath, QString() );
        static_cast<KMFolderImap*>(mNewParent->owner()->storage())->setAccount( selectedStorage->account() );
        waitForFolderCreation = true;
        success = true;
      }
    }
  } else if ( mNewParent->owner() && mNewParent->owner()->folderType() == KMFolderTypeCachedImap ) {
    mNewFolder = kmkernel->dimapFolderMgr()->createFolder( mStorage->folder()->name(), false, typenew, mNewParent );
    if ( mNewFolder ) {
      KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mNewParent->owner()->storage() );
      KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( mNewFolder->storage() );
      newStorage->initializeFrom( selectedStorage );
      success = true;
    }
  } else {
    // local folder
    mNewFolder = kmkernel->folderMgr()->createFolder(mStorage->folder()->name(), false, typenew, mNewParent );
    if ( mNewFolder )
      success = true;
  }

  if ( !success ) {
      kWarning(5006) << k_funcinfo << "could not create folder" << endl;
      emit folderCopyComplete( false );
      deleteLater();
      return false;
  }

  mNewFolder->setMoveInProgress( true );

  // inherit the folder type
  // FIXME we should probably copy over most if not all settings
  mNewFolder->storage()->setContentsType( mStorage->contentsType(), true /*quiet*/ );
  mNewFolder->storage()->writeConfig();
  kDebug(5006)<< "CopyJob::createTargetDir - " << mStorage->folder()->idString()
    << " |=> " << mNewFolder->idString() << endl;
  return !waitForFolderCreation;
}

void CopyFolderJob::rollback()
{
  // copy failed - rollback the last transaction
//   kmkernel->undoStack()->undo();
  // .. and delete the new folder
  if ( mNewFolder ) {
    if ( mNewFolder->folderType() == KMFolderTypeImap )
    {
      kmkernel->imapFolderMgr()->remove( mNewFolder );
    } else if ( mNewFolder->folderType() == KMFolderTypeCachedImap )
    {
      // tell the account (see KMFolderCachedImap::listDirectory2)
      KMFolderCachedImap* folder = static_cast<KMFolderCachedImap*>(mNewFolder->storage());
      KMAcctCachedImap* acct = folder->account();
      if ( acct )
        acct->addDeletedFolder( folder->imapPath() );
      kmkernel->dimapFolderMgr()->remove( mNewFolder );
    } else if ( mNewFolder->folderType() == KMFolderTypeSearch )
    {
      // invalid
      kWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
    } else {
      kmkernel->folderMgr()->remove( mNewFolder );
    }
  }

  emit folderCopyComplete( false );
  deleteLater();
}

void CopyFolderJob::folderCreationDone(const QString & name, bool success)
{
  if ( mStorage->folder()->name() != name )
    return; // not our business
  kDebug(5006) << k_funcinfo << success << endl;

  if ( !success ) {
    rollback();
  } else {
    copyMessagesToTargetDir();
  }
}
#include "copyfolderjob.moc"
<commit_msg>Forwardport SVN commit 687341 by vkrause:<commit_after>/**
 *  Copyright (c) 2005 Till Adam <adam@kde.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of this program with any edition of
 *  the Qt library by Trolltech AS, Norway (or with modified versions
 *  of Qt that use the same license as Qt), and distribute linked
 *  combinations including the two.  You must obey the GNU General
 *  Public License in all respects for all of the code used other than
 *  Qt.  If you modify this file, you may extend this exception to
 *  your version of the file, but you are not obligated to do so.  If
 *  you do not wish to do so, delete this exception statement from
 *  your version.
 */

#include "copyfolderjob.h"
#include "folderstorage.h"
#include "kmacctcachedimap.h"
#include "kmfoldercachedimap.h"
#include "kmfolder.h"
#include "kmfolderdir.h"
#include "kmfoldertype.h"
#include "kmfoldermgr.h"
#include "kmcommands.h"
#include "kmmsgbase.h"
#include "undostack.h"

#include <kconfiggroup.h>
#include <kdebug.h>
#include <klocale.h>

using namespace KMail;

CopyFolderJob::CopyFolderJob( FolderStorage* const storage, KMFolderDir* const newParent )
 : FolderJob( 0, tOther, (storage ? storage->folder() : 0) ),
   mStorage( storage ), mNewParent( newParent ),
   mNewFolder( 0 ), mNextChildFolder( 0 )
{
  if ( mStorage->folder()->child() &&
       mStorage->folder()->child()->size() > 0 ) {
    mHasChildFolders = true;
    mChildFolderNodeIterator = mStorage->folder()->child()->begin();
  }
  else
    mHasChildFolders = false;

  mStorage->open( "copyfolder" );
}

CopyFolderJob::~CopyFolderJob()
{
  kDebug(5006) << k_funcinfo << endl;
  if ( mNewFolder )
    mNewFolder->setMoveInProgress( false );
  if ( mStorage )
    mStorage->close( "copyfolder" );
}

/*
 * The basic strategy is to first create the target folder, then copy all the mail
 * from the source to the target folder, then recurse for each of the folder's children
 */
void CopyFolderJob::execute()
{
  if ( createTargetDir() ) {
    copyMessagesToTargetDir();
  }
}

void CopyFolderJob::copyMessagesToTargetDir()
{
  // Hmmmm. Tasty hack. Can I have fries with that?
  mStorage->blockSignals( true );
  // move all messages to the new folder
  QList<KMMsgBase*> msgList;
  for ( int i = 0; i < mStorage->count(); i++ )
  {
    KMMsgBase* msgBase = mStorage->getMsgBase( i );
    assert( msgBase );
    msgList.append( msgBase );
  }
  if ( msgList.count() == 0 ) {
    mStorage->blockSignals( false );
    // ### be careful, after slotCopyNextChild() the source folder
    // (including mStorage) might already be deleted!
    slotCopyNextChild(); // no contents, check subfolders
  } else {
    KMCommand *command = new KMCopyCommand( mNewFolder, msgList );
    connect( command, SIGNAL( completed( KMCommand * ) ),
        this, SLOT( slotCopyCompleted( KMCommand * ) ) );
    command->start();
  }
}

void CopyFolderJob::slotCopyCompleted( KMCommand* command )
{
  kDebug(5006) << k_funcinfo << (command?command->result():0) << endl;
  disconnect( command, SIGNAL( completed( KMCommand * ) ),
      this, SLOT( slotCopyCompleted( KMCommand * ) ) );

  mStorage->blockSignals( false );

  if ( command && command->result() != KMCommand::OK ) {
    rollback();
    return;
  }
  // if we have children, recurse
  if ( mHasChildFolders )
    slotCopyNextChild();
  else {
    emit folderCopyComplete( true );
    deleteLater();
  }
}

void CopyFolderJob::slotCopyNextChild( bool success )
{
  if ( mNextChildFolder )
    mNextChildFolder->close( "copyfolder" ); // refcount
  // previous sibling failed
  if ( !success ) {
    kDebug(5006) << "Failed to copy one subfolder, let's not continue:  " << mNewFolder->prettyUrl() << endl;
    rollback();
    emit folderCopyComplete( false );
    deleteLater();
  }

  //Attempt to find the next child folder which is not a directory
  KMFolderNode* node = 0;
  bool folderFound = false;
  if ( mHasChildFolders )
    for ( ; mChildFolderNodeIterator != mStorage->folder()->child()->end();
          ++mChildFolderNodeIterator ) {
      node = *mChildFolderNodeIterator;
      if ( !node->isDir() ) {
        folderFound = true;
        break;
      }
    }

  if ( folderFound ) {
    mNextChildFolder = static_cast<KMFolder*>(node);
    ++mChildFolderNodeIterator;
  } else {
    // no more children, we are done
    emit folderCopyComplete( true );
    deleteLater();
    return;
  }

  KMFolderDir * const dir = mNewFolder->createChildFolder();
  if ( !dir ) {
    kDebug(5006) << "Failed to create subfolders of:  " << mNewFolder->prettyUrl() << endl;
    emit folderCopyComplete( false );
    deleteLater();
    return;
  }
  // let it do its thing and report back when we are ready to do the next sibling
  mNextChildFolder->open( "copyfolder" ); // refcount
  FolderJob* job = new CopyFolderJob( mNextChildFolder->storage(), dir);
  connect( job, SIGNAL( folderCopyComplete( bool ) ),
           this, SLOT( slotCopyNextChild( bool ) ) );
  job->start();
}

// FIXME factor into CreateFolderJob and make async, so it works with online imap
// (create folder code taken from newfolderdialog.cpp)
bool CopyFolderJob::createTargetDir()
{
  // get the default mailbox type
  KConfig * const config = KMKernel::config();
  KConfigGroup saver(config, "General");
  int deftype = saver.readEntry("default-mailbox-format", 1);
  if ( deftype < 0 || deftype > 1 ) deftype = 1;

  // the type of the new folder
  KMFolderType typenew =
    ( deftype == 0 ) ? KMFolderTypeMbox : KMFolderTypeMaildir;
  if ( mNewParent->owner() )
    typenew = mNewParent->owner()->folderType();

  bool success = false, waitForFolderCreation = false;

  if ( mNewParent->owner() && mNewParent->owner()->folderType() == KMFolderTypeImap ) {
    KMFolderImap* selectedStorage = static_cast<KMFolderImap*>( mNewParent->owner()->storage() );
    KMAcctImap *anAccount = selectedStorage->account();
    // check if a connection is available BEFORE creating the folder
    if (anAccount->makeConnection() == ImapAccountBase::Connected) {
      mNewFolder = kmkernel->imapFolderMgr()->createFolder( mStorage->folder()->name(), false, typenew, mNewParent );
      if ( mNewFolder ) {
        QString imapPath;
        imapPath = anAccount->createImapPath( selectedStorage->imapPath(), mStorage->folder()->name() );
        KMFolderImap* newStorage = static_cast<KMFolderImap*>( mNewFolder->storage() );
        connect( selectedStorage, SIGNAL(folderCreationResult(const QString&, bool)),
                 this, SLOT(folderCreationDone(const QString&, bool)) );
        selectedStorage->createFolder( mStorage->folder()->name(), QString() ); // create it on the server
        newStorage->initializeFrom( selectedStorage, imapPath, QString() );
        static_cast<KMFolderImap*>(mNewParent->owner()->storage())->setAccount( selectedStorage->account() );
        waitForFolderCreation = true;
        success = true;
      }
    }
  } else if ( mNewParent->owner() && mNewParent->owner()->folderType() == KMFolderTypeCachedImap ) {
    mNewFolder = kmkernel->dimapFolderMgr()->createFolder( mStorage->folder()->name(), false, typenew, mNewParent );
    if ( mNewFolder ) {
      KMFolderCachedImap* selectedStorage = static_cast<KMFolderCachedImap*>( mNewParent->owner()->storage() );
      KMFolderCachedImap* newStorage = static_cast<KMFolderCachedImap*>( mNewFolder->storage() );
      newStorage->initializeFrom( selectedStorage );
      success = true;
    }
  } else {
    // local folder
    mNewFolder = kmkernel->folderMgr()->createFolder(mStorage->folder()->name(), false, typenew, mNewParent );
    if ( mNewFolder )
      success = true;
  }

  if ( !success ) {
      kWarning(5006) << k_funcinfo << "could not create folder" << endl;
      emit folderCopyComplete( false );
      deleteLater();
      return false;
  }

  mNewFolder->setMoveInProgress( true );

  // inherit the folder type
  // FIXME we should probably copy over most if not all settings
  mNewFolder->storage()->setContentsType( mStorage->contentsType(), true /*quiet*/ );
  mNewFolder->storage()->writeConfig();
  kDebug(5006)<< "CopyJob::createTargetDir - " << mStorage->folder()->idString()
    << " |=> " << mNewFolder->idString() << endl;
  return !waitForFolderCreation;
}

void CopyFolderJob::rollback()
{
  // copy failed - rollback the last transaction
//   kmkernel->undoStack()->undo();
  // .. and delete the new folder
  if ( mNewFolder ) {
    if ( mNewFolder->folderType() == KMFolderTypeImap )
    {
      kmkernel->imapFolderMgr()->remove( mNewFolder );
    } else if ( mNewFolder->folderType() == KMFolderTypeCachedImap )
    {
      // tell the account (see KMFolderCachedImap::listDirectory2)
      KMFolderCachedImap* folder = static_cast<KMFolderCachedImap*>(mNewFolder->storage());
      KMAcctCachedImap* acct = folder->account();
      if ( acct )
        acct->addDeletedFolder( folder->imapPath() );
      kmkernel->dimapFolderMgr()->remove( mNewFolder );
    } else if ( mNewFolder->folderType() == KMFolderTypeSearch )
    {
      // invalid
      kWarning(5006) << k_funcinfo << "cannot remove a search folder" << endl;
    } else {
      kmkernel->folderMgr()->remove( mNewFolder );
    }
  }

  emit folderCopyComplete( false );
  deleteLater();
}

void CopyFolderJob::folderCreationDone(const QString & name, bool success)
{
  if ( mStorage->folder()->name() != name )
    return; // not our business
  kDebug(5006) << k_funcinfo << success << endl;

  if ( !success ) {
    rollback();
  } else {
    copyMessagesToTargetDir();
  }
}
#include "copyfolderjob.moc"
<|endoftext|>


<commit_before><commit_msg>Fix a big mistake<commit_after><|endoftext|>


<commit_before><commit_msg>Improve warning message when extra attributes cannot be created<commit_after><|endoftext|>


<commit_before>#include "Utility/Random.h"

#include <random>
#include <string>
#include <limits>

namespace
{
    struct Seeder
    {
        using result_type = unsigned int;
        template<typename Iterator>
        void generate(Iterator begin, Iterator end)
        {
            std::random_device rd;
            std::generate(begin, end, [&rd]() { return rd(); });
        }
    };
}

Random::Random_Bits_Generator Random::get_new_seeded_random_bit_source() noexcept
{
    return Random_Bits_Generator{Seeder{}};
}

double Random::random_laplace(double width) noexcept
{
    thread_local static auto generator = get_new_seeded_random_bit_source();
    using ed = std::exponential_distribution<double>;
    thread_local static auto dist = ed{};
    return (coin_flip() ? 1 : -1)*dist(generator, ed::param_type{1.0/width});
}

uint64_t Random::random_unsigned_int64() noexcept
{
    return random_integer(std::numeric_limits<uint64_t>::min(),
                          std::numeric_limits<uint64_t>::max());
}

bool Random::coin_flip() noexcept
{
    return success_probability(1, 2);
}

bool Random::success_probability(size_t successes, size_t attempts) noexcept
{
    assert(attempts > 0);
    return random_integer(size_t{1}, attempts) <= successes;
}

std::string Random::random_string(size_t size) noexcept
{
    std::string s;
    while(s.size() < size)
    {
        s.push_back('a' + random_integer(0, 25));
    }
    return s;
}
<commit_msg>Fix incorrect seeding (according to gcc and clang)<commit_after>#include "Utility/Random.h"

#include <random>
#include <string>
#include <limits>

namespace
{
    struct Seeder
    {
        using result_type = unsigned int;
        template<typename Iterator>
        void generate(Iterator begin, Iterator end)
        {
            std::random_device rd;
            std::generate(begin, end, [&rd]() { return rd(); });
        }
    };
}

Random::Random_Bits_Generator Random::get_new_seeded_random_bit_source() noexcept
{
    auto seeder = Seeder{};
    return Random_Bits_Generator(seeder);
}

double Random::random_laplace(double width) noexcept
{
    thread_local static auto generator = get_new_seeded_random_bit_source();
    using ed = std::exponential_distribution<double>;
    thread_local static auto dist = ed{};
    return (coin_flip() ? 1 : -1)*dist(generator, ed::param_type{1.0/width});
}

uint64_t Random::random_unsigned_int64() noexcept
{
    return random_integer(std::numeric_limits<uint64_t>::min(),
                          std::numeric_limits<uint64_t>::max());
}

bool Random::coin_flip() noexcept
{
    return success_probability(1, 2);
}

bool Random::success_probability(size_t successes, size_t attempts) noexcept
{
    assert(attempts > 0);
    return random_integer(size_t{1}, attempts) <= successes;
}

std::string Random::random_string(size_t size) noexcept
{
    std::string s;
    while(s.size() < size)
    {
        s.push_back('a' + random_integer(0, 25));
    }
    return s;
}
<|endoftext|>


<commit_before>#include "Utility/Random.h"

#include <random>
#include <string>

double Random::random_laplace(double width) noexcept
{
    thread_local static std::mt19937_64 generator(std::random_device{}());
    using ed = std::exponential_distribution<double>;
    thread_local static auto dist = ed{};
    return (coin_flip() ? 1 : -1)*dist(generator, ed::param_type{1.0/width});
}

uint64_t Random::random_unsigned_int64() noexcept
{
    thread_local static std::mt19937_64 generator(std::random_device{}());
    thread_local static std::uniform_int_distribution<uint64_t> dist;
    return dist(generator);
}

bool Random::coin_flip() noexcept
{
    return success_probability(1, 2);
}

bool Random::success_probability(size_t successes, size_t attempts) noexcept
{
    assert(attempts > 0);
    return random_integer(size_t{1}, attempts) <= successes;
}

std::string Random::random_string(size_t size) noexcept
{
    std::string s;
    while(s.size() < size)
    {
        s.push_back('a' + random_integer(0, 25));
    }
    return s;
}
<commit_msg>Reuse random_integer() for random_unsigned_int64()<commit_after>#include "Utility/Random.h"

#include <random>
#include <string>
#include <limits>

double Random::random_laplace(double width) noexcept
{
    thread_local static std::mt19937_64 generator(std::random_device{}());
    using ed = std::exponential_distribution<double>;
    thread_local static auto dist = ed{};
    return (coin_flip() ? 1 : -1)*dist(generator, ed::param_type{1.0/width});
}

uint64_t Random::random_unsigned_int64() noexcept
{
    return random_integer(std::numeric_limits<uint64_t>::min(),
                          std::numeric_limits<uint64_t>::max());
}

bool Random::coin_flip() noexcept
{
    return success_probability(1, 2);
}

bool Random::success_probability(size_t successes, size_t attempts) noexcept
{
    assert(attempts > 0);
    return random_integer(size_t{1}, attempts) <= successes;
}

std::string Random::random_string(size_t size) noexcept
{
    std::string s;
    while(s.size() < size)
    {
        s.push_back('a' + random_integer(0, 25));
    }
    return s;
}
<|endoftext|>


<commit_before>#include "Utility/String.h"

#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <cctype>
#include <chrono>
#include <iomanip>
#include <sstream>

namespace String
{
    namespace
    {
        const auto whitespace = " \t\n";
    }
}

std::vector<std::string> String::split(std::string s, std::string delim, size_t count)
{
    if(delim.empty())
    {
        s = remove_extra_whitespace(s);
        delim = " ";
    }

    if(s.empty())
    {
        return {};
    }

    std::vector<std::string> result;
    size_t start_index = 0;
    size_t end_index = 0;
    size_t split_count = 0;
    while(end_index < s.size() && split_count < count)
    {
        end_index = s.find(delim, start_index);
        result.push_back(s.substr(start_index, end_index - start_index));
        start_index = std::min(end_index, s.size()) + delim.size();
        ++split_count;
    }

    if(start_index <= s.size())
    {
        result.push_back(s.substr(start_index));
    }

    return result;
}

bool String::starts_with(const std::string& s, const std::string& beginning)
{
    return (beginning.size() <= s.size()) && std::equal(beginning.begin(), beginning.end(), s.begin());
}

bool String::ends_with(const std::string& s, const std::string& ending)
{
    return (ending.size() <= s.size()) && std::equal(ending.rbegin(), ending.rend(), s.rbegin());
}

std::string String::trim_outer_whitespace(const std::string& s)
{
    auto text_start = s.find_first_not_of(whitespace);
    if(text_start == std::string::npos)
    {
        return {};
    }

    auto text_end = s.find_last_not_of(whitespace);
    return s.substr(text_start, text_end - text_start + 1);
}

std::string String::remove_extra_whitespace(const std::string& s)
{
    std::string s2 = trim_outer_whitespace(s);
    std::replace_if(s2.begin(), s2.end(), [](auto c) { return String::contains(whitespace, c); }, ' ');
    std::string result;
    std::copy_if(s2.begin(), s2.end(), std::back_inserter(result),
                 [&result](auto c)
                 {
                     return  c != ' ' || result.back() != ' ';

                 });

    return result;
}

std::string String::strip_comments(const std::string& str, const std::string& comment)
{
    return trim_outer_whitespace(str.substr(0, str.find(comment)));
}

std::string String::strip_block_comment(const std::string& str, const std::string& start, const std::string& end)
{
    auto start_comment_index = str.find(start);
    auto end_comment_index = str.find(end);

    if(start_comment_index == std::string::npos && end_comment_index == std::string::npos)
    {
        return trim_outer_whitespace(str);
    }

    if(start_comment_index == std::string::npos || end_comment_index == std::string::npos)
    {
        throw std::invalid_argument("\"" + str + "\" is missing a comment delimiter: " + std::string{start} + std::string{end});
    }

    if(start_comment_index >= end_comment_index)
    {
        throw std::invalid_argument("\"" + str + "\" contains bad comment delimiters: " + std::string{start} + std::string{end});
    }

    auto first_part = str.substr(0, start_comment_index);
    auto last_part = str.substr(end_comment_index + end.size());
    try
    {
        return strip_block_comment(trim_outer_whitespace(first_part) + " " + trim_outer_whitespace(last_part), start, end);
    }
    catch(const std::invalid_argument& e)
    {
        throw std::invalid_argument(e.what() + std::string("\nOriginal line: ") + str);
    }
}

std::string String::lowercase(std::string s)
{
    for(auto& c : s){ c = std::tolower(c); }
    return s;
}

std::string String::format_integer(int n, const std::string& separator)
{
    if(n < 0)
    {
        return '-' + format_integer(-n, separator);
    }
    else
    {
        auto s = std::to_string(n);
        auto group_size = 3;
        auto index = s.size() % group_size;
        index = (index == 0 ? group_size : index);
        auto result = s.substr(0, index);

        for( ; index < s.size(); index += group_size)
        {
            result += separator;
            result += s.substr(index, group_size);
        }

        return result;
    }
}

size_t String::string_to_size_t(const std::string& s)
{
    size_t characters_used;

    auto result =
    #ifdef __linux__
        std::stoul(s, &characters_used);
    #elif defined(_WIN64)
        std::stoull(s, &characters_used);
    #else
        std::stoi(s, &characters_used);
    #endif

    if( ! String::trim_outer_whitespace(s.substr(characters_used)).empty())
    {
        throw std::invalid_argument("Non-numeric characters in string: " + s);
    }

    return result;
}

std::string String::date_and_time_format(const std::chrono::system_clock::time_point& point_in_time,
                                         const std::string& format)
{
    auto time_c = std::chrono::system_clock::to_time_t(point_in_time);
    std::tm time_out;
#ifdef _WIN32
    localtime_s(&time_out, &time_c);
#elif defined(__linux__)
    localtime_r(&time_c, &time_out);
#endif
    auto ss = std::ostringstream{};
    ss << std::put_time(&time_out, format.c_str());
    return ss.str();
}
<commit_msg>Delete unneeded type conversion<commit_after>#include "Utility/String.h"

#include <string>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <cctype>
#include <chrono>
#include <iomanip>
#include <sstream>

namespace String
{
    namespace
    {
        const auto whitespace = " \t\n";
    }
}

std::vector<std::string> String::split(std::string s, std::string delim, size_t count)
{
    if(delim.empty())
    {
        s = remove_extra_whitespace(s);
        delim = " ";
    }

    if(s.empty())
    {
        return {};
    }

    std::vector<std::string> result;
    size_t start_index = 0;
    size_t end_index = 0;
    size_t split_count = 0;
    while(end_index < s.size() && split_count < count)
    {
        end_index = s.find(delim, start_index);
        result.push_back(s.substr(start_index, end_index - start_index));
        start_index = std::min(end_index, s.size()) + delim.size();
        ++split_count;
    }

    if(start_index <= s.size())
    {
        result.push_back(s.substr(start_index));
    }

    return result;
}

bool String::starts_with(const std::string& s, const std::string& beginning)
{
    return (beginning.size() <= s.size()) && std::equal(beginning.begin(), beginning.end(), s.begin());
}

bool String::ends_with(const std::string& s, const std::string& ending)
{
    return (ending.size() <= s.size()) && std::equal(ending.rbegin(), ending.rend(), s.rbegin());
}

std::string String::trim_outer_whitespace(const std::string& s)
{
    auto text_start = s.find_first_not_of(whitespace);
    if(text_start == std::string::npos)
    {
        return {};
    }

    auto text_end = s.find_last_not_of(whitespace);
    return s.substr(text_start, text_end - text_start + 1);
}

std::string String::remove_extra_whitespace(const std::string& s)
{
    std::string s2 = trim_outer_whitespace(s);
    std::replace_if(s2.begin(), s2.end(), [](auto c) { return String::contains(whitespace, c); }, ' ');
    std::string result;
    std::copy_if(s2.begin(), s2.end(), std::back_inserter(result),
                 [&result](auto c)
                 {
                     return  c != ' ' || result.back() != ' ';

                 });

    return result;
}

std::string String::strip_comments(const std::string& str, const std::string& comment)
{
    return trim_outer_whitespace(str.substr(0, str.find(comment)));
}

std::string String::strip_block_comment(const std::string& str, const std::string& start, const std::string& end)
{
    auto start_comment_index = str.find(start);
    auto end_comment_index = str.find(end);

    if(start_comment_index == std::string::npos && end_comment_index == std::string::npos)
    {
        return trim_outer_whitespace(str);
    }

    if(start_comment_index == std::string::npos || end_comment_index == std::string::npos)
    {
        throw std::invalid_argument("\"" + str + "\" is missing a comment delimiter: " + start + end);
    }

    if(start_comment_index >= end_comment_index)
    {
        throw std::invalid_argument("\"" + str + "\" contains bad comment delimiters: " + start + end);
    }

    auto first_part = str.substr(0, start_comment_index);
    auto last_part = str.substr(end_comment_index + end.size());
    try
    {
        return strip_block_comment(trim_outer_whitespace(first_part) + " " + trim_outer_whitespace(last_part), start, end);
    }
    catch(const std::invalid_argument& e)
    {
        throw std::invalid_argument(e.what() + std::string("\nOriginal line: ") + str);
    }
}

std::string String::lowercase(std::string s)
{
    for(auto& c : s){ c = std::tolower(c); }
    return s;
}

std::string String::format_integer(int n, const std::string& separator)
{
    if(n < 0)
    {
        return '-' + format_integer(-n, separator);
    }
    else
    {
        auto s = std::to_string(n);
        auto group_size = 3;
        auto index = s.size() % group_size;
        index = (index == 0 ? group_size : index);
        auto result = s.substr(0, index);

        for( ; index < s.size(); index += group_size)
        {
            result += separator;
            result += s.substr(index, group_size);
        }

        return result;
    }
}

size_t String::string_to_size_t(const std::string& s)
{
    size_t characters_used;

    auto result =
    #ifdef __linux__
        std::stoul(s, &characters_used);
    #elif defined(_WIN64)
        std::stoull(s, &characters_used);
    #else
        std::stoi(s, &characters_used);
    #endif

    if( ! String::trim_outer_whitespace(s.substr(characters_used)).empty())
    {
        throw std::invalid_argument("Non-numeric characters in string: " + s);
    }

    return result;
}

std::string String::date_and_time_format(const std::chrono::system_clock::time_point& point_in_time,
                                         const std::string& format)
{
    auto time_c = std::chrono::system_clock::to_time_t(point_in_time);
    std::tm time_out;
#ifdef _WIN32
    localtime_s(&time_out, &time_c);
#elif defined(__linux__)
    localtime_r(&time_c, &time_out);
#endif
    auto ss = std::ostringstream{};
    ss << std::put_time(&time_out, format.c_str());
    return ss.str();
}
<|endoftext|>