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

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>

#include <set>

constexpr int TS_PACKET_SIZE = 188;
constexpr int PID_PAT = 0;

int g_pmtPid = -1;

std::set<int> dropPidSet;

void printDebug(const char *format, ...) {
/*
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
*/
}

void printError(const char *format, ...) {
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
}

class PSI {
public:
  PSI();
  const u_int8_t *header() { return &data[headerPos]; }
  const u_int8_t *syntaxSection() { return &data[syntaxSectionPos]; }
  const u_int8_t *tableData() { return &data[tableDataPos]; }
  int tableDataSize() { return tailPos - tableDataPos - 4; }

  bool feed(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize);

private:
  u_int8_t data[1024];
  int nextCounter;
  int dataSize;
  int headerPos;
  int syntaxSectionPos;
  int tableDataPos;
  int tailPos;
};

PSI::PSI()
 : data(),
   nextCounter(-1),
   dataSize(0),
   headerPos(0),
   syntaxSectionPos(0),
   tableDataPos(0),
   tailPos(0)
{}

bool PSI::feed(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize) {
  if (!startInd) {
    if (contCounter != nextCounter) {
      nextCounter = -1;
      return false;
    }
    nextCounter = (nextCounter + 1) % 16;
  } else {
    dataSize = 0;
    nextCounter = (contCounter + 1) % 16;
  }

  printDebug("feed\n");

  memcpy(&data[dataSize], payload, payloadSize);
  dataSize += payloadSize;

  if (startInd) {
    headerPos = data[0] + 1;
    syntaxSectionPos = headerPos + 3;
    tableDataPos = syntaxSectionPos + 5;
    const u_int8_t *hdr = header();
    int sectionLen = ((hdr[1] & 0xf) << 8) | hdr[2];
    tailPos = syntaxSectionPos + sectionLen;
  }

  return (tailPos <= dataSize);
}

void feedPAT(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize) {
  static PSI psi;
  bool completed = psi.feed(startInd, contCounter, payload, payloadSize);
  if (!completed)
    return;

  const u_int8_t *p = psi.tableData();
  const u_int8_t *tail = p + psi.tableDataSize();
  while (p < tail) {
    int programNumber = (p[0] << 8) | p[1];
    int pid = ((p[2] & 0x1f) << 8) | p[3];
    printDebug("PAT: prog:%d  pid:%d\n", programNumber, pid);
    if (programNumber != 0) {
      g_pmtPid = pid;
      break;
    }
    p += 4;
  }
}

void feedPMT(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize) {
  static PSI psi;
  bool completed = psi.feed(startInd, contCounter, payload, payloadSize);
  if (!completed)
    return;

  const u_int8_t *p = psi.tableData();
  const u_int8_t *tail = p + psi.tableDataSize();

  int programInfoLen = ((p[2] & 0xf) << 8) | p[3];
  p += programInfoLen + 4;

  bool hasVideo = false;
  bool hasAudio = false;

  dropPidSet.clear();

  while (p < tail) {
    int streamType = p[0];
    int pid = ((p[1] & 0x1f) << 8) | p[2];
    printDebug("PMT: streamType:%d  pid:%d\n", streamType, pid);
    int infoLen = ((p[3] & 0xf) << 8) | p[4];
    p += infoLen + 5;

    switch (streamType) {
      case 2: // ISO/IEC 13818-2
        if (hasVideo) {
          dropPidSet.insert(pid);
        } else {
          hasVideo = true;
        }
        break;

      case 0xf: // ISO/IEC 13818-7
        if (hasAudio) {
          dropPidSet.insert(pid);
        } else {
          hasAudio = true;
        }
        break;

      default:
        dropPidSet.insert(pid);
        break;
    }
  }
}

bool checkPacket(const u_int8_t *packet, int packetSize) {
  bool startInd = ((packet[1] & 0x40) != 0);
  int pid = ((packet[1] & 0x1f) << 8) | packet[2];
  bool hasAdaptationField = ((packet[3] & 0x20) != 0);
  bool hasPayload = ((packet[3] & 0x10) != 0);
  int contCounter = packet[3] & 0xf;

  printDebug("SI:%d PID:%d hasAF:%d hasPL:%d ct:%d\n",
    startInd, pid, hasAdaptationField, hasPayload, contCounter);

  if (!hasPayload)
    return false;

  int payloadPos = 4;
  if (hasAdaptationField)
    payloadPos += packet[4] + 1;

  if (pid == PID_PAT) {
    feedPAT(startInd, contCounter, &packet[payloadPos], packetSize - payloadPos);
  } else if (pid == g_pmtPid) {
    feedPMT(startInd, contCounter, &packet[payloadPos], packetSize - payloadPos);
  } else if (dropPidSet.find(pid) != dropPidSet.end()) {
    return true;
  }

  return false;
}

void filterTS(FILE *fin, FILE *fout) {
  constexpr u_int8_t SYNC_BYTE = 0x47;

  u_int8_t packet[TS_PACKET_SIZE];

  for(;;) {
    for(;;) {
      int c = fgetc(fin);
      if (c == EOF)
        return;
      if (c == SYNC_BYTE)
        break;
    }

    fseek(fin, ftell(fin) - 1, SEEK_SET);

    for(;;) {
      long readPos = ftell(fin);
      size_t len = fread(packet, 1, TS_PACKET_SIZE, fin);
      if (len != TS_PACKET_SIZE)
        return;

      if (packet[0] != SYNC_BYTE) {
        printError("missing sync-byte\n");
        fseek(fin, readPos, SEEK_SET);
        break;
      }

      bool drop = checkPacket(packet, TS_PACKET_SIZE);
      if (!drop) {
        fwrite(packet, TS_PACKET_SIZE, 1, fout);
      }
    }
  }
}

int main(int argc, char **argv) {

  const char *inPath = NULL;
  const char *outPath = NULL;

  for (int i = 1; i < argc; ++i) {
    if (!inPath) {
      inPath = argv[i];
      continue;
    }
    if (!outPath) {
      outPath = argv[i];
      continue;
    }
  }

  int result = 0;
  FILE *fin = NULL;
  FILE *fout = NULL;

  fin = inPath ? fopen(inPath, "rb") : stdin;
  if (!fin) {
    printError("cannot open : %s\n", inPath);
    result = 1;
    goto FINISH;
  }

  fout = outPath ? fopen(outPath, "wb") : stdout;
  if (!fout) {
    printError("cannot open : %s\n", outPath);
    result = 1;
    goto FINISH;
  }

  filterTS(fin, fout);

  fflush(fout);

FINISH:
  if (fin && fin != stdin)
    fclose(fin);

  if (fout && fout != stdout)
    fclose(fout);

  return result;
}

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

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>

#include <set>

constexpr int TS_PACKET_SIZE = 188;
constexpr int PID_PAT = 0;

int g_pmtPid = -1;

std::set<int> g_dropPidSet;

void printDebug(const char *format, ...) {
/*
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
*/
}

void printError(const char *format, ...) {
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
}

class PSI {
public:
  PSI();
  const u_int8_t *header() { return &data[headerPos]; }
  const u_int8_t *syntaxSection() { return &data[syntaxSectionPos]; }
  const u_int8_t *tableData() { return &data[tableDataPos]; }
  int tableDataSize() { return tailPos - tableDataPos - 4; }

  bool feed(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize);

private:
  u_int8_t data[1024];
  int nextCounter;
  int dataSize;
  int headerPos;
  int syntaxSectionPos;
  int tableDataPos;
  int tailPos;
};

PSI::PSI()
 : data(),
   nextCounter(-1),
   dataSize(0),
   headerPos(0),
   syntaxSectionPos(0),
   tableDataPos(0),
   tailPos(0)
{}

bool PSI::feed(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize) {
  if (!startInd) {
    if (contCounter != nextCounter) {
      nextCounter = -1;
      return false;
    }
    nextCounter = (nextCounter + 1) % 16;
  } else {
    dataSize = 0;
    nextCounter = (contCounter + 1) % 16;
  }

  printDebug("feed\n");

  memcpy(&data[dataSize], payload, payloadSize);
  dataSize += payloadSize;

  if (startInd) {
    headerPos = data[0] + 1;
    syntaxSectionPos = headerPos + 3;
    tableDataPos = syntaxSectionPos + 5;
    const u_int8_t *hdr = header();
    int sectionLen = ((hdr[1] & 0xf) << 8) | hdr[2];
    tailPos = syntaxSectionPos + sectionLen;
  }

  return (tailPos <= dataSize);
}

void feedPAT(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize) {
  static PSI psi;
  bool completed = psi.feed(startInd, contCounter, payload, payloadSize);
  if (!completed)
    return;

  const u_int8_t *p = psi.tableData();
  const u_int8_t *tail = p + psi.tableDataSize();
  while (p < tail) {
    int programNumber = (p[0] << 8) | p[1];
    int pid = ((p[2] & 0x1f) << 8) | p[3];
    printDebug("PAT: prog:%d  pid:%d\n", programNumber, pid);
    if (programNumber != 0) {
      g_pmtPid = pid;
      break;
    }
    p += 4;
  }
}

void feedPMT(bool startInd, int contCounter, const u_int8_t *payload, int payloadSize) {
  static PSI psi;
  bool completed = psi.feed(startInd, contCounter, payload, payloadSize);
  if (!completed)
    return;

  const u_int8_t *p = psi.tableData();
  const u_int8_t *tail = p + psi.tableDataSize();

  int programInfoLen = ((p[2] & 0xf) << 8) | p[3];
  p += programInfoLen + 4;

  bool hasVideo = false;
  bool hasAudio = false;

  g_dropPidSet.clear();

  while (p < tail) {
    int streamType = p[0];
    int pid = ((p[1] & 0x1f) << 8) | p[2];
    printDebug("PMT: streamType:%d  pid:%d\n", streamType, pid);
    int infoLen = ((p[3] & 0xf) << 8) | p[4];
    p += infoLen + 5;

    switch (streamType) {
      case 2: // ISO/IEC 13818-2
        if (hasVideo) {
          g_dropPidSet.insert(pid);
        } else {
          hasVideo = true;
        }
        break;

      case 0xf: // ISO/IEC 13818-7
        if (hasAudio) {
          g_dropPidSet.insert(pid);
        } else {
          hasAudio = true;
        }
        break;

      default:
        g_dropPidSet.insert(pid);
        break;
    }
  }
}

bool checkPacket(const u_int8_t *packet, int packetSize) {
  bool startInd = ((packet[1] & 0x40) != 0);
  int pid = ((packet[1] & 0x1f) << 8) | packet[2];
  bool hasAdaptationField = ((packet[3] & 0x20) != 0);
  bool hasPayload = ((packet[3] & 0x10) != 0);
  int contCounter = packet[3] & 0xf;

  printDebug("SI:%d PID:%d hasAF:%d hasPL:%d ct:%d\n",
    startInd, pid, hasAdaptationField, hasPayload, contCounter);

  if (!hasPayload)
    return false;

  int payloadPos = 4;
  if (hasAdaptationField)
    payloadPos += packet[4] + 1;

  if (pid == PID_PAT) {
    feedPAT(startInd, contCounter, &packet[payloadPos], packetSize - payloadPos);
  } else if (pid == g_pmtPid) {
    feedPMT(startInd, contCounter, &packet[payloadPos], packetSize - payloadPos);
  } else if (g_dropPidSet.find(pid) != g_dropPidSet.end()) {
    return true;
  }

  return false;
}

void filterTS(FILE *fin, FILE *fout) {
  constexpr u_int8_t SYNC_BYTE = 0x47;

  u_int8_t packet[TS_PACKET_SIZE];

  for(;;) {
    for(;;) {
      int c = fgetc(fin);
      if (c == EOF)
        return;
      if (c == SYNC_BYTE)
        break;
    }

    fseek(fin, ftell(fin) - 1, SEEK_SET);

    for(;;) {
      long readPos = ftell(fin);
      size_t len = fread(packet, 1, TS_PACKET_SIZE, fin);
      if (len != TS_PACKET_SIZE)
        return;

      if (packet[0] != SYNC_BYTE) {
        printError("missing sync-byte\n");
        fseek(fin, readPos, SEEK_SET);
        break;
      }

      bool drop = checkPacket(packet, TS_PACKET_SIZE);
      if (!drop) {
        fwrite(packet, TS_PACKET_SIZE, 1, fout);
      }
    }
  }
}

int main(int argc, char **argv) {

  const char *inPath = NULL;
  const char *outPath = NULL;

  for (int i = 1; i < argc; ++i) {
    if (!inPath) {
      inPath = argv[i];
      continue;
    }
    if (!outPath) {
      outPath = argv[i];
      continue;
    }
  }

  int result = 0;
  FILE *fin = NULL;
  FILE *fout = NULL;

  fin = inPath ? fopen(inPath, "rb") : stdin;
  if (!fin) {
    printError("cannot open : %s\n", inPath);
    result = 1;
    goto FINISH;
  }

  fout = outPath ? fopen(outPath, "wb") : stdout;
  if (!fout) {
    printError("cannot open : %s\n", outPath);
    result = 1;
    goto FINISH;
  }

  filterTS(fin, fout);

  fflush(fout);

FINISH:
  if (fin && fin != stdin)
    fclose(fin);

  if (fout && fout != stdout)
    fclose(fout);

  return result;
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(URISUPPORT_HEADER_GUARD_1357924680)
#define URISUPPORT_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <PlatformSupport/PlatformSupportDefinitions.hpp>

#include <xercesc/util/XMLURL.hpp>

#include <XalanDOM/XalanDOMString.hpp>

#include <Include/XalanAutoPtr.hpp>

#include <PlatformSupport/XSLException.hpp>

XALAN_CPP_NAMESPACE_BEGIN

class XALAN_PLATFORMSUPPORT_EXPORT URISupport
{
public:

	typedef XERCES_CPP_NAMESPACE_QUALIFIER XMLURL	XMLURLType;

	typedef XalanAutoPtr<XMLURLType>	URLAutoPtrType;

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(const XalanDOMString&	urlString)
	{
		return getURLFromString(urlString.c_str());
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param url to update with the qualified string.
	 */
	static void
	getURLFromString(
			const XalanDOMString&	urlString,
			XMLURLType&				url)
	{
		getURLFromString(urlString.c_str(), url);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(const XalanDOMChar*	urlString);

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param url to update with the qualified string.
	 */
	static void
	getURLFromString(
			const XalanDOMChar*		urlString,
			XMLURLType&				url)
	{
		url.setURL(getURLStringFromString(urlString).c_str());
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base)
	{
		return getURLFromString(getURLStringFromString(urlString, base));
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(
			const XalanDOMChar*		urlString,
			const XalanDOMChar*		base);

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(const XalanDOMString&	urlString)
	{
		XalanDOMString	result;

		getURLStringFromString(urlString.c_str(), urlString.length(), result);

		return result;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return string to fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMString&	urlString,
			XalanDOMString&			theNormalizedURI)
	{
		getURLStringFromString(urlString.c_str(), urlString.length(), theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(const XalanDOMChar*	urlString)
	{
		XalanDOMString	theNormalizedURI;

		getURLStringFromString(urlString, theNormalizedURI);

		return theNormalizedURI;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*			urlString,
			XalanDOMString&				theNormalizedURI)
	{
		assert(urlString != 0);

		getURLStringFromString(
			urlString,
			XalanDOMString::length(urlString),
			theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param len the length of urlString
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*			urlString,
			XalanDOMString::size_type	len,
			XalanDOMString&				theNormalizedURI);

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base)
	{
		XalanDOMString	theNormalizedURI;

		getURLStringFromString(
			urlString.c_str(),
			urlString.length(),
			base.c_str(),
			base.length(),
			theNormalizedURI);

		return theNormalizedURI;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base,
			XalanDOMString&			theNormalizedURI)
	{
		getURLStringFromString(urlString.c_str(), base.c_str(), theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(
			const XalanDOMChar*		urlString,
			const XalanDOMChar*		base)
	{
		XalanDOMString	theNormalizedURI;

		getURLStringFromString(urlString, base, theNormalizedURI);

		return theNormalizedURI;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*		urlString,
			const XalanDOMChar*		base,
			XalanDOMString&			theNormalizedURI)
	{
		assert(urlString != 0 && base != 0);

		getURLStringFromString(
			urlString,
			XalanDOMString::length(urlString),
			base,
			XalanDOMString::length(base),
			theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*			urlString,
			XalanDOMString::size_type	urlStringLen,
			const XalanDOMChar*			base,
			XalanDOMString::size_type	baseLen,
			XalanDOMString&				theNormalizedURI);

	/**
	 * Normalizes the string passed in, replacing
	 * \ with /.
	 *
	 * @param urlString string to normalize
	 * @return a reference to the passed parameter
	 */
	static XalanDOMString&
	NormalizeURIText(XalanDOMString&	uriString);

	/**
	 * Normalizes the string passed in, replacing
	 * \ with /.
	 *
	 * @param urlString string to normalize
	 * @return a copy of the normalized URI
	 */
	static const XalanDOMString
	NormalizeURIText(const XalanDOMString&	uriString);

	class InvalidURIException : public XSLException
	{
	public:

		/**
		 * Construct an InvalidURIException.
		 *
		 * @param theMessage the error message
		 */
		InvalidURIException(const XalanDOMString&	theMessage);

		virtual
		~InvalidURIException();
	};

	static const XalanDOMChar	s_fileProtocolString1[];

	static const XalanDOMChar	s_fileProtocolString2[];
};

XALAN_CPP_NAMESPACE_END

#endif	// URISUPPORT_HEADER_GUARD_1357924680
<commit_msg>Moved typedef out of class scope.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(URISUPPORT_HEADER_GUARD_1357924680)
#define URISUPPORT_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <PlatformSupport/PlatformSupportDefinitions.hpp>

#include <xercesc/util/XMLURL.hpp>

#include <XalanDOM/XalanDOMString.hpp>

#include <Include/XalanAutoPtr.hpp>

#include <PlatformSupport/XSLException.hpp>

XALAN_CPP_NAMESPACE_BEGIN

typedef XERCES_CPP_NAMESPACE_QUALIFIER XMLURL	XMLURLType;

class XALAN_PLATFORMSUPPORT_EXPORT URISupport
{
public:

	typedef XalanAutoPtr<XMLURLType>	URLAutoPtrType;

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(const XalanDOMString&	urlString)
	{
		return getURLFromString(urlString.c_str());
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param url to update with the qualified string.
	 */
	static void
	getURLFromString(
			const XalanDOMString&	urlString,
			XMLURLType&				url)
	{
		getURLFromString(urlString.c_str(), url);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(const XalanDOMChar*	urlString);

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param url to update with the qualified string.
	 */
	static void
	getURLFromString(
			const XalanDOMChar*		urlString,
			XMLURLType&				url)
	{
		url.setURL(getURLStringFromString(urlString).c_str());
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base)
	{
		return getURLFromString(getURLStringFromString(urlString, base));
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return auto pointer to fully qualified URI
	 */
	static URLAutoPtrType
	getURLFromString(
			const XalanDOMChar*		urlString,
			const XalanDOMChar*		base);

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(const XalanDOMString&	urlString)
	{
		XalanDOMString	result;

		getURLStringFromString(urlString.c_str(), urlString.length(), result);

		return result;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return string to fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMString&	urlString,
			XalanDOMString&			theNormalizedURI)
	{
		getURLStringFromString(urlString.c_str(), urlString.length(), theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(const XalanDOMChar*	urlString)
	{
		XalanDOMString	theNormalizedURI;

		getURLStringFromString(urlString, theNormalizedURI);

		return theNormalizedURI;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*			urlString,
			XalanDOMString&				theNormalizedURI)
	{
		assert(urlString != 0);

		getURLStringFromString(
			urlString,
			XalanDOMString::length(urlString),
			theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param len the length of urlString
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*			urlString,
			XalanDOMString::size_type	len,
			XalanDOMString&				theNormalizedURI);

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base)
	{
		XalanDOMString	theNormalizedURI;

		getURLStringFromString(
			urlString.c_str(),
			urlString.length(),
			base.c_str(),
			base.length(),
			theNormalizedURI);

		return theNormalizedURI;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base,
			XalanDOMString&			theNormalizedURI)
	{
		getURLStringFromString(urlString.c_str(), base.c_str(), theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @return string to fully qualified URI
	 */
	static XalanDOMString
	getURLStringFromString(
			const XalanDOMChar*		urlString,
			const XalanDOMChar*		base)
	{
		XalanDOMString	theNormalizedURI;

		getURLStringFromString(urlString, base, theNormalizedURI);

		return theNormalizedURI;
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*		urlString,
			const XalanDOMChar*		base,
			XalanDOMString&			theNormalizedURI)
	{
		assert(urlString != 0 && base != 0);

		getURLStringFromString(
			urlString,
			XalanDOMString::length(urlString),
			base,
			XalanDOMString::length(base),
			theNormalizedURI);
	}

	/**
	 * Determine the fully qualified URI for a string.
	 *
	 * @param urlString string to qualify
	 * @param base base location for URI
	 * @param theNormalizedURI fully qualified URI
	 */
	static void
	getURLStringFromString(
			const XalanDOMChar*			urlString,
			XalanDOMString::size_type	urlStringLen,
			const XalanDOMChar*			base,
			XalanDOMString::size_type	baseLen,
			XalanDOMString&				theNormalizedURI);

	/**
	 * Normalizes the string passed in, replacing
	 * \ with /.
	 *
	 * @param urlString string to normalize
	 * @return a reference to the passed parameter
	 */
	static XalanDOMString&
	NormalizeURIText(XalanDOMString&	uriString);

	/**
	 * Normalizes the string passed in, replacing
	 * \ with /.
	 *
	 * @param urlString string to normalize
	 * @return a copy of the normalized URI
	 */
	static const XalanDOMString
	NormalizeURIText(const XalanDOMString&	uriString);

	class InvalidURIException : public XSLException
	{
	public:

		/**
		 * Construct an InvalidURIException.
		 *
		 * @param theMessage the error message
		 */
		InvalidURIException(const XalanDOMString&	theMessage);

		virtual
		~InvalidURIException();
	};

	static const XalanDOMChar	s_fileProtocolString1[];

	static const XalanDOMChar	s_fileProtocolString2[];
};

XALAN_CPP_NAMESPACE_END

#endif	// URISUPPORT_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>#include "carcv.hpp"
#include "det.hpp"

using namespace std;
using namespace cv;

namespace fs = boost::filesystem;

int main(int argc, char** argv) {
	CarCV c;

	cout << "arg1: path of list" << endl;
	cout << "arg2: cascadexml path" << endl;

	CascadeClassifier cascade;
	cascade.load(argv[2]);

	fs::path listPath(argv[1]);

	c.run(listPath, CCV_HAAR_SURF, cascade);

	/* maptest
	map<string, double> mapl;

	for (int i = 1; i <= 5; i++) {
		istringstream source(argv[i]);
		string token;
		string key;
	    double value;
		for (int i = 0; getline( source, token, '=' ); i++) {
			if (i == 0) {
				key = token;
			}
		    istringstream ss(token);
		    ss >> value;

		}
		mapl.insert(pair<string, double>(key, value));
	}

	cout << mapl.size() << endl;

	string s = argv[6];
	bool test = (CarCV::atMap(mapl, s) == (*mapl.end()).second);
	cout << "---------------------" << endl;
	cout << "AtIndex: "<< CarCV::atMap(mapl, s) << endl;
	cout << "Works?: " << test << endl;*/

	return 0;
}

/*
 * Main run method
 * method is from enum of same name
 */
void CarCV::run(fs::path &imgListPath, int method, CascadeClassifier &cascade) {
	fs::path posDirPath = "pos"; //load pos dir path
	fs::path negDirPath = "neg"; //load neg dir path

	list<string> strImgList = CarCV::parseList(imgListPath); //parse image list file to list<string>
	list<CarImg> imgList = CarCV::loadCarImgList(strImgList); //load CarImg objects from the list

	CarCV c; //create an instance of CarCV
	list<CarImg> posCarImgList = c.detect_sortPOS_AND_NEG(&imgList, cascade, posDirPath, negDirPath);//detect and sort objects in images of imgList

	fs::path carsDir = "cars";
	if (!fs::exists(carsDir) || !fs::is_directory(carsDir)) { //create cars dir
		fs::create_directory(carsDir);
	}

	list<list<CarImg> > cars = c.sortUnique(posCarImgList, cascade);

	list<CarImg> carlist;
	const int carsListSize = cars.size();
	double speed;

	for (int i = 0; i < carsListSize; i++) {
		carlist = CarCV::atList(cars, i);
		speed = c.calcSpeed(carlist, CCV_SP_FROMALLFILES);
		cout << "Car speed: " << speed << "km/h" << endl;
	}

}

/*
 * //TODO: to be implemented
 * Returns list of positive images list<CarImg>
 *
 */
list<CarImg> CarCV::detect_sortPOS_AND_NEG(list<CarImg> *imgList, CascadeClassifier &cascade, fs::path &posDirPath, fs::path &negDirPath) {
	list<CarImg> sorted = *imgList;

	return sorted; //temp
}

/*
 * Sort images from posImgList into unique car subdirectiories of carsDir
 * Uses <sarcasm> Ondrej Skopek Sort Algorithm (OSSA) </sarcasm>
 */
list<list<CarImg> > CarCV::sortUnique(list<CarImg> &posCarImgList, CascadeClassifier &cascade) { //TODO: test implementation of super algorithm 3000
	/*const*/ double scale = 1;

	map<CarImg, double> probability; //flushed at every iteration over posImgList

	list<list<CarImg> > cars; //sorted list

	list<double> carProbabilty; //result probabilities for every potential unique car

	for (int i = 0; i < CarCV::listSize(posCarImgList); i++) { //iterate over posImgList
		probability.clear();
		carProbabilty.clear();
		const CarImg sortingCar = CarCV::atList(posCarImgList, i);

		if (i == 0 && cars.size() == 0) { //first iteration
			CarCV::atList(cars, 0).push_back(CarCV::atList(posCarImgList, i));
			continue;
		}

		for (int j = 0; j < CarCV::listSize(cars); j++) { //iterate over the main list of cars
			int k;

			const int carsjSize = CarCV::atList(cars, j).size();
			for (k = 0; k < carsjSize; k++) {
				list<CarImg> curList = CarCV::atList(cars, j);
				const CarImg curCar = CarCV::atList(curList, k);

				Mat sortingCarMat = sortingCar.getImg();
				Mat curCarMat = curCar.getImg();

				const double prob = Det::probability(sortingCarMat, curCarMat, cascade, scale); //input from detection algorithm here

				probability.insert(std::pair<CarImg, double>(curCar, prob));
			}
		}

		int carsSize = cars.size();
		for (int l = 0; l < carsSize; l++) {
			double prob;
			int m;
			const int carslSize = CarCV::atList(cars, l).size();
			for (m = 0; m < carslSize; m++) {
				list<CarImg> li = CarCV::atList(cars, l);
				CarImg t = CarCV::atList(li, m);
				prob += CarCV::atMap(probability, t);
			}
			prob /= CarCV::atList(cars, l).size();
			carProbabilty.push_back(prob);
		}

		int carProbId = CarCV::findMaxIndex(carProbabilty);
		CarCV::atList(cars, carProbId).push_back(CarCV::atList(posCarImgList, i));
	}

	return cars;
}

/*
 * Should return the index of the biggest double in mlist
 * If two are equal, returns the index of the first one
 *
 */
int CarCV::findMaxIndex(list<double> &mlist) { //tested, works
	list<double>::iterator mlistI = mlist.begin();
	double probmax;
	int index;

	for (int i = 0; mlistI != mlist.end();i++) {
		if(*mlistI > probmax) {
			probmax = *mlistI;
			index = i;
		}

		mlistI++;
	}
	return index;
}

/*
 * Calculates speed of given unique car from the list of CarImg
 * Give him a row from the main list<list<CarImg> >
 * Returns a positive double
 * if speed_method isn't recognized, returns -1
 *
 * speed_method is from enum of same name
 */
double CarCV::calcSpeed(list<CarImg> clist, int speed_method) { //TODO: not yet implemented
	if (speed_method == 1) { //CCV_SP_FROMSORTEDFILES
		return 1;
	} else if (speed_method == 2) { //CCV_SP_FROMALLFILES
		return 2;
	}
	else {
		int n = speed_method;
		cerr << "ERROR: Unimplemented method: " << n << endl;
		return -1;
	}
	return 0;
}

/*
 * Save CarImg objects to carDir (USE FOR UNIQUE CARS)
 */
void CarCV::saveCarImgList(list<CarImg> carList, fs::path carDir) { //todo: create a saver for CarImgs

}

/**
 * Save list<CarImg> objects to carsDir
 */
void CarCV::saveCars(list<list<CarImg> > cars, fs::path carsDir) { //TODO: create a saver for carsDir

}

/*
 * Load/parse list<CarImg> objects from carsDir
 */
list<list<CarImg> > CarCV::loadCars(fs::path carsDir) { //TODO: create a loader/parser for carsDir
	list<list<CarImg> > carsList;

	return carsList;
}

/*
 * Load/parse CarImg objects from carList
 */
list<CarImg> CarCV::loadCarImgList(list<string> carList) { //TODO: create a loader/parser for CarImg //add a posdir param here
	list<CarImg> carImgList;

	return carImgList;
}

/*
 * Parses the input file plist into a list<string>
 */
list<string> CarCV::parseList(fs::path &plist) { //tested, should work
	list<string> retlist;

	FILE* f = fopen(plist.c_str(), "rt");
	if(f)
	{
		char buf [1000+1];
		for(int i = 0; fgets( buf, 1000, f ); i++)
		{
			int len = (int)strlen(buf);
			while( len > 0 && isspace(buf[len-1]) ) {
				len--;
			}
			buf[len] = '\0';
			retlist.push_back(buf);
		}
	}
	return retlist;
}

/*
 * List item at index
 * If index is out of bounds, returns *tlist.end()
 */
template <class T>
T CarCV::atList(list<T> &tlist, int index) { //

	typename list<T>::iterator tlistI = tlist.begin();

	for (int i = 0; tlistI != tlist.end();i++) {
			if (i == index) {
				return *tlistI;
			}
			tlistI++;
		}
	return *tlist.end();//*--tlistI; was used for returning the last element anyway
}

/*
 * Length of plist
 * Useless: use plist.size()
 */
template <class P>
int CarCV::listSize(list<P> &plist) { //useless, use plist.size()
	typename list<P>::iterator plistI = plist.begin();
	int i;

	for (i = 0; plistI != plist.end();i++) {
			plistI++;
		}
	return i;
}

/*
 * Map item at index
 * If index is not found in map, returns (*tmap.end()).second
 */
template <class K, class V>
V CarCV::atMap(map<K, V> &tmap, K index) { //tested, works

	typename map<K, V>::iterator tmapI = tmap.begin();
	typename map<K, V>::iterator searching = tmap.find(index);

	for (int i = 0; tmapI != tmap.end();i++) {
			if (tmapI == searching) {
				return (*tmapI).second;
			}
			tmapI++;
		}
	return (*tmap.end()).second;
}

/*
 * Size of pmap
 * Useless, use pmap.size()
 */
template <class K, class V>
int CarCV::mapSize(map<K, V> &pmap) { //useless, use pmap.size()
	typename map<K, V>::iterator pmapI = pmap.begin();
	int i;

	for (i = 0; pmapI != pmap.end();i++) {
			pmapI++;
		}
	return i;
}

void grabKVparams(char **argv) { //just for testing reference, erase later
	for (int i = 1; i <= 5; i++) {
		istringstream source(argv[i]);
		string token;
		string key;
		double n;
		for (int i = 0; getline( source, token, '=' ); i++) {
			if (i == 0) {
				key = token;
			}
		    istringstream ss(token);
		    ss >> n;

		}
		cout << key << endl;
		cout << n << endl;
		// do something with n
		cout << "----------" << endl;
	}
}
<commit_msg>added global const scale = 1; updated implementation of methods according to their definitions; implemented detect&sort()<commit_after>#include "carcv.hpp"
#include "det.hpp"

using namespace std;
using namespace cv;

namespace fs = boost::filesystem;

const double scale = 1;

int main(int argc, char** argv) {
	CarCV c;

	cout << "arg1: path of list" << endl;
	cout << "arg2: cascadexml path" << endl;

	CascadeClassifier cascade;
	cascade.load(argv[2]);

	fs::path listPath(argv[1]);

	c.run(listPath, CCV_HAAR_SURF, cascade);

	/* maptest
	map<string, double> mapl;

	for (int i = 1; i <= 5; i++) {
		istringstream source(argv[i]);
		string token;
		string key;
	    double value;
		for (int i = 0; getline( source, token, '=' ); i++) {
			if (i == 0) {
				key = token;
			}
		    istringstream ss(token);
		    ss >> value;

		}
		mapl.insert(pair<string, double>(key, value));
	}

	cout << mapl.size() << endl;

	string s = argv[6];
	bool test = (CarCV::atMap(mapl, s) == (*mapl.end()).second);
	cout << "---------------------" << endl;
	cout << "AtIndex: "<< CarCV::atMap(mapl, s) << endl;
	cout << "Works?: " << test << endl;*/

	return 0;
}

/*
 * Main run method
 * method is from enum of same name
 */
void CarCV::run(fs::path &imgListPath, int method, CascadeClassifier &cascade) {
	fs::path posDirPath = "pos"; //load pos dir path
	fs::path negDirPath = "neg"; //load neg dir path

	list<string> strImgList = CarCV::parseList(imgListPath); //parse image list file to list<string>
	list<CarImg> imgList = CarCV::loadCarImgList(strImgList); //load CarImg objects from the list

	list<CarImg> negList;
	CarCV c; //create an instance of CarCV
	list<CarImg> posCarImgList = c.detect_sortPOS_AND_NEG(imgList, cascade, &negList);//detect and sort objects in images of imgList

	fs::path carsDir = "cars";
	if (!fs::exists(carsDir) || !fs::is_directory(carsDir)) { //create cars dir
		fs::create_directory(carsDir);
	}

	list<list<CarImg> > cars = c.sortUnique(posCarImgList, cascade);

	list<CarImg> carlist;
	const int carsListSize = cars.size();
	double speed;

	for (int i = 0; i < carsListSize; i++) {
		carlist = CarCV::atList(cars, i);
		speed = c.calcSpeed(carlist, CCV_SP_FROMALLFILES);
		cout << "Car speed: " << speed << "km/h" << endl;
	}
}

/*
 * Returns list of positive images list<CarImg>
 * Negative images are stored in *imgList pointer
 */
list<CarImg> CarCV::detect_sortPOS_AND_NEG(list<CarImg> &imgList, CascadeClassifier &cascade, list<CarImg> *negList) { //todo: test this
	list<CarImg> posList;

	const int listSize = imgList.size();

	fs::path cPath = (*imgList.begin()).getPath();
	string cFile = "";
	Mat cMat;
	CarImg cImg(cPath, cFile, cMat);

	for (int i = 0; i < listSize; i++) {
		cImg = CarCV::atList(imgList, i);
		cPath = cImg.getPath();
		cFile = cImg.getFilename();
		cMat = cImg.getImg();

		if (Det::isDetected(cMat, cascade, scale)) {
			posList.push_back(cImg); //maybe .clone()?
		} else {
			negList->push_back(cImg); //maybe .clone()?
		}
	}

	return posList;
}

/*
 * Sort images from posImgList into unique car subdirectiories of carsDir
 * Uses <sarcasm> Ondrej Skopek Sort Algorithm (OSSA) </sarcasm>
 */
list<list<CarImg> > CarCV::sortUnique(list<CarImg> &posCarImgList, CascadeClassifier &cascade) { //TODO: test implementation of super algorithm 3000

	map<CarImg, double> probability; //flushed at every iteration over posImgList

	list<list<CarImg> > cars; //sorted list

	list<double> carProbabilty; //result probabilities for every potential unique car

	for (int i = 0; i < CarCV::listSize(posCarImgList); i++) { //iterate over posImgList
		probability.clear();
		carProbabilty.clear();
		const CarImg sortingCar = CarCV::atList(posCarImgList, i);

		if (i == 0 && cars.size() == 0) { //first iteration
			CarCV::atList(cars, 0).push_back(CarCV::atList(posCarImgList, i));
			continue;
		}

		for (int j = 0; j < CarCV::listSize(cars); j++) { //iterate over the main list of cars
			int k;

			const int carsjSize = CarCV::atList(cars, j).size();
			for (k = 0; k < carsjSize; k++) {
				list<CarImg> curList = CarCV::atList(cars, j);
				const CarImg curCar = CarCV::atList(curList, k);

				Mat sortingCarMat = sortingCar.getImg();
				Mat curCarMat = curCar.getImg();

				const double prob = Det::probability(sortingCarMat, curCarMat, cascade, scale); //input from detection algorithm here

				probability.insert(std::pair<CarImg, double>(curCar, prob));
			}
		}

		int carsSize = cars.size();
		for (int l = 0; l < carsSize; l++) {
			double prob;
			int m;
			const int carslSize = CarCV::atList(cars, l).size();
			for (m = 0; m < carslSize; m++) {
				list<CarImg> li = CarCV::atList(cars, l);
				CarImg t = CarCV::atList(li, m);
				prob += CarCV::atMap(probability, t);
			}
			prob /= CarCV::atList(cars, l).size();
			carProbabilty.push_back(prob);
		}

		int carProbId = CarCV::findMaxIndex(carProbabilty);
		CarCV::atList(cars, carProbId).push_back(CarCV::atList(posCarImgList, i));
	}

	return cars;
}

/*
 * Should return the index of the biggest double in mlist
 * If two are equal, returns the index of the first one
 *
 */
int CarCV::findMaxIndex(list<double> &mlist) { //tested, works
	list<double>::iterator mlistI = mlist.begin();
	double probmax;
	int index;

	for (int i = 0; mlistI != mlist.end();i++) {
		if(*mlistI > probmax) {
			probmax = *mlistI;
			index = i;
		}

		mlistI++;
	}
	return index;
}

/*
 * Calculates speed of given unique car from the list of CarImg
 * Give him a row from the main list<list<CarImg> >
 * Returns a positive double
 * if speed_method isn't recognized, returns -1
 *
 * speed_method is from enum of same name
 */
double CarCV::calcSpeed(list<CarImg> clist, int speed_method) { //TODO: not yet implemented
	if (speed_method == 1) { //CCV_SP_FROMSORTEDFILES
		return 1;
	} else if (speed_method == 2) { //CCV_SP_FROMALLFILES
		return 2;
	}
	else {
		int n = speed_method;
		cerr << "ERROR: Unimplemented method: " << n << endl;
		return -1;
	}
	return 0;
}

/*
 * Save CarImg objects to carDir (USE FOR UNIQUE CARS)
 */
void CarCV::saveCarImgList(list<CarImg> carList, fs::path carDir) { //todo: create a saver for CarImgs

}

/**
 * Save list<CarImg> objects to carsDir
 */
void CarCV::saveCars(list<list<CarImg> > cars, fs::path carsDir) { //TODO: create a saver for carsDir

}

/*
 * Load/parse list<CarImg> objects from carsDir
 */
list<list<CarImg> > CarCV::loadCars(fs::path carsDir) { //TODO: create a loader/parser for carsDir
	list<list<CarImg> > carsList;

	return carsList;
}

/*
 * Load/parse CarImg objects from carList
 */
list<CarImg> CarCV::loadCarImgList(list<string> carList) { //TODO: create a loader/parser for CarImg //add a posdir param here
	list<CarImg> carImgList;

	return carImgList;
}

/*
 * Parses the input file plist into a list<string>
 */
list<string> CarCV::parseList(fs::path &plist) { //tested, should work
	list<string> retlist;

	FILE* f = fopen(plist.c_str(), "rt");
	if(f)
	{
		char buf [1000+1];
		for(int i = 0; fgets( buf, 1000, f ); i++)
		{
			int len = (int)strlen(buf);
			while( len > 0 && isspace(buf[len-1]) ) {
				len--;
			}
			buf[len] = '\0';
			retlist.push_back(buf);
		}
	}
	return retlist;
}

/*
 * List item at index
 * If index is out of bounds, returns *tlist.end()
 */
template <class T>
T CarCV::atList(list<T> &tlist, int index) { //

	typename list<T>::iterator tlistI = tlist.begin();

	for (int i = 0; tlistI != tlist.end();i++) {
			if (i == index) {
				return *tlistI;
			}
			tlistI++;
		}
	return *tlist.end();//*--tlistI; was used for returning the last element anyway
}

/*
 * Length of plist
 * Useless: use plist.size()
 */
template <class P>
int CarCV::listSize(list<P> &plist) { //useless, use plist.size()
	typename list<P>::iterator plistI = plist.begin();
	int i;

	for (i = 0; plistI != plist.end();i++) {
			plistI++;
		}
	return i;
}

/*
 * Map item at index
 * If index is not found in map, returns (*tmap.end()).second
 */
template <class K, class V>
V CarCV::atMap(map<K, V> &tmap, K index) { //tested, works

	typename map<K, V>::iterator tmapI = tmap.begin();
	typename map<K, V>::iterator searching = tmap.find(index);

	for (int i = 0; tmapI != tmap.end();i++) {
			if (tmapI == searching) {
				return (*tmapI).second;
			}
			tmapI++;
		}
	return (*tmap.end()).second;
}

/*
 * Size of pmap
 * Useless, use pmap.size()
 */
template <class K, class V>
int CarCV::mapSize(map<K, V> &pmap) { //useless, use pmap.size()
	typename map<K, V>::iterator pmapI = pmap.begin();
	int i;

	for (i = 0; pmapI != pmap.end();i++) {
			pmapI++;
		}
	return i;
}

void grabKVparams(char **argv) { //just for testing reference, erase later
	for (int i = 1; i <= 5; i++) {
		istringstream source(argv[i]);
		string token;
		string key;
		double n;
		for (int i = 0; getline( source, token, '=' ); i++) {
			if (i == 0) {
				key = token;
			}
		    istringstream ss(token);
		    ss >> n;

		}
		cout << key << endl;
		cout << n << endl;
		// do something with n
		cout << "----------" << endl;
	}
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2006 Peter Kmmel
// Permission to use, copy, modify, distribute and sell this software for any
//     purpose is hereby granted without fee, provided that the above copyright
//     notice appear in all copies and that both that copyright notice and this
//     permission notice appear in supporting documentation.
// The author makes no representations about the
//     suitability of this software for any purpose. It is provided "as is"
//     without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

// $Header:

#include "singletondll.h"
#include "foo.h"

int main()
{
	Foo& foo = Singleton<Foo>::Instance();
	Foo& lokifoo = Loki::Singleton<Foo>::Instance();
	foo.foo();
	lokifoo.foo();
}<commit_msg>add documenation, correct cvs keyword<commit_after>////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2006 Peter Kmmel
// Permission to use, copy, modify, distribute and sell this software for any
//     purpose is hereby granted without fee, provided that the above copyright
//     notice appear in all copies and that both that copyright notice and this
//     permission notice appear in supporting documentation.
// The author makes no representations about the
//     suitability of this software for any purpose. It is provided "as is"
//     without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

// $Header$

/*

Test for singletons in a shared libraries:

- there is a Foo class in Foo.dll/so
- there is a Foo singleton object which is exported by SingletonDll.dll/so
- the Foo singleton object is  managed by a Loki::SingletonHolder typedef
- the declaration of the Loki::SingletonHolder type is visiable only
  in singletondll.cpp
- a client (this file) imports the singleton object from SingletonDll.dll/so

*/

#include "singletondll.h"
#include "foo.h"

int main()
{
	Foo& foo = Singleton<Foo>::Instance();
	Foo& lokifoo = Loki::Singleton<Foo>::Instance();
	foo.foo();
	lokifoo.foo();
}<|endoftext|>


<commit_before>// Copyright © 2015 Mikko Ronkainen <firstname@mikkoronkainen.com>
// License: MIT, see the LICENSE file.

#include <exception>

#include "Raytracing/Primitives/Mesh.h"
#include "Raytracing/Ray.h"
#include "Utils/ObjReader.h"
#include "Utils/PlyReader.h"
#include "Utils/StringUtils.h"
#include "Math/Matrix4x4.h"

using namespace Raycer;

void Mesh::initialize()
{
	if (StringUtils::endsWith(meshFilePath, "obj"))
		triangles = ObjReader::readFile(meshFilePath);
	else if (StringUtils::endsWith(meshFilePath, "ply"))
		triangles = PlyReader::readFile(meshFilePath);
	else
		throw std::runtime_error("Unknown mesh file format");

	Matrix4x4 rotationX = Matrix4x4::rotateX(orientation.pitch);
	Matrix4x4 rotationY = Matrix4x4::rotateY(orientation.yaw);
	Matrix4x4 rotationZ = Matrix4x4::rotateZ(orientation.roll);
	Matrix4x4 rotation = rotationX * rotationY * rotationZ;
	Matrix4x4 scaling = Matrix4x4::scale(scale.x, scale.y, scale.z);
	Matrix4x4 translation = Matrix4x4::translate(position.x, position.y, position.z);
	Matrix4x4 transformation = translation * scaling * rotation;

	for (Triangle& triangle : triangles)
	{
		triangle.vertices[0] = transformation * triangle.vertices[0];
		triangle.vertices[1] = transformation * triangle.vertices[1];
		triangle.vertices[2] = transformation * triangle.vertices[2];

		// TODO: does not work with non-uniform scaling
		triangle.normals[0] = rotation * triangle.normals[0];
		triangle.normals[1] = rotation * triangle.normals[1];
		triangle.normals[2] = rotation * triangle.normals[2];

		triangle.normal = rotation * triangle.normal;
	}
}

void Mesh::intersect(Ray& ray) const
{
	for (const Triangle& triangle : triangles)
	{
		if (triangle.intersect(ray))
		{
			ray.intersection.materialId = materialId;
			ray.intersection.texcoord *= texcoordScale;
		}
	}
}
<commit_msg>Fixed compilation error<commit_after>// Copyright © 2015 Mikko Ronkainen <firstname@mikkoronkainen.com>
// License: MIT, see the LICENSE file.

#include <stdexcept>

#include "Raytracing/Primitives/Mesh.h"
#include "Raytracing/Ray.h"
#include "Utils/ObjReader.h"
#include "Utils/PlyReader.h"
#include "Utils/StringUtils.h"
#include "Math/Matrix4x4.h"

using namespace Raycer;

void Mesh::initialize()
{
	if (StringUtils::endsWith(meshFilePath, "obj"))
		triangles = ObjReader::readFile(meshFilePath);
	else if (StringUtils::endsWith(meshFilePath, "ply"))
		triangles = PlyReader::readFile(meshFilePath);
	else
		throw std::runtime_error("Unknown mesh file format");

	Matrix4x4 rotationX = Matrix4x4::rotateX(orientation.pitch);
	Matrix4x4 rotationY = Matrix4x4::rotateY(orientation.yaw);
	Matrix4x4 rotationZ = Matrix4x4::rotateZ(orientation.roll);
	Matrix4x4 rotation = rotationX * rotationY * rotationZ;
	Matrix4x4 scaling = Matrix4x4::scale(scale.x, scale.y, scale.z);
	Matrix4x4 translation = Matrix4x4::translate(position.x, position.y, position.z);
	Matrix4x4 transformation = translation * scaling * rotation;

	for (Triangle& triangle : triangles)
	{
		triangle.vertices[0] = transformation * triangle.vertices[0];
		triangle.vertices[1] = transformation * triangle.vertices[1];
		triangle.vertices[2] = transformation * triangle.vertices[2];

		// TODO: does not work with non-uniform scaling
		triangle.normals[0] = rotation * triangle.normals[0];
		triangle.normals[1] = rotation * triangle.normals[1];
		triangle.normals[2] = rotation * triangle.normals[2];

		triangle.normal = rotation * triangle.normal;
	}
}

void Mesh::intersect(Ray& ray) const
{
	for (const Triangle& triangle : triangles)
	{
		if (triangle.intersect(ray))
		{
			ray.intersection.materialId = materialId;
			ray.intersection.texcoord *= texcoordScale;
		}
	}
}
<|endoftext|>


<commit_before>/*
  This file is part of KOrganizer.

  Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>

  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.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "incidencechanger.h"
#include "koprefs.h"
#include "kogroupware.h"
#include "mailscheduler.h"

#include <kcal/assignmentvisitor.h>
#include <kcal/freebusy.h>
#include <kcal/dndfactory.h>

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

bool IncidenceChanger::beginChange( Incidence *incidence )
{
  if ( !incidence ) {
    return false;
  }
  kDebug() << "for incidence \"" << incidence->summary() << "\"";
  return mCalendar->beginChange( incidence );
}

bool IncidenceChanger::sendGroupwareMessage( Incidence *incidence,
                                             KCal::iTIPMethod method, bool deleting )
{
  if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) &&
       incidence->attendeeCount() > 0 &&
       !KOPrefs::instance()->mUseGroupwareCommunication ) {
    emit schedule( method, incidence );
    return true;
  } else if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
    // FIXME: Find a widget to use as parent, instead of 0
    return KOGroupware::instance()->sendICalMessage( 0, method, incidence, deleting );
  }
  return true;
}

void IncidenceChanger::cancelAttendees( Incidence *incidence )
{
  if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
    if ( KMessageBox::questionYesNo(
           0,
           i18n( "Some attendees were removed from the incidence. "
                 "Shall cancel messages be sent to these attendees?" ),
           i18n( "Attendees Removed" ), KGuiItem( i18n( "Send Messages" ) ),
           KGuiItem( i18n( "Do Not Send" ) ) ) == KMessageBox::Yes ) {
      // don't use KOGroupware::sendICalMessage here, because that asks just
      // a very general question "Other people are involved, send message to
      // them?", which isn't helpful at all in this situation. Afterwards, it
      // would only call the MailScheduler::performTransaction, so do this
      // manually.
      // FIXME: Groupware schedulling should be factored out to it's own class
      //        anyway
      KCal::MailScheduler scheduler( mCalendar );
      scheduler.performTransaction( incidence, iTIPCancel );
    }
  }
}

bool IncidenceChanger::endChange( Incidence *incidence )
{
  // FIXME: if that's a groupware incidence, and I'm not the organizer,
  // send out a mail to the organizer with a counterproposal instead
  // of actually changing the incidence. Then no locking is needed.
  // FIXME: if that's a groupware incidence, and the incidence was
  // never locked, we can't unlock it with endChange().
  if ( !incidence ) {
    return false;
  }

  kDebug() << "\"" << incidence->summary() << "\"";
  return mCalendar->endChange( incidence );
}

bool IncidenceChanger::deleteIncidence( Incidence *incidence )
{
  if ( !incidence ) {
    return true;
  }

  kDebug() << "\"" << incidence->summary() << "\"";
  bool doDelete = sendGroupwareMessage( incidence, KCal::iTIPCancel, true );
  if( doDelete ) {
    // @TODO: let Calendar::deleteIncidence do the locking...
    Incidence *tmp = incidence->clone();
    emit incidenceToBeDeleted( incidence );
    doDelete = mCalendar->deleteIncidence( incidence );
    if ( !KOPrefs::instance()->thatIsMe( tmp->organizer().email() ) ) {
      const QStringList myEmails = KOPrefs::instance()->allEmails();
      bool notifyOrganizer = false;
      for ( QStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
        QString email = *it;
        Attendee *me = tmp->attendeeByMail(email);
        if ( me ) {
          if ( me->status() == KCal::Attendee::Accepted ||
               me->status() == KCal::Attendee::Delegated ) {
            notifyOrganizer = true;
          }
          Attendee *newMe = new Attendee( *me );
          newMe->setStatus( KCal::Attendee::Declined );
          tmp->clearAttendees();
          tmp->addAttendee( newMe );
          break;
        }
      }

      if ( notifyOrganizer ) {
        KCal::MailScheduler scheduler( mCalendar );
        scheduler.performTransaction( tmp, KCal::iTIPReply );
      }
    }
    emit incidenceDeleted( incidence );
  }
  return doDelete;
}

bool IncidenceChanger::cutIncidence( Incidence *incidence )
{
  if ( !incidence ) {
    return true;
  }

  kDebug() << "\"" << incidence->summary() << "\"";
  bool doDelete = sendGroupwareMessage( incidence, KCal::iTIPCancel );
  if( doDelete ) {
    // @TODO: the factory needs to do the locking!
    DndFactory factory( mCalendar );
    emit incidenceToBeDeleted( incidence );
    factory.cutIncidence( incidence );
    emit incidenceDeleted( incidence );
  }
  return doDelete;
}

class IncidenceChanger::ComparisonVisitor : public IncidenceBase::Visitor
{
  public:
    ComparisonVisitor() {}
    bool act( IncidenceBase *incidence, IncidenceBase *inc2 )
    {
      mIncidence2 = inc2;
      if ( incidence ) {
        return incidence->accept( *this );
      } else {
        return inc2 == 0;
      }
    }

  protected:
    bool visit( Event *event )
    {
      Event *ev2 = dynamic_cast<Event*>(mIncidence2);
      if ( event && ev2 ) {
        return *event == *ev2;
      } else {
        // either both 0, or return false;
        return ev2 == event;
      }
    }
    bool visit( Todo *todo )
    {
      Todo *to2 = dynamic_cast<Todo*>( mIncidence2 );
      if ( todo && to2 ) {
        return *todo == *to2;
      } else {
        // either both 0, or return false;
        return todo == to2;
      }
    }
    bool visit( Journal *journal )
    {
      Journal *j2 = dynamic_cast<Journal*>( mIncidence2 );
      if ( journal && j2 ) {
        return *journal == *j2;
      } else {
        // either both 0, or return false;
        return journal == j2;
      }
    }
    bool visit( FreeBusy *fb )
    {
      FreeBusy *fb2 = dynamic_cast<FreeBusy*>( mIncidence2 );
      if ( fb && fb2 ) {
        return *fb == *fb2;
      } else {
        // either both 0, or return false;
        return fb2 == fb;
      }
    }

  protected:
    IncidenceBase *mIncidence2;
};

bool IncidenceChanger::incidencesEqual( Incidence *inc1, Incidence *inc2 )
{
  ComparisonVisitor v;
  return ( v.act( inc1, inc2 ) );
}

bool IncidenceChanger::assignIncidence( Incidence *inc1, Incidence *inc2 )
{
  if ( !inc1 || !inc2 ) {
    return false;
  }

  AssignmentVisitor v;
  return v.assign( inc1, inc2 );
}

bool IncidenceChanger::myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc )
{
  Attendee *oldMe = oldInc->attendeeByMails( KOPrefs::instance()->allEmails() );
  Attendee *newMe = newInc->attendeeByMails( KOPrefs::instance()->allEmails() );
  if ( oldMe && newMe && ( oldMe->status() != newMe->status() ) ) {
    return true;
  }

  return false;
}

bool IncidenceChanger::changeIncidence( Incidence *oldinc, Incidence *newinc,
                                        int action )
{
  kDebug() << "for incidence \"" << newinc->summary() << "\""
           << "( old one was \"" << oldinc->summary() << "\")";

  if ( incidencesEqual( newinc, oldinc ) ) {
    // Don't do anything
    kDebug() << "Incidence not changed";
  } else {
    kDebug() << "Changing incidence";
    bool statusChanged = myAttendeeStatusChanged( oldinc, newinc );
    int revision = newinc->revision();
    newinc->setRevision( revision + 1 );
    // FIXME: Use a generic method for this! Ideally, have an interface class
    //        for group cheduling. Each implementation could then just do what
    //        it wants with the event. If no groupware is used,use the null
    //        pattern...
    bool revert = KOPrefs::instance()->mUseGroupwareCommunication;
    if ( revert &&
        KOGroupware::instance()->sendICalMessage( 0,
                                                  KCal::iTIPRequest,
                                                  newinc, false, statusChanged ) ) {
      // Accept the event changes
      if ( action < 0 ) {
        emit incidenceChanged( oldinc, newinc );
      } else {
        emit incidenceChanged( oldinc, newinc, action );
      }
      revert = false;
    }

    if ( revert ) {
      assignIncidence( newinc, oldinc );
      return false;
    }
  }
  return true;
}

bool IncidenceChanger::addIncidence( Incidence *incidence, QWidget *parent )
{
  kDebug() << "\"" << incidence->summary() << "\"";
  if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
    if ( !KOGroupware::instance()->sendICalMessage( parent,
                                                    KCal::iTIPRequest,
                                                    incidence ) ) {
      return false;
    }
  }
  // FIXME: This is a nasty hack, since we need to set a parent for the
  //        resource selection dialog. However, we don't have any UI methods
  //        in the calendar, only in the CalendarResources::DestinationPolicy
  //        So we need to type-cast it and extract it from the CalendarResources
  CalendarResources *stdcal = dynamic_cast<CalendarResources*>( mCalendar );
  QWidget *tmpparent = 0;
  if ( stdcal ) {
    tmpparent = stdcal->dialogParentWidget();
    stdcal->setDialogParentWidget( parent );
  }
  bool success = mCalendar->addIncidence( incidence );
  if ( stdcal ) {
    // Reset the parent widget, otherwise we'll end up with pointers to deleted
    // widgets sooner or later
    stdcal->setDialogParentWidget( tmpparent );
  }
  if ( !success ) {
    // We can have a failure if the user pressed [cancel] in the resource
    // selectdialog, so check the exception.
    if ( stdcal->exception()->errorCode() != KCal::ErrorFormat::UserCancel ) {
      KMessageBox::sorry( parent,
                          i18n( "Unable to save %1 \"%2\".",
                                i18n( incidence->type() ),
                                incidence->summary() ) );
    }
    return false;
  }
  emit incidenceAdded( incidence );
  return true;
}

#include "incidencechanger.moc"
<commit_msg>Don't crash when stdcal->exception() is null.<commit_after>/*
  This file is part of KOrganizer.

  Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>

  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.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "incidencechanger.h"
#include "koprefs.h"
#include "kogroupware.h"
#include "mailscheduler.h"

#include <kcal/assignmentvisitor.h>
#include <kcal/freebusy.h>
#include <kcal/dndfactory.h>

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

bool IncidenceChanger::beginChange( Incidence *incidence )
{
  if ( !incidence ) {
    return false;
  }
  kDebug() << "for incidence \"" << incidence->summary() << "\"";
  return mCalendar->beginChange( incidence );
}

bool IncidenceChanger::sendGroupwareMessage( Incidence *incidence,
                                             KCal::iTIPMethod method, bool deleting )
{
  if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) &&
       incidence->attendeeCount() > 0 &&
       !KOPrefs::instance()->mUseGroupwareCommunication ) {
    emit schedule( method, incidence );
    return true;
  } else if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
    // FIXME: Find a widget to use as parent, instead of 0
    return KOGroupware::instance()->sendICalMessage( 0, method, incidence, deleting );
  }
  return true;
}

void IncidenceChanger::cancelAttendees( Incidence *incidence )
{
  if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
    if ( KMessageBox::questionYesNo(
           0,
           i18n( "Some attendees were removed from the incidence. "
                 "Shall cancel messages be sent to these attendees?" ),
           i18n( "Attendees Removed" ), KGuiItem( i18n( "Send Messages" ) ),
           KGuiItem( i18n( "Do Not Send" ) ) ) == KMessageBox::Yes ) {
      // don't use KOGroupware::sendICalMessage here, because that asks just
      // a very general question "Other people are involved, send message to
      // them?", which isn't helpful at all in this situation. Afterwards, it
      // would only call the MailScheduler::performTransaction, so do this
      // manually.
      // FIXME: Groupware schedulling should be factored out to it's own class
      //        anyway
      KCal::MailScheduler scheduler( mCalendar );
      scheduler.performTransaction( incidence, iTIPCancel );
    }
  }
}

bool IncidenceChanger::endChange( Incidence *incidence )
{
  // FIXME: if that's a groupware incidence, and I'm not the organizer,
  // send out a mail to the organizer with a counterproposal instead
  // of actually changing the incidence. Then no locking is needed.
  // FIXME: if that's a groupware incidence, and the incidence was
  // never locked, we can't unlock it with endChange().
  if ( !incidence ) {
    return false;
  }

  kDebug() << "\"" << incidence->summary() << "\"";
  return mCalendar->endChange( incidence );
}

bool IncidenceChanger::deleteIncidence( Incidence *incidence )
{
  if ( !incidence ) {
    return true;
  }

  kDebug() << "\"" << incidence->summary() << "\"";
  bool doDelete = sendGroupwareMessage( incidence, KCal::iTIPCancel, true );
  if( doDelete ) {
    // @TODO: let Calendar::deleteIncidence do the locking...
    Incidence *tmp = incidence->clone();
    emit incidenceToBeDeleted( incidence );
    doDelete = mCalendar->deleteIncidence( incidence );
    if ( !KOPrefs::instance()->thatIsMe( tmp->organizer().email() ) ) {
      const QStringList myEmails = KOPrefs::instance()->allEmails();
      bool notifyOrganizer = false;
      for ( QStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
        QString email = *it;
        Attendee *me = tmp->attendeeByMail(email);
        if ( me ) {
          if ( me->status() == KCal::Attendee::Accepted ||
               me->status() == KCal::Attendee::Delegated ) {
            notifyOrganizer = true;
          }
          Attendee *newMe = new Attendee( *me );
          newMe->setStatus( KCal::Attendee::Declined );
          tmp->clearAttendees();
          tmp->addAttendee( newMe );
          break;
        }
      }

      if ( notifyOrganizer ) {
        KCal::MailScheduler scheduler( mCalendar );
        scheduler.performTransaction( tmp, KCal::iTIPReply );
      }
    }
    emit incidenceDeleted( incidence );
  }
  return doDelete;
}

bool IncidenceChanger::cutIncidence( Incidence *incidence )
{
  if ( !incidence ) {
    return true;
  }

  kDebug() << "\"" << incidence->summary() << "\"";
  bool doDelete = sendGroupwareMessage( incidence, KCal::iTIPCancel );
  if( doDelete ) {
    // @TODO: the factory needs to do the locking!
    DndFactory factory( mCalendar );
    emit incidenceToBeDeleted( incidence );
    factory.cutIncidence( incidence );
    emit incidenceDeleted( incidence );
  }
  return doDelete;
}

class IncidenceChanger::ComparisonVisitor : public IncidenceBase::Visitor
{
  public:
    ComparisonVisitor() {}
    bool act( IncidenceBase *incidence, IncidenceBase *inc2 )
    {
      mIncidence2 = inc2;
      if ( incidence ) {
        return incidence->accept( *this );
      } else {
        return inc2 == 0;
      }
    }

  protected:
    bool visit( Event *event )
    {
      Event *ev2 = dynamic_cast<Event*>(mIncidence2);
      if ( event && ev2 ) {
        return *event == *ev2;
      } else {
        // either both 0, or return false;
        return ev2 == event;
      }
    }
    bool visit( Todo *todo )
    {
      Todo *to2 = dynamic_cast<Todo*>( mIncidence2 );
      if ( todo && to2 ) {
        return *todo == *to2;
      } else {
        // either both 0, or return false;
        return todo == to2;
      }
    }
    bool visit( Journal *journal )
    {
      Journal *j2 = dynamic_cast<Journal*>( mIncidence2 );
      if ( journal && j2 ) {
        return *journal == *j2;
      } else {
        // either both 0, or return false;
        return journal == j2;
      }
    }
    bool visit( FreeBusy *fb )
    {
      FreeBusy *fb2 = dynamic_cast<FreeBusy*>( mIncidence2 );
      if ( fb && fb2 ) {
        return *fb == *fb2;
      } else {
        // either both 0, or return false;
        return fb2 == fb;
      }
    }

  protected:
    IncidenceBase *mIncidence2;
};

bool IncidenceChanger::incidencesEqual( Incidence *inc1, Incidence *inc2 )
{
  ComparisonVisitor v;
  return ( v.act( inc1, inc2 ) );
}

bool IncidenceChanger::assignIncidence( Incidence *inc1, Incidence *inc2 )
{
  if ( !inc1 || !inc2 ) {
    return false;
  }

  AssignmentVisitor v;
  return v.assign( inc1, inc2 );
}

bool IncidenceChanger::myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc )
{
  Attendee *oldMe = oldInc->attendeeByMails( KOPrefs::instance()->allEmails() );
  Attendee *newMe = newInc->attendeeByMails( KOPrefs::instance()->allEmails() );
  if ( oldMe && newMe && ( oldMe->status() != newMe->status() ) ) {
    return true;
  }

  return false;
}

bool IncidenceChanger::changeIncidence( Incidence *oldinc, Incidence *newinc,
                                        int action )
{
  kDebug() << "for incidence \"" << newinc->summary() << "\""
           << "( old one was \"" << oldinc->summary() << "\")";

  if ( incidencesEqual( newinc, oldinc ) ) {
    // Don't do anything
    kDebug() << "Incidence not changed";
  } else {
    kDebug() << "Changing incidence";
    bool statusChanged = myAttendeeStatusChanged( oldinc, newinc );
    int revision = newinc->revision();
    newinc->setRevision( revision + 1 );
    // FIXME: Use a generic method for this! Ideally, have an interface class
    //        for group cheduling. Each implementation could then just do what
    //        it wants with the event. If no groupware is used,use the null
    //        pattern...
    bool revert = KOPrefs::instance()->mUseGroupwareCommunication;
    if ( revert &&
        KOGroupware::instance()->sendICalMessage( 0,
                                                  KCal::iTIPRequest,
                                                  newinc, false, statusChanged ) ) {
      // Accept the event changes
      if ( action < 0 ) {
        emit incidenceChanged( oldinc, newinc );
      } else {
        emit incidenceChanged( oldinc, newinc, action );
      }
      revert = false;
    }

    if ( revert ) {
      assignIncidence( newinc, oldinc );
      return false;
    }
  }
  return true;
}

bool IncidenceChanger::addIncidence( Incidence *incidence, QWidget *parent )
{
  kDebug() << "\"" << incidence->summary() << "\"";
  if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
    if ( !KOGroupware::instance()->sendICalMessage( parent,
                                                    KCal::iTIPRequest,
                                                    incidence ) ) {
      return false;
    }
  }
  // FIXME: This is a nasty hack, since we need to set a parent for the
  //        resource selection dialog. However, we don't have any UI methods
  //        in the calendar, only in the CalendarResources::DestinationPolicy
  //        So we need to type-cast it and extract it from the CalendarResources
  CalendarResources *stdcal = dynamic_cast<CalendarResources*>( mCalendar );
  QWidget *tmpparent = 0;
  if ( stdcal ) {
    tmpparent = stdcal->dialogParentWidget();
    stdcal->setDialogParentWidget( parent );
  }
  bool success = mCalendar->addIncidence( incidence );
  if ( stdcal ) {
    // Reset the parent widget, otherwise we'll end up with pointers to deleted
    // widgets sooner or later
    stdcal->setDialogParentWidget( tmpparent );
  }
  if ( !success ) {
    // We can have a failure if the user pressed [cancel] in the resource
    // selectdialog, so check the exception.
    ErrorFormat *e = stdcal->exception();
    if ( !e || ( e && ( e->errorCode() != KCal::ErrorFormat::UserCancel ) ) ) {
      KMessageBox::sorry( parent,
                          i18n( "Unable to save %1 \"%2\".",
                                i18n( incidence->type() ),
                                incidence->summary() ) );
    }
    return false;
  }
  emit incidenceAdded( incidence );
  return true;
}

#include "incidencechanger.moc"
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2007 by Thomas Moenicke                                 *
 *   thomas.moenicke@kdemail.net                                           *
 *                                                                         *
 *   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 "plasmobiff.h"

#include <QApplication>
#include <QImage>
#include <QPaintDevice>
#include <QLabel>
#include <QPixmap>
#include <QPaintEvent>
#include <QPainter>
#include <QX11Info>
#include <QWidget>
#include <QGraphicsItem>
#include <QColor>

#include <plasma/svg.h>

PlasmoBiff::PlasmoBiff(QObject *parent, const QStringList &args)
  : Plasma::Applet(parent, args),
    m_dialog(0),
    m_fmFrom(QApplication::font()),
    m_fmSubject(QApplication::font())
{
  setFlags(QGraphicsItem::ItemIsMovable);

  KConfigGroup cg = appletConfig();
  m_xPixelSize = cg.readEntry("xsize", 413);
  m_yPixelSize = cg.readEntry("ysize", 307);

  m_theme = new Plasma::Svg("widgets/akonadi", this);
  m_theme->setContentType(Plasma::Svg::SingleImage);
  m_theme->resize(m_xPixelSize,m_yPixelSize);

  // DataEngine
  Plasma::DataEngine* akonadiEngine = dataEngine("akonadi");
  //  akonadiEngine->connectSource(m_fromList[0], this);
  akonadiEngine->connectAllSources(this);

  constraintsUpdated();

  QFontMetrics fmFrom(QApplication::font());
  QFontMetrics fmSubject(QApplication::font());

  //  m_fontFrom.
  m_fontSubject.setBold(true);
  /*
  m_fromList[0] = QString("mail1 longtextlongtextlongtext");
  m_fromList[1] = QString("mail2 longtextlongtextlongtext");
  m_fromList[2] = QString("mail3 longtext");
  m_fromList[3] = QString("mail4 longtextlongtextlongtext");

  m_subjectList[0] = QString("subject1 longtextlongtextlongtext");
  m_subjectList[1] = QString("subject2 longtextlongtextlongtext");
  m_subjectList[2] = QString("subject3 longtext");
  m_subjectList[3] = QString("subject4 longtextlongtextlongtext");
  */
}

PlasmoBiff::~ PlasmoBiff()
{
}

void PlasmoBiff::constraintsUpdated()
{
  prepareGeometryChange();

  if (formFactor() == Plasma::Planar ||
      formFactor() == Plasma::MediaCenter) {
    QSize s = m_theme->size();
    m_bounds = QRect(0, 0, s.width(), s.height());
  } else {
    QFontMetrics fm(QApplication::font());
    m_bounds = QRectF(0 ,0 ,fm.width("email@something.org"), fm.height() * 1.5);
  }

}

void PlasmoBiff::configureDialog()
{
  if (m_dialog == 0) {
    m_dialog = new KDialog;
    m_dialog->setCaption( "Configure PlasmoBiff" );

    ui.setupUi(m_dialog->mainWidget());
    m_dialog->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
    connect( m_dialog, SIGNAL(applyClicked()), this, SLOT(configAccepted()) );
    connect( m_dialog, SIGNAL(okClicked()), this, SLOT(configAccepted()) );

  }
  m_dialog->show();
}

void PlasmoBiff::paintInterface(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{

  painter->setRenderHint(QPainter::SmoothPixmapTransform);
  // draw the main background stuff
  m_theme->paint(painter, boundingRect(), "email_frame");

  QRectF bRect = boundingRect();
  bRect.setX(bRect.x()+228);

  // draw the 4 channels
  bRect.setY(bRect.y()+102);
  drawEmail(0, bRect, painter);

  bRect.setY(bRect.y()-88);
  drawEmail(1, bRect, painter);

  bRect.setY(bRect.y()-88);
  drawEmail(2, bRect, painter);

  bRect.setY(bRect.y()-88);
  drawEmail(3, bRect, painter);

}

QRectF PlasmoBiff::boundingRect() const
{
  return m_bounds;
}

void PlasmoBiff::drawEmail(int index, const QRectF& rect, QPainter* painter)
{

  QPen _pen = painter->pen();
  QFont _font = painter->font();

  painter->setPen(Qt::white);

  painter->setFont(m_fontFrom);
  painter->drawText((int)(rect.width()/2 - m_fmFrom.width(m_fromList[index]) / 2),
		    (int)((rect.height()/2) - m_fmFrom.xHeight()*3),
		    m_fromList[index]);

  painter->setFont(m_fontSubject);
  painter->drawText((int)(rect.width()/2 - m_fmSubject.width(m_subjectList[index]) / 2),
		    (int)((rect.height()/2) - m_fmSubject.xHeight()*3 + 15),
		    m_subjectList[index]);

  // restore
  painter->setFont(_font);
  painter->setPen(_pen);

}

void PlasmoBiff::updated(const QString &source, Plasma::DataEngine::Data &data)
{

  m_fromList[3] = m_fromList[2];
  m_subjectList[3] = m_subjectList[2];

  m_fromList[2] = m_fromList[1];
  m_subjectList[2] = m_subjectList[1];

  m_fromList[1] = m_fromList[0];
  m_subjectList[1] = m_subjectList[0];

  m_fromList[0] = data["From"].toString();
  m_subjectList[0] = data["Subject"].toString();

  update();

}

#include "plasmobiff.moc"
<commit_msg>* long subject/from are cutted. text is centered. small issue in update(source)<commit_after>/***************************************************************************
 *   Copyright (C) 2007 by Thomas Moenicke                                 *
 *   thomas.moenicke@kdemail.net                                           *
 *                                                                         *
 *   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 "plasmobiff.h"

#include <QApplication>
#include <QImage>
#include <QPaintDevice>
#include <QLabel>
#include <QPixmap>
#include <QPaintEvent>
#include <QPainter>
#include <QX11Info>
#include <QWidget>
#include <QGraphicsItem>
#include <QColor>

#include <plasma/svg.h>

PlasmoBiff::PlasmoBiff(QObject *parent, const QStringList &args)
  : Plasma::Applet(parent, args),
    m_dialog(0),
    m_fmFrom(QApplication::font()),
    m_fmSubject(QApplication::font())
{
  setFlags(QGraphicsItem::ItemIsMovable);

  KConfigGroup cg = appletConfig();
  m_xPixelSize = cg.readEntry("xsize", 413);
  m_yPixelSize = cg.readEntry("ysize", 307);

  m_theme = new Plasma::Svg("widgets/akonadi", this);
  m_theme->setContentType(Plasma::Svg::SingleImage);
  m_theme->resize(m_xPixelSize,m_yPixelSize);

  // DataEngine
  Plasma::DataEngine* akonadiEngine = dataEngine("akonadi");
  //  akonadiEngine->connectSource(m_fromList[0], this);
  akonadiEngine->connectAllSources(this);

  constraintsUpdated();

  QFontMetrics fmFrom(QApplication::font());
  QFontMetrics fmSubject(QApplication::font());

  //  m_fontFrom.
  m_fontSubject.setBold(true);

  m_subjectList[0] = QString("hello aKademy");

}

PlasmoBiff::~ PlasmoBiff()
{
}

void PlasmoBiff::constraintsUpdated()
{
  prepareGeometryChange();

  if (formFactor() == Plasma::Planar ||
      formFactor() == Plasma::MediaCenter) {
    QSize s = m_theme->size();
    m_bounds = QRect(0, 0, s.width(), s.height());
  } else {
    QFontMetrics fm(QApplication::font());
    m_bounds = QRectF(0 ,0 ,fm.width("email@something.org"), fm.height() * 1.5);
  }

}

void PlasmoBiff::configureDialog()
{
  if (m_dialog == 0) {
    m_dialog = new KDialog;
    m_dialog->setCaption( "Configure PlasmoBiff" );

    ui.setupUi(m_dialog->mainWidget());
    m_dialog->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
    connect( m_dialog, SIGNAL(applyClicked()), this, SLOT(configAccepted()) );
    connect( m_dialog, SIGNAL(okClicked()), this, SLOT(configAccepted()) );

  }
  m_dialog->show();
}

void PlasmoBiff::paintInterface(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{

  painter->setRenderHint(QPainter::SmoothPixmapTransform);
  // draw the main background stuff
  m_theme->paint(painter, boundingRect(), "email_frame");

  QRectF bRect = boundingRect();
  bRect.setX(bRect.x()+93);

  // draw the 4 channels
  bRect.setY(bRect.y()+102);
  drawEmail(0, bRect, painter);

  bRect.setY(bRect.y()-88);
  drawEmail(1, bRect, painter);

  bRect.setY(bRect.y()-88);
  drawEmail(2, bRect, painter);

  bRect.setY(bRect.y()-88);
  drawEmail(3, bRect, painter);

}

QRectF PlasmoBiff::boundingRect() const
{
  return m_bounds;
}

void PlasmoBiff::drawEmail(int index, const QRectF& rect, QPainter* painter)
{

  QPen _pen = painter->pen();
  QFont _font = painter->font();

  painter->setPen(Qt::white);

  QString from = m_fromList[index];
  if(from.size() > 33) // cut if too long
    {
      from.resize(30);
      from.append("...");
    }

  painter->setFont(m_fontFrom);
  painter->drawText((int)(rect.width()/2 - m_fmFrom.width(from) / 2),
		    (int)((rect.height()/2) - m_fmFrom.xHeight()*3),
		    from);

  QString subject = m_subjectList[index];
  if(subject.size() > 33) // cut
    {
      subject.resize(30);
      subject.append("...");
    }

  painter->setFont(m_fontSubject);
  painter->drawText((int)(rect.width()/2 - m_fmSubject.width(subject) / 2),
		    (int)((rect.height()/2) - m_fmSubject.xHeight()*3 + 15),
		    subject);

  // restore
  painter->setFont(_font);
  painter->setPen(_pen);

}

void PlasmoBiff::updated(const QString &source, Plasma::DataEngine::Data &data)
{

  m_fromList[3] = m_fromList[2];
  m_subjectList[3] = m_subjectList[2];

  m_fromList[2] = m_fromList[1];
  m_subjectList[2] = m_subjectList[1];

  m_fromList[1] = m_fromList[0];
  m_subjectList[1] = m_subjectList[0];

  if(source == "From")
    m_fromList[0] = data["From"].toString();
  else
    m_subjectList[0] = data["Subject"].toString();

  update();

}

#include "plasmobiff.moc"
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2008-08-31
// Updated : 2008-08-31
// Licence : This source is under MIT License
// File    : test/core/type_vec1.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////

#define GLM_FORCE_RADIANS
#include <glm/gtx/vec1.hpp>

int test_operators()
{
	glm::vec4 A(1.0f);
	glm::vec4 B(1.0f);
	bool R = A != B;
	bool S = A == B;

	return (S && !R) ? 0 : 1;
}

int test_operator_increment()
{
	int Error(0);

	glm::ivec1 v0(1);
	glm::ivec1 v1(v0);
	glm::ivec1 v2(v0);
	glm::ivec1 v3 = ++v1;
	glm::ivec1 v4 = v2++;

	Error += glm::all(glm::equal(v0, v4)) ? 0 : 1;
	Error += glm::all(glm::equal(v1, v2)) ? 0 : 1;
	Error += glm::all(glm::equal(v1, v3)) ? 0 : 1;

	int i0(1);
	int i1(i0);
	int i2(i0);
	int i3 = ++i1;
	int i4 = i2++;

	Error += i0 == i4 ? 0 : 1;
	Error += i1 == i2 ? 0 : 1;
	Error += i1 == i3 ? 0 : 1;

	return Error;
}

int main()
{
	int Error = 0;

	Error += test_operators();
	Error += test_operator_increment();

	return Error;
}
<commit_msg>Added vec1 operator tests<commit_after>///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2008-08-31
// Updated : 2008-08-31
// Licence : This source is under MIT License
// File    : test/core/type_vec1.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////

#define GLM_FORCE_RADIANS
#include <glm/gtx/vec1.hpp>

int test_operators()
{
	int Error(0);

	glm::vec1 A(1.0f);
	glm::vec1 B(1.0f);
	{
		bool R = A != B;
		bool S = A == B;

		Error += (S && !R) ? 0 : 1;
	}

	{
		A *= 1.0f;
		B *= 1.0;
		A += 1.0f;
		B += 1.0;

		bool R = A != B;
		bool S = A == B;

		Error += (S && !R) ? 0 : 1;
	}

	return Error;
}

int test_operator_increment()
{
	int Error(0);

	glm::ivec1 v0(1);
	glm::ivec1 v1(v0);
	glm::ivec1 v2(v0);
	glm::ivec1 v3 = ++v1;
	glm::ivec1 v4 = v2++;

	Error += glm::all(glm::equal(v0, v4)) ? 0 : 1;
	Error += glm::all(glm::equal(v1, v2)) ? 0 : 1;
	Error += glm::all(glm::equal(v1, v3)) ? 0 : 1;

	int i0(1);
	int i1(i0);
	int i2(i0);
	int i3 = ++i1;
	int i4 = i2++;

	Error += i0 == i4 ? 0 : 1;
	Error += i1 == i2 ? 0 : 1;
	Error += i1 == i3 ? 0 : 1;

	return Error;
}

int main()
{
	int Error = 0;

	Error += test_operators();
	Error += test_operator_increment();

	return Error;
}
<|endoftext|>


<commit_before><commit_msg>Added unit tests for the Matrix class.<commit_after>#include "gtest/gtest.h"
#include "Matrix.h"

/**
 * Object Construction tests
 */
TEST(MatrixContructionTests, ByZeroMatrix) {
	Matrix a;
	const char *expectedResult = "[ 000.00, 000.00 ]\n[ 000.00, 000.00 ]\n";
	EXPECT_STREQ(expectedResult, a.display());
}

TEST(MatrixContructionTests, ByValue) {
	Matrix a(12.0, 45.0, 66.0, 10.0);
	const char *expectedResult = "[ 012.00, 045.00 ]\n[ 066.00, 010.00 ]\n";
	EXPECT_STREQ(expectedResult, a.display());
}

TEST(MatrixContructionTests, ByArray) {
	float b[2][2] = {{2.0, 4.0}, {7.0, 10.0}};
	Matrix a(b);
	const char *expectedResult = "[ 002.00, 004.00 ]\n[ 007.00, 010.00 ]\n";
	EXPECT_STREQ(expectedResult, a.display());
}

/**
 * Test matrix operations (PREP)
 */
class MatrixTests : public ::testing::Test {

protected:
	Matrix m1;
	Matrix m2;
	Matrix m3;

	virtual void SetUp() {
		m1 = Matrix (1, 2, 3, 4);
		m2 = Matrix (1, 2, 3, 4);
		m3 = Matrix (1, 1, 1, 1);
	}

};

/**
 * Test matrix operations (Unit tests)
 */
TEST_F(MatrixTests, AdditionTest) {
	Matrix m = m1 + m2;
	const char *expectedResult = "[ 002.00, 004.00 ]\n[ 006.00, 008.00 ]\n";
	EXPECT_STREQ(expectedResult, m.display());
}

TEST_F(MatrixTests, MultiplicationTest) {
	Matrix m = m2 * m3;
	const char *expectedResult = "[ 003.00, 003.00 ]\n[ 007.00, 007.00 ]\n";
	EXPECT_STREQ(expectedResult, m.display());
}

TEST_F(MatrixTests, AddAndMultiplyTest) {
	Matrix m = m2 * m3 + m1;
	const char *expectedResult = "[ 004.00, 005.00 ]\n[ 010.00, 011.00 ]\n";
	EXPECT_STREQ(expectedResult, m.display());
}<|endoftext|>