<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  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.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *
 */
#ifndef PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_DISTANCE_HPP_
#define PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_DISTANCE_HPP_

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::registration::CorrespondenceRejectorDistance::applyRejection (pcl::Correspondences &correspondences)
{
  unsigned int number_valid_correspondences = 0;
  correspondences.resize (input_correspondences_->size ());
  for (size_t i = 0; i < input_correspondences_->size (); ++i)
  {
    if (data_container_)
    {
      if (data_container_->getCorrespondenceScore ((*input_correspondences_)[i]) < max_distance_)
      {
        correspondences[number_valid_correspondences] = (*input_correspondences_)[i];
        ++number_valid_correspondences;
      }
    }
    else
    {
      if ((*input_correspondences_)[i].distance < max_distance_)
      {
        correspondences[number_valid_correspondences] = (*input_correspondences_)[i];
        ++number_valid_correspondences;
      }
    }
  }
  correspondences.resize (number_valid_correspondences);
}

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::registration::CorrespondenceRejectorDistance::getRemainingCorrespondences (
    const pcl::Correspondences& original_correspondences,
    pcl::Correspondences& remaining_correspondences)
{
  unsigned int number_valid_correspondences = 0;
  remaining_correspondences.resize (original_correspondences.size ());
  for (size_t i = 0; i < original_correspondences.size (); ++i)
  {
    if (original_correspondences[i].distance < max_distance_)
    {
      remaining_correspondences[number_valid_correspondences] = original_correspondences[i];
      ++number_valid_correspondences;
    }
  }
  remaining_correspondences.resize (number_valid_correspondences);
}

#endif /* PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_DISTANCE_HPP_ */
<commit_msg>fixed `pcl::registration::CorrespondenceRejectorDistance::getRemainingCorrespondences (const pcl::Correspondences& original_correspondences, pcl::Correspondences& remaining_correspondences)`    <commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  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.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *
 */
#ifndef PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_DISTANCE_HPP_
#define PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_DISTANCE_HPP_

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::registration::CorrespondenceRejectorDistance::applyRejection (pcl::Correspondences &correspondences)
{
  unsigned int number_valid_correspondences = 0;
  correspondences.resize (input_correspondences_->size ());
  for (size_t i = 0; i < input_correspondences_->size (); ++i)
  {
    if (data_container_)
    {
      if (data_container_->getCorrespondenceScore ((*input_correspondences_)[i]) < max_distance_)
      {
        correspondences[number_valid_correspondences] = (*input_correspondences_)[i];
        ++number_valid_correspondences;
      }
    }
    else
    {
      if ((*input_correspondences_)[i].distance < max_distance_)
      {
        correspondences[number_valid_correspondences] = (*input_correspondences_)[i];
        ++number_valid_correspondences;
      }
    }
  }
  correspondences.resize (number_valid_correspondences);
}

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::registration::CorrespondenceRejectorDistance::getRemainingCorrespondences (
    const pcl::Correspondences& original_correspondences,
    pcl::Correspondences& remaining_correspondences)
{
  unsigned int number_valid_correspondences = 0;
  remaining_correspondences.resize (original_correspondences.size ());
  for (size_t i = 0; i < original_correspondences.size (); ++i)
  {
    if (data_container_)
    {
      if (data_container_->getCorrespondenceScore (original_correspondences[i]) < max_distance_)
      {
        remaining_correspondences[number_valid_correspondences] = original_correspondences[i];
        ++number_valid_correspondences;
      }
    }
    else
    {
      if (original_correspondences[i].distance < max_distance_)
      {
        remaining_correspondences[number_valid_correspondences] = original_correspondences[i];
        ++number_valid_correspondences;
      }
    }
  }
  remaining_correspondences.resize (number_valid_correspondences);
}

#endif /* PCL_REGISTRATION_IMPL_CORRESPONDENCE_REJECTION_DISTANCE_HPP_ */
<|endoftext|>


<commit_before>#include "cm_utils.h"
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <poll.h>

namespace cm
{

static void SetDefaultPath( GtkWidget *dialog, const char *defaultPath )
{
    if ( !defaultPath || strlen(defaultPath) == 0 )
        return;

    /* GTK+ manual recommends not specifically setting the default path.
       We do it anyway in order to be consistent across platforms.

       If consistency with the native OS is preferred, this is the line
       to comment out. -ml */
    gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), defaultPath );
}

#define MAX_STRLEN 512

static void AddFiltersToDialog( GtkWidget *dialog, const char *type )
{
    GtkFileFilter *filter;

    if ( !type || strlen(type) == 0 )
        return;

    std::string wildcard = std::string("*.") + type;
    filter = gtk_file_filter_new();
    gtk_file_filter_set_name(filter, type);
    gtk_file_filter_add_pattern( filter, wildcard.c_str() );
    gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );

    filter = gtk_file_filter_new();
    gtk_file_filter_set_name( filter, "*.*" );
    gtk_file_filter_add_pattern( filter, "*" );
    gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
}

static void WaitForCleanup(void)
{
    while (gtk_events_pending())
        gtk_main_iteration();
}

bool openFolderDialog( std::string & str, const char *title )
{
    printf("openFolderDialog not implemented on LINUX!!");
    return false;
}

/// \todo String!
/// Dialog for opening file
bool		openFileDialog( std::string & path,  const char*  type, int maxsize  )
{
	static std::string currentOpenPath="none";

	bool result = false;
	char * outPath;

	GtkWidget *dialog;

    if ( !gtk_init_check( NULL, NULL ) )
    {
        return false;
    }

    dialog = gtk_file_chooser_dialog_new( "Open File",
                                          NULL,
                                          GTK_FILE_CHOOSER_ACTION_OPEN,
                                          "_Cancel", GTK_RESPONSE_CANCEL,
                                          "_Open", GTK_RESPONSE_ACCEPT,
                                          NULL );

    bool typeSpecified = true;
    if( strcmp(type,"*")==0 )
	{
		typeSpecified = false;
	}
	else
	{
    	AddFiltersToDialog(dialog, type);
    }

    /* Set the default path */
    if(currentOpenPath != "none")
	    SetDefaultPath(dialog, currentOpenPath.c_str());
	else
		SetDefaultPath(dialog, getCurrentDirectory().c_str());

    result = false;
    if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
    {
        char *filename;

        filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

        path = filename;

        g_free( filename );

        currentOpenPath = getDirectoryFromPath(path);

        result = true;
    }

    WaitForCleanup();
    gtk_widget_destroy(dialog);
    WaitForCleanup();

    return result;
}

/// Dialog for saving file
bool		saveFileDialog( std::string & path, const char* type, int maxsize  )
{
	static std::string currentSavePath="none";

	bool result = false;
	char * outPath;

	GtkWidget *dialog;

    if ( !gtk_init_check( NULL, NULL ) )
    {
        return false;
    }

    dialog = gtk_file_chooser_dialog_new( "Save File",
                                          NULL,
                                          GTK_FILE_CHOOSER_ACTION_SAVE,
                                          "_Cancel", GTK_RESPONSE_CANCEL,
                                          "_Save", GTK_RESPONSE_ACCEPT,
                                          NULL );

    bool typeSpecified = true;
    if( strcmp(type,"*")==0 )
	{
		typeSpecified = false;
	}
	else
	{
    	AddFiltersToDialog(dialog, type);
    }

    /* Set the default path */
    if( currentSavePath != "none" )
    	SetDefaultPath(dialog, currentSavePath.c_str());
    else
    	SetDefaultPath(dialog, getCurrentDirectory().c_str());

    result = false;
    if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
    {
        char *filename;

        filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

        std::string res = filename;
        if(typeSpecified)
		{
			std::string suff = getFileExt(res);
			if( suff != type )
			{
				res = getPathWithoutExt(res) + "." + std::string(type);
			}
		}

		path = res;

       	currentSavePath = getDirectoryFromPath(path);

        g_free( filename );

        result = true;
    }

    WaitForCleanup();
    gtk_widget_destroy(dialog);
    WaitForCleanup();

    return result;
}

std::string  getExecutablePath()
{
	char buffer[PATH_MAX];

	char* path_end;
  	/* Read the target of /proc/self/exe.  */
  	if (readlink ("/proc/self/exe", buffer, PATH_MAX) <= 0)
    	return "";
  	/* Find the last occurence of a forward slash, the path separator.  */
 	path_end = strrchr (buffer, '/');
  	if (path_end == NULL)
    	return "";
 	 /* Advance to the character past the last slash.  */
  	++path_end;
	/* Obtain the directory containing the program by truncating the
	   path after the last slash.  */
	*path_end = '\0';
	/* The length of the path is the number of characters up through the
	 last slash.  */
	return std::string(buffer);
}

///////////////
// Gross filewatcher

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

FileWatcher::FileWatcher( const std::string & path, int msecs  )
:
fileFlags(0),
msecs(msecs)
{
  //http://man7.org/tlpi/code/online/diff/inotify/demo_inotify.c.html

     struct inotify_event *event;

     fd = inotify_init();                 /* Create inotify instance */
     if (fd == -1)
         assert(0);

  numFiles =  1;

  int wd = inotify_add_watch(fd, path.c_str(), IN_MODIFY ); //IN_ALL_EVENTS);
    Wd.push_back(wd);

    //paths.push_back(path);

    running = true;
    thread = std::thread(&FileWatcher::run, this);
}

FileWatcher::~FileWatcher()
{
    stop();
    for( int i = 0; i < Wd.size(); i++ )
       inotify_rm_watch( fd, Wd[i] );
   close(fd);
     printf("Closed file watcher\n");
}

bool FileWatcher::hasFileChanged()
{
  bool res = fileFlags != 0;
  fileFlags = 0;
  return res;
}

static void             /* Display information from inotify_event structure */
 displayInotifyEvent(FileWatcher * watcher, struct inotify_event *i)
 {
    /*
     printf("    wd =%2d; ", i->wd);
     if (i->cookie > 0)
         printf("cookie =%4d; ", i->cookie);

     printf("mask = ");
     if (i->mask & IN_ACCESS)        printf("IN_ACCESS ");
     if (i->mask & IN_ATTRIB)        printf("IN_ATTRIB ");
     if (i->mask & IN_CLOSE_NOWRITE) printf("IN_CLOSE_NOWRITE ");
     if (i->mask & IN_CLOSE_WRITE)   printf("IN_CLOSE_WRITE ");
     if (i->mask & IN_CREATE)        printf("IN_CREATE ");
     if (i->mask & IN_DELETE)        printf("IN_DELETE ");
     if (i->mask & IN_DELETE_SELF)   printf("IN_DELETE_SELF ");
     if (i->mask & IN_IGNORED)       printf("IN_IGNORED ");
     if (i->mask & IN_ISDIR)         printf("IN_ISDIR ");
     if (i->mask & IN_MODIFY)        printf("IN_MODIFY ");
     if (i->mask & IN_MOVE_SELF)     printf("IN_MOVE_SELF ");
     if (i->mask & IN_MOVED_FROM)    printf("IN_MOVED_FROM ");
     if (i->mask & IN_MOVED_TO)      printf("IN_MOVED_TO ");
     if (i->mask & IN_OPEN)          printf("IN_OPEN ");
     if (i->mask & IN_Q_OVERFLOW)    printf("IN_Q_OVERFLOW ");
     if (i->mask & IN_UNMOUNT)       printf("IN_UNMOUNT ");
     printf("\n");

*/

    if( i->len < 1 )
        return;

    std::string name = i->name;
    if( getFileExt(name) == "py" && getFilenameFromPath(name) != "tmp.py" )
    {
        printf("Modified file: %s\n", i->name);
        watcher->fileFlags = 1;
    }

 }

void FileWatcher::stop()
{
    if(running)
    {
        mutex.lock();
        printf("Joining thread\n");
        running = false;
        thread.join();
        printf("Stopped file watching thread\n");
        mutex.unlock();
    }
}

void FileWatcher::run()
{
  char *p;
  struct inotify_event *event;
  char buf[EVENT_BUF_LEN] __attribute__ ((aligned(8)));
    printf("Starting file watcher\n");

  while( running )
  {
        //mutex.lock();
        struct pollfd pfd = { fd, POLLIN, 0 };
        int ret = poll(&pfd, 1, 50);  // timeout of 50ms
        if (ret < 0) {
            fprintf(stderr, "poll failed: %s\n", strerror(errno));
        } else if (ret == 0) {
            continue;
        }

    int numRead = read(fd, buf, EVENT_BUF_LEN);

        if( numRead == 0 )
    {
      continue;
    }

    for (p = buf; p < buf + numRead; ) {
             event = (struct inotify_event *) p;
             displayInotifyEvent(this, event);
         //fileFlags = 1;
             p += EVENT_SIZE + event->len;
         }
         //mutex.unlock();
         std::this_thread::sleep_for(std::chrono::milliseconds(10));

    //Thread::sleep(msecs);
  }
}

}<commit_msg>fixes for linux<commit_after>#include "cm_utils.h"
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <poll.h>

namespace cm
{

static void SetDefaultPath( GtkWidget *dialog, const char *defaultPath )
{
    if ( !defaultPath || strlen(defaultPath) == 0 )
        return;

    /* GTK+ manual recommends not specifically setting the default path.
       We do it anyway in order to be consistent across platforms.

       If consistency with the native OS is preferred, this is the line
       to comment out. -ml */
    gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), defaultPath );
}

#define MAX_STRLEN 512

static void AddFiltersToDialog( GtkWidget *dialog, const char *type )
{
    GtkFileFilter *filter;

    if ( !type || strlen(type) == 0 )
        return;

    std::string wildcard = std::string("*.") + type;
    filter = gtk_file_filter_new();
    gtk_file_filter_set_name(filter, type);
    gtk_file_filter_add_pattern( filter, wildcard.c_str() );
    gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );

    filter = gtk_file_filter_new();
    gtk_file_filter_set_name( filter, "*.*" );
    gtk_file_filter_add_pattern( filter, "*" );
    gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(dialog), filter );
}

static void WaitForCleanup(void)
{
    while (gtk_events_pending())
        gtk_main_iteration();
}

bool openFolderDialog( std::string & str, const char *title )
{
    printf("openFolderDialog not implemented on LINUX!!");
    return false;
}

/// \todo String!
/// Dialog for opening file
bool		openFileDialog( std::string & path,  const char*  type, int maxsize  )
{
	static std::string currentOpenPath="none";

	bool result = false;
	char * outPath;

	GtkWidget *dialog;

    if ( !gtk_init_check( NULL, NULL ) )
    {
        return false;
    }

    dialog = gtk_file_chooser_dialog_new( "Open File",
                                          NULL,
                                          GTK_FILE_CHOOSER_ACTION_OPEN,
                                          "_Cancel", GTK_RESPONSE_CANCEL,
                                          "_Open", GTK_RESPONSE_ACCEPT,
                                          NULL );

    bool typeSpecified = true;
    if( strcmp(type,"*")==0 )
	{
		typeSpecified = false;
	}
	else
	{
    	AddFiltersToDialog(dialog, type);
    }

    /* Set the default path */
    if(currentOpenPath != "none")
	    SetDefaultPath(dialog, currentOpenPath.c_str());
	else
		SetDefaultPath(dialog, getCurrentDirectory().c_str());

    result = false;
    if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
    {
        char *filename;

        filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

        path = filename;

        g_free( filename );

        currentOpenPath = getDirectoryFromPath(path);

        result = true;
    }

    WaitForCleanup();
    gtk_widget_destroy(dialog);
    WaitForCleanup();

    return result;
}

/// Dialog for saving file
bool		saveFileDialog( std::string & path, const char* type, int maxsize  )
{
	static std::string currentSavePath="none";

	bool result = false;
	char * outPath;

	GtkWidget *dialog;

    if ( !gtk_init_check( NULL, NULL ) )
    {
        return false;
    }

    dialog = gtk_file_chooser_dialog_new( "Save File",
                                          NULL,
                                          GTK_FILE_CHOOSER_ACTION_SAVE,
                                          "_Cancel", GTK_RESPONSE_CANCEL,
                                          "_Save", GTK_RESPONSE_ACCEPT,
                                          NULL );

    bool typeSpecified = true;
    if( strcmp(type,"*")==0 )
	{
		typeSpecified = false;
	}
	else
	{
    	AddFiltersToDialog(dialog, type);
    }

    /* Set the default path */
    if( currentSavePath != "none" )
    	SetDefaultPath(dialog, currentSavePath.c_str());
    else
    	SetDefaultPath(dialog, getCurrentDirectory().c_str());

    result = false;
    if ( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
    {
        char *filename;

        filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(dialog) );

        std::string res = filename;
        if(typeSpecified)
		{
			std::string suff = getFileExt(res);
			if( suff != type )
			{
				res = getPathWithoutExt(res) + "." + std::string(type);
			}
		}

		path = res;

       	currentSavePath = getDirectoryFromPath(path);

        g_free( filename );

        result = true;
    }

    WaitForCleanup();
    gtk_widget_destroy(dialog);
    WaitForCleanup();

    return result;
}

std::string  getExecutablePath()
{
	char buffer[PATH_MAX];

	char* path_end;
  	/* Read the target of /proc/self/exe.  */
  	if (readlink ("/proc/self/exe", buffer, PATH_MAX) <= 0)
    	return "";
  	/* Find the last occurence of a forward slash, the path separator.  */
 	path_end = strrchr (buffer, '/');
  	if (path_end == NULL)
    	return "";
 	 /* Advance to the character past the last slash.  */
  	++path_end;
	/* Obtain the directory containing the program by truncating the
	   path after the last slash.  */
	*path_end = '\0';
	/* The length of the path is the number of characters up through the
	 last slash.  */
	return std::string(buffer);
}

///////////////
// Gross filewatcher

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

FileWatcher::FileWatcher( const std::string & path, int msecs  )
:
fileFlags(0),
msecs(msecs)
{
  //http://man7.org/tlpi/code/online/diff/inotify/demo_inotify.c.html

    struct inotify_event *event;

    fd = inotify_init();                 /* Create inotify instance */
    if (fd == -1)
        assert(0);

    int wd = inotify_add_watch(fd, path.c_str(), IN_ALL_EVENTS ); //IN_ALL_EVENTS);

    Wd.push_back(wd);

    printf("Watching file: %s\n", path.c_str());
    //paths.push_back(path);

    running = true;
    thread = std::thread(&FileWatcher::run, this);
}

FileWatcher::~FileWatcher()
{
    stop();
    for( int i = 0; i < Wd.size(); i++ )
        inotify_rm_watch( fd, Wd[i] );
    close(fd);
    printf("Closed file watcher\n");
}

bool FileWatcher::hasFileChanged()
{
  bool res = fileFlags != 0;
  fileFlags = 0;
  return res;
}

static void             /* Display information from inotify_event structure */
 displayInotifyEvent(FileWatcher * watcher, struct inotify_event *i)
 {

     printf("    wd =%2d; ", i->wd);
     if (i->cookie > 0)
         printf("cookie =%4d; ", i->cookie);

     printf("mask = ");
     if (i->mask & IN_ACCESS)        printf("IN_ACCESS ");
     if (i->mask & IN_ATTRIB)        printf("IN_ATTRIB ");
     if (i->mask & IN_CLOSE_NOWRITE) printf("IN_CLOSE_NOWRITE ");
     if (i->mask & IN_CLOSE_WRITE)   printf("IN_CLOSE_WRITE ");
     if (i->mask & IN_CREATE)        printf("IN_CREATE ");
     if (i->mask & IN_DELETE)        printf("IN_DELETE ");
     if (i->mask & IN_DELETE_SELF)   printf("IN_DELETE_SELF ");
     if (i->mask & IN_IGNORED)       printf("IN_IGNORED ");
     if (i->mask & IN_ISDIR)         printf("IN_ISDIR ");
     if (i->mask & IN_MODIFY)        printf("IN_MODIFY ");
     if (i->mask & IN_MOVE_SELF)     printf("IN_MOVE_SELF ");
     if (i->mask & IN_MOVED_FROM)    printf("IN_MOVED_FROM ");
     if (i->mask & IN_MOVED_TO)      printf("IN_MOVED_TO ");
     if (i->mask & IN_OPEN)          printf("IN_OPEN ");
     if (i->mask & IN_Q_OVERFLOW)    printf("IN_Q_OVERFLOW ");
     if (i->mask & IN_UNMOUNT)       printf("IN_UNMOUNT ");
     printf("\n");

    if( i->len < 1 )
        return;

    printf("caz\n");

    std::string name = i->name;
    if( getFileExt(name) == "py" && getFilenameFromPath(name) != "tmp.py" )
    {
        printf("Modified file: %s\n", i->name);
        watcher->fileFlags = 1;
    }

 }

void FileWatcher::stop()
{
    if(running)
    {
        mutex.lock();
        printf("Joining thread\n");
        running = false;
        thread.join();
        printf("Stopped file watching thread\n");
        mutex.unlock();
    }
}

void FileWatcher::run()
{
  char *p;
  struct inotify_event *event;
  char buf[EVENT_BUF_LEN] __attribute__ ((aligned(8)));
  printf("Starting file watcher\n");

  while( running )
  {
        printf("Polling\n");
        //std::this_thread::sleep_for(std::chrono::milliseconds(200));

        //mutex.lock();
        struct pollfd pfd = { fd, POLLIN, 0 };
        int ret = poll(&pfd, 1, 1050);  // timeout of 50ms
        if (ret < 0) {
            fprintf(stderr, "poll failed: %s\n", strerror(errno));
        } else if (ret == 0) {
            printf("nothing from poll\n");
            continue;
        }

        int numRead = read(fd, buf, EVENT_BUF_LEN);

        if( numRead == 0 )
    {
        printf("nothing to read\n");
      continue;
    }
    else
    {
        printf("stuff\n");
    }
    for (p = buf; p < buf + numRead; ) {
             event = (struct inotify_event *) p;
             displayInotifyEvent(this, event);
         //fileFlags = 1;
             p += EVENT_SIZE + event->len;
         }
         //mutex.unlock();
         std::this_thread::sleep_for(std::chrono::milliseconds(10));

    //Thread::sleep(msecs);
  }

  printf("Exit loop\n");
}

}<|endoftext|>


<commit_before>/*
Copyright (c) 2017 InversePalindrome
Memento Mori - PauseState.cpp
InversePalindrome.com
*/

#include "PauseState.hpp"
#include "StateMachine.hpp"

#include <SFGUI/Image.hpp>

PauseState::PauseState(StateMachine& stateMachine, SharedData& sharedData) :
	State(stateMachine, sharedData),
	pauseMenu(sharedData.textures[Textures::ID::PauseMenu]),
	resumeButton(sfg::Button::Create()),
	restartButton(sfg::Button::Create()),
	settingsButton(sfg::Button::Create()),
	quitButton(sfg::Button::Create())
{
	pauseMenu.setPosition(sf::Vector2f(1020.f, 280.f));

	resumeButton->SetImage(sfg::Image::Create(sharedData.images[Images::ID::ResumeButton]));
	resumeButton->SetPosition(sf::Vector2f(1078.f, 428.f));
	resumeButton->GetSignal(sfg::Widget::OnLeftClick).Connect([this] { transitionToGame(); });

	restartButton->SetImage(sfg::Image::Create(sharedData.images[Images::ID::RestartButton]));
	restartButton->SetPosition(sf::Vector2f(1078.f, 578.f));
	restartButton->GetSignal(sfg::Widget::OnLeftClick).Connect([this] { restartGame(); });

	settingsButton->SetImage(sfg::Image::Create(sharedData.images[Images::ID::SettingsButton2]));
	settingsButton->SetPosition(sf::Vector2f(1078.f, 728.f));
	settingsButton->GetSignal(sfg::Widget::OnLeftClick).Connect([this] { transitionToSettings(); });

	quitButton->SetImage(sfg::Image::Create(sharedData.images[Images::ID::QuitButton]));
	quitButton->SetPosition(sf::Vector2f(1078.f, 878.f));
	quitButton->GetSignal(sfg::Widget::OnLeftClick).Connect([this] { transitionToMenu(); });

	sharedData.hud.Add(resumeButton);
	sharedData.hud.Add(restartButton);
	sharedData.hud.Add(settingsButton);
	sharedData.hud.Add(quitButton);
}

void PauseState::handleEvent(const sf::Event& event)
{

}

void PauseState::update(sf::Time deltaTime)
{
	this->resumeButton->Show(true);
	this->restartButton->Show(true);
	this->settingsButton->Show(true);
	this->quitButton->Show(true);
}

void PauseState::draw()
{
	this->sharedData.window.draw(this->pauseMenu);
}

bool PauseState::isTransparent()
{
	return true;
}

void PauseState::transitionToGame()
{
	this->resumeButton->Show(false);
	this->restartButton->Show(false);
	this->settingsButton->Show(false);
	this->quitButton->Show(false);

	this->stateMachine.popState();
}

void PauseState::restartGame()
{
	this->resumeButton->Show(false);
	this->restartButton->Show(false);
	this->settingsButton->Show(false);
	this->quitButton->Show(false);

	this->stateMachine.clearStates();
	this->stateMachine.pushState(StateMachine::StateID::Game);
}

void PauseState::transitionToSettings()
{
	this->resumeButton->Show(false);
	this->restartButton->Show(false);
	this->settingsButton->Show(false);
	this->quitButton->Show(false);

	this->stateMachine.pushState(StateMachine::StateID::Settings);
}

void PauseState::transitionToMenu()
{
	this->resumeButton->Show(false);
	this->restartButton->Show(false);
	this->settingsButton->Show(false);
	this->quitButton->Show(false);

	this->stateMachine.clearStates();
	this->stateMachine.pushState(StateMachine::StateID::Menu);
}<commit_msg>Delete PauseState.cpp<commit_after><|endoftext|>


<commit_before>#include "AudioDevice.h"

extern "C" {
#include "gba.h"
#include "gba-audio.h"
#include "gba-thread.h"
}

using namespace QGBA;

AudioDevice::AudioDevice(QObject* parent)
	: QIODevice(parent)
	, m_context(nullptr)
{
	setOpenMode(ReadOnly);
}

void AudioDevice::setFormat(const QAudioFormat& format) {
	if (!GBAThreadHasStarted(m_context)) {
		return;
	}
	GBAThreadInterrupt(m_context);
	m_ratio = GBAAudioCalculateRatio(&m_context->gba->audio, m_context->fpsTarget, format.sampleRate());
	GBAThreadContinue(m_context);
}

void AudioDevice::setInput(GBAThread* input) {
	m_context = input;
}

qint64 AudioDevice::readData(char* data, qint64 maxSize) {
	if (maxSize > 0xFFFFFFFF) {
		maxSize = 0xFFFFFFFF;
	}

	if (!m_context->gba) {
		return 0;
	}

	return GBAAudioResampleNN(&m_context->gba->audio, m_ratio, &m_drift, reinterpret_cast<GBAStereoSample*>(data), maxSize / sizeof(GBAStereoSample)) * sizeof(GBAStereoSample);
}

qint64 AudioDevice::writeData(const char*, qint64) {
	return 0;
}
<commit_msg>Initialize audio drift<commit_after>#include "AudioDevice.h"

extern "C" {
#include "gba.h"
#include "gba-audio.h"
#include "gba-thread.h"
}

using namespace QGBA;

AudioDevice::AudioDevice(QObject* parent)
	: QIODevice(parent)
	, m_context(nullptr)
	, m_drift(0)
{
	setOpenMode(ReadOnly);
}

void AudioDevice::setFormat(const QAudioFormat& format) {
	if (!GBAThreadHasStarted(m_context)) {
		return;
	}
	GBAThreadInterrupt(m_context);
	m_ratio = GBAAudioCalculateRatio(&m_context->gba->audio, m_context->fpsTarget, format.sampleRate());
	GBAThreadContinue(m_context);
}

void AudioDevice::setInput(GBAThread* input) {
	m_context = input;
}

qint64 AudioDevice::readData(char* data, qint64 maxSize) {
	if (maxSize > 0xFFFFFFFF) {
		maxSize = 0xFFFFFFFF;
	}

	if (!m_context->gba) {
		return 0;
	}

	return GBAAudioResampleNN(&m_context->gba->audio, m_ratio, &m_drift, reinterpret_cast<GBAStereoSample*>(data), maxSize / sizeof(GBAStereoSample)) * sizeof(GBAStereoSample);
}

qint64 AudioDevice::writeData(const char*, qint64) {
	return 0;
}
<|endoftext|>


<commit_before>#include "acmacs-base/argv.hh"
// #include "acmacs-base/range-v3.hh"
#include "acmacs-base/enumerate.hh"
#include "acmacs-base/string-join.hh"
#include "acmacs-chart-2/factory-import.hh"
#include "acmacs-chart-2/chart.hh"
#include "hidb-5/hidb-set.hh"
#include "hidb-5/hidb.hh"
#include "acmacs-whocc/log.hh"

// ----------------------------------------------------------------------

using namespace acmacs::argv;
struct Options : public argv
{
    Options(int a_argc, const char* const a_argv[], on_error on_err = on_error::exit) : argv() { parse(a_argc, a_argv, on_err); }

    option<str_array> verbose{*this, 'v', "verbose", desc{"comma separated list (or multiple switches) of log enablers"}};

    argument<str_array> tables{*this, arg_name{".ace"}, mandatory};
};

int main(int argc, char* const argv[])
{
    using namespace std::string_view_literals;
    int exit_code = 0;
    try {
        Options opt(argc, argv);
        acmacs::log::enable(opt.verbose);

        for (const auto& filename : *opt.tables) {
            auto chart = acmacs::chart::import_from_file(filename);
            AD_INFO("{}", chart->make_name());
            const auto& hidb = hidb::get(chart->info()->virus_type(acmacs::chart::Info::Compute::Yes));
            auto tables = hidb.tables();

            auto antigens = chart->antigens();
            for (auto [ag_no, antigen] : acmacs::enumerate(*antigens)) {
                if (!antigen->distinct()) {
                    const auto hidb_antigens = hidb.antigens()->find(antigen->name(), hidb::fix_location::no);
                    if (!hidb_antigens.empty()) {
                        const auto full_name = antigen->full_name();
                        fmt::print("AG {:3d} \"{}\"\n", ag_no, full_name);
                        std::vector<std::pair<std::string, fmt::memory_buffer>> hidb_variants;
                        bool full_name_match_present{false};
                        for (const auto& [hidb_antigen, hidb_index] : hidb_antigens) {
                            auto hidb_antigen_full_name =
                                acmacs::string::join(acmacs::string::join_space, hidb_antigen->name(), acmacs::string::join(acmacs::string::join_space, hidb_antigen->annotations()),
                                                     hidb_antigen->reassortant(), hidb_antigen->passage());
                            full_name_match_present |= hidb_antigen_full_name == full_name;
                            auto& variant = hidb_variants.emplace_back(std::move(hidb_antigen_full_name), fmt::memory_buffer{});
                            const auto by_lab_assay = hidb.tables(*hidb_antigen, hidb::lab_assay_table_t::recent_first);
                            for (auto entry : by_lab_assay) {
                                fmt::format_to(variant.second, "        {}:{} ({})", entry.lab, entry.assay, entry.tables.size());
                                for (auto table : entry.tables)
                                    fmt::format_to(variant.second, " {}{}", table->date(), entry.assay); // rbc(entry.assay, table->rbc()));
                                fmt::format_to(variant.second, "\n");
                            }
                        }
                        std::sort(std::begin(hidb_variants), std::end(hidb_variants), [&full_name](const auto& e1, const auto& e2) {
                            const auto f1 = e1.first == full_name, f2 = e2.first == full_name;
                            if (f1 && !f2)
                                return true;
                            else if (!f1 && f2)
                                return false;
                            else
                                return e1.first < e2.first;
                        });
                        if (!full_name_match_present)
                            hidb_variants.emplace(hidb_variants.begin(), "*** New ***", fmt::memory_buffer{});
                        for (const auto& variant : hidb_variants)
                            fmt::print("    {}\n{}", variant.first, fmt::to_string(variant.second));
                    }
                }
            }
        }
    }
    catch (std::exception& err) {
        AD_ERROR("{}", err);
        exit_code = 2;
    }
    return exit_code;
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>whocc-check-new-tables<commit_after>#include "acmacs-base/argv.hh"
// #include "acmacs-base/range-v3.hh"
#include "acmacs-base/enumerate.hh"
#include "acmacs-base/string-join.hh"
#include "acmacs-chart-2/factory-import.hh"
#include "acmacs-chart-2/chart.hh"
#include "hidb-5/hidb-set.hh"
#include "hidb-5/hidb.hh"
#include "acmacs-whocc/log.hh"

// ----------------------------------------------------------------------

using namespace acmacs::argv;
struct Options : public argv
{
    Options(int a_argc, const char* const a_argv[], on_error on_err = on_error::exit) : argv() { parse(a_argc, a_argv, on_err); }

    option<str_array> verbose{*this, 'v', "verbose", desc{"comma separated list (or multiple switches) of log enablers"}};

    argument<str_array> tables{*this, arg_name{".ace"}, mandatory};
};

int main(int argc, char* const argv[])
{
    using namespace std::string_view_literals;
    int exit_code = 0;
    try {
        Options opt(argc, argv);
        acmacs::log::enable(opt.verbose);

        for (const auto& filename : *opt.tables) {
            auto chart = acmacs::chart::import_from_file(filename);
            AD_INFO("{}", chart->make_name());
            const auto& hidb = hidb::get(chart->info()->virus_type(acmacs::chart::Info::Compute::Yes));
            auto tables = hidb.tables();

            auto antigens = chart->antigens();
            for (auto [ag_no, antigen] : acmacs::enumerate(*antigens)) {
                if (!antigen->distinct()) {
                    const auto hidb_antigens = hidb.antigens()->find(antigen->name(), hidb::fix_location::no);
                    if (!hidb_antigens.empty()) {
                        const auto full_name = antigen->full_name();
                        fmt::print("AG {:3d} \"{}\"\n", ag_no, full_name);
                        std::vector<std::pair<std::string, fmt::memory_buffer>> hidb_variants;
                        bool full_name_match_present{false};
                        for (const auto& [hidb_antigen, hidb_index] : hidb_antigens) {
                            auto hidb_antigen_full_name =
                                acmacs::string::join(acmacs::string::join_space, hidb_antigen->name(), acmacs::string::join(acmacs::string::join_space, hidb_antigen->annotations()),
                                                     hidb_antigen->reassortant(), hidb_antigen->passage());
                            full_name_match_present |= hidb_antigen_full_name == full_name;
                            auto& variant = hidb_variants.emplace_back(std::move(hidb_antigen_full_name), fmt::memory_buffer{});
                            const auto by_lab_assay = hidb.tables(*hidb_antigen, hidb::lab_assay_rbc_table_t::recent_first);
                            for (auto entry : by_lab_assay) {
                                fmt::format_to(variant.second, "        [{} {} {}] ({})", entry.lab, entry.assay, entry.rbc, entry.tables.size());
                                for (auto table : entry.tables)
                                    fmt::format_to(variant.second, " {}", table->date());
                                fmt::format_to(variant.second, "\n");
                            }
                        }
                        std::sort(std::begin(hidb_variants), std::end(hidb_variants), [&full_name](const auto& e1, const auto& e2) {
                            const auto f1 = e1.first == full_name, f2 = e2.first == full_name;
                            if (f1 && !f2)
                                return true;
                            else if (!f1 && f2)
                                return false;
                            else
                                return e1.first < e2.first;
                        });
                        if (!full_name_match_present)
                            hidb_variants.emplace(hidb_variants.begin(), "*** New ***", fmt::memory_buffer{});
                        for (const auto& variant : hidb_variants)
                            fmt::print("    {}\n{}", variant.first, fmt::to_string(variant.second));
                    }
                }
            }
        }
    }
    catch (std::exception& err) {
        AD_ERROR("{}", err);
        exit_code = 2;
    }
    return exit_code;
}

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "lxqtgridlayout.h"
#include <QDebug>
#include <math.h>
#include <QWidget>
#include <QVariantAnimation>

using namespace LXQt;

namespace
{
    class ItemMoveAnimation : public QVariantAnimation
    {
    public:
        static void animate(QLayoutItem * item, QRect const & geometry)
        {
            ItemMoveAnimation* animation = new ItemMoveAnimation(item);
            animation->setStartValue(item->geometry());
            animation->setEndValue(geometry);
            animation->start(DeleteWhenStopped);
        }

        ItemMoveAnimation(QLayoutItem *item)
            : mItem(item)
        {
            setEasingCurve(QEasingCurve::OutBack);
            setDuration(250);
        }

        void updateCurrentValue(const QVariant &current)
        {
            mItem->setGeometry(current.toRect());
        }

    private:
        QLayoutItem* mItem;

    };
}

class LXQt::GridLayoutPrivate
{
public:
    GridLayoutPrivate();

    QList<QLayoutItem*> mItems;
    int mRowCount;
    int mColumnCount;
    GridLayout::Direction mDirection;

    bool mIsValid;
    QSize mCellSizeHint;
    QSize mCellMaxSize;
    int mVisibleCount;
    GridLayout::Stretch mStretch;
    bool mAnimate;

    void updateCache();
    int rows() const;
    int cols() const;
    void setItemGeometry(QLayoutItem * item, QRect const & geometry);
    QSize mPrefCellMinSize;
    QSize mPrefCellMaxSize;
    QRect mOccupiedGeometry;
};

/************************************************

 ************************************************/
GridLayoutPrivate::GridLayoutPrivate()
{
    mColumnCount = 0;
    mRowCount = 0;
    mDirection = GridLayout::LeftToRight;
    mIsValid = false;
    mVisibleCount = 0;
    mStretch = GridLayout::StretchHorizontal | GridLayout::StretchVertical;
    mAnimate = false;
    mPrefCellMinSize = QSize(0,0);
    mPrefCellMaxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
}

/************************************************

 ************************************************/
void GridLayoutPrivate::updateCache()
{
    mCellSizeHint = QSize(0, 0);
    mCellMaxSize = QSize(0, 0);
    mVisibleCount = 0;

    for (int i=0; i<mItems.count(); ++i)
    {
        QLayoutItem *item = mItems.at(i);
        if (!item->widget() || item->widget()->isHidden())
            continue;

        int h = qBound(item->minimumSize().height(),
                       item->sizeHint().height(),
                       item->maximumSize().height());

        int w = qBound(item->minimumSize().width(),
                       item->sizeHint().width(),
                       item->maximumSize().width());

        mCellSizeHint.rheight() = qMax(mCellSizeHint.height(), h);
        mCellSizeHint.rwidth()  = qMax(mCellSizeHint.width(), w);

        mCellMaxSize.rheight() = qMax(mCellMaxSize.height(), item->maximumSize().height());
        mCellMaxSize.rwidth()  = qMax(mCellMaxSize.width(), item->maximumSize().width());
        mVisibleCount++;

#if 0
        qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
        qDebug() << "item.min" << item->minimumSize().width();
        qDebug() << "item.sz " << item->sizeHint().width();
        qDebug() << "item.max" << item->maximumSize().width();
        qDebug() << "w h" << w << h;
        qDebug() << "wid.sizeHint" << item->widget()->sizeHint();
        qDebug() << "mCellSizeHint:" << mCellSizeHint;
        qDebug() << "mCellMaxSize: " << mCellMaxSize;
        qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
#endif

    }
    mCellSizeHint.rwidth() = qBound(mPrefCellMinSize.width(),  mCellSizeHint.width(),  mPrefCellMaxSize.width());
    mCellSizeHint.rheight()= qBound(mPrefCellMinSize.height(), mCellSizeHint.height(), mPrefCellMaxSize.height());
    mIsValid = !mCellSizeHint.isEmpty();
}

/************************************************

 ************************************************/
int GridLayoutPrivate::rows() const
{
    if (mRowCount)
        return mRowCount;

    if (!mColumnCount)
        return 1;

    return ceil(mVisibleCount * 1.0 / mColumnCount);
}

/************************************************

 ************************************************/
int GridLayoutPrivate::cols() const
{
    if (mColumnCount)
        return mColumnCount;

    int rows = mRowCount;
    if (!rows)
        rows = 1;

    return ceil(mVisibleCount * 1.0 / rows);
}

void GridLayoutPrivate::setItemGeometry(QLayoutItem * item, QRect const & geometry)
{
    mOccupiedGeometry |= geometry;
    if (mAnimate)
    {
        ItemMoveAnimation::animate(item, geometry);
    } else
    {
        item->setGeometry(geometry);
    }
}

/************************************************

 ************************************************/
GridLayout::GridLayout(QWidget *parent):
    QLayout(parent),
    d_ptr(new GridLayoutPrivate())
{
}

/************************************************

 ************************************************/
GridLayout::~GridLayout()
{
    delete d_ptr;
}

/************************************************

 ************************************************/
void GridLayout::addItem(QLayoutItem *item)
{
    d_ptr->mItems.append(item);
}

/************************************************

 ************************************************/
QLayoutItem *GridLayout::itemAt(int index) const
{
    Q_D(const GridLayout);
    if (index < 0 || index >= d->mItems.count())
        return 0;

    return d->mItems.at(index);
}

/************************************************

 ************************************************/
QLayoutItem *GridLayout::takeAt(int index)
{
    Q_D(GridLayout);
    if (index < 0 || index >= d->mItems.count())
        return 0;

    QLayoutItem *item = d->mItems.takeAt(index);
    return item;
}

/************************************************

 ************************************************/
int GridLayout::count() const
{
    Q_D(const GridLayout);
    return d->mItems.count();
}

/************************************************

 ************************************************/
void GridLayout::invalidate()
{
    Q_D(GridLayout);
    d->mIsValid = false;
    QLayout::invalidate();
}

/************************************************

 ************************************************/
int GridLayout::rowCount() const
{
    Q_D(const GridLayout);
    return d->mRowCount;
}

/************************************************

 ************************************************/
void GridLayout::setRowCount(int value)
{
    Q_D(GridLayout);
    if (d->mRowCount != value)
    {
        d->mRowCount = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
int GridLayout::columnCount() const
{
    Q_D(const GridLayout);
    return d->mColumnCount;
}

/************************************************

 ************************************************/
void GridLayout::setColumnCount(int value)
{
    Q_D(GridLayout);
    if (d->mColumnCount != value)
    {
        d->mColumnCount = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
GridLayout::Direction GridLayout::direction() const
{
    Q_D(const GridLayout);
    return d->mDirection;
}

/************************************************

 ************************************************/
void GridLayout::setDirection(GridLayout::Direction value)
{
    Q_D(GridLayout);
    if (d->mDirection != value)
    {
        d->mDirection = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
GridLayout::Stretch GridLayout::stretch() const
{
    Q_D(const GridLayout);
    return d->mStretch;
}

/************************************************

 ************************************************/
void GridLayout::setStretch(Stretch value)
{
    Q_D(GridLayout);
    if (d->mStretch != value)
    {
        d->mStretch = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::moveItem(int from, int to, bool withAnimation /*= false*/)
{
    Q_D(GridLayout);
    d->mAnimate = withAnimation;
    d->mItems.move(from, to);
    invalidate();
}

/************************************************

 ************************************************/
QSize GridLayout::cellMinimumSize() const
{
    Q_D(const GridLayout);
    return d->mPrefCellMinSize;
}

/************************************************

 ************************************************/
void GridLayout::setCellMinimumSize(QSize minSize)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize != minSize)
    {
        d->mPrefCellMinSize = minSize;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMinimumHeight(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.height() != value)
    {
        d->mPrefCellMinSize.setHeight(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMinimumWidth(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.width() != value)
    {
        d->mPrefCellMinSize.setWidth(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
QSize GridLayout::cellMaximumSize() const
{
    Q_D(const GridLayout);
    return d->mPrefCellMaxSize;
}

/************************************************

 ************************************************/
void GridLayout::setCellMaximumSize(QSize maxSize)
{
    Q_D(GridLayout);
    if (d->mPrefCellMaxSize != maxSize)
    {
        d->mPrefCellMaxSize = maxSize;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMaximumHeight(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMaxSize.height() != value)
    {
        d->mPrefCellMaxSize.setHeight(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMaximumWidth(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMaxSize.width() != value)
    {
        d->mPrefCellMaxSize.setWidth(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellFixedSize(QSize size)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize != size ||
        d->mPrefCellMaxSize != size)
    {
        d->mPrefCellMinSize = size;
        d->mPrefCellMaxSize = size;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellFixedHeight(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.height() != value ||
        d->mPrefCellMaxSize.height() != value)
    {
        d->mPrefCellMinSize.setHeight(value);
        d->mPrefCellMaxSize.setHeight(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellFixedWidth(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.width() != value ||
        d->mPrefCellMaxSize.width() != value)
    {
        d->mPrefCellMinSize.setWidth(value);
        d->mPrefCellMaxSize.setWidth(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
QSize GridLayout::sizeHint() const
{
    Q_D(const GridLayout);

    if (!d->mIsValid)
        const_cast<GridLayoutPrivate*>(d)->updateCache();

    return QSize(d->cols() * d->mCellSizeHint.width(),
                 d->rows() * d->mCellSizeHint.height());
}

/************************************************

 ************************************************/
void GridLayout::setGeometry(const QRect &geometry)
{
    Q_D(GridLayout);

    QLayout::setGeometry(geometry);
    d->mOccupiedGeometry.setTopLeft(geometry.topLeft());
    d->mOccupiedGeometry.setBottomRight(geometry.topLeft());

    if (!d->mIsValid)
        d->updateCache();

    int y = geometry.top();
    int x = geometry.left();

    // For historical reasons QRect::right returns left() + width() - 1
    // and QRect::bottom() returns top() + height() - 1;
    // So we use left() + height() and top() + height()
    //
    // http://qt-project.org/doc/qt-4.8/qrect.html

    const int maxX = geometry.left() + geometry.width();
    const int maxY = geometry.top() + geometry.height();

    const bool stretch_h = d->mStretch.testFlag(StretchHorizontal);
    const bool stretch_v = d->mStretch.testFlag(StretchVertical);

    const int cols = d->cols();
    int itemWidth = 0;
    if (stretch_h && 0 < cols)
        itemWidth = qMin(geometry.width() / cols, d->mCellMaxSize.width());
    else
        itemWidth = d->mCellSizeHint.width();
    itemWidth = qBound(qMin(d->mPrefCellMinSize.width(), maxX), itemWidth, d->mPrefCellMaxSize.width());
    const int widthRemain = stretch_h && 0 < itemWidth ? geometry.width() % itemWidth : 0;

    const int rows = d->rows();
    int itemHeight = 0;
    if (stretch_v && 0 < rows)
        itemHeight = qMin(geometry.height() / rows, d->mCellMaxSize.height());
    else
        itemHeight = d->mCellSizeHint.height();
    itemHeight = qBound(qMin(d->mPrefCellMinSize.height(), maxY), itemHeight, d->mPrefCellMaxSize.height());
    const int heightRemain = stretch_v && 0 < itemHeight ? geometry.height() % itemHeight : 0;

#if 0
    qDebug() << "** GridLayout::setGeometry *******************************";
    qDebug() << "Geometry:" << geometry;
    qDebug() << "CellSize:" << d->mCellSizeHint;
    qDebug() << "Constraints:" << "min" << d->mPrefCellMinSize << "max" << d->mPrefCellMaxSize;
    qDebug() << "Count" << count();
    qDebug() << "Cols:" << d->cols() << "(" << d->mColumnCount << ")";
    qDebug() << "Rows:" << d->rows() << "(" << d->mRowCount << ")";
    qDebug() << "Stretch:" << "h:" << (d->mStretch.testFlag(StretchHorizontal)) << " v:" << (d->mStretch.testFlag(StretchVertical));
    qDebug() << "Item:" << "h:" << itemHeight << " w:" << itemWidth;
#endif

    int remain_height = heightRemain;
    int remain_width = widthRemain;
    if (d->mDirection == LeftToRight)
    {
        int height = itemHeight + (0 < remain_height-- ? 1 : 0);
        foreach(QLayoutItem *item, d->mItems)
        {
            if (!item->widget() || item->widget()->isHidden())
                continue;
            int width = itemWidth + (0 < remain_width-- ? 1 : 0);

            if (x + width > maxX)
            {
                x = geometry.left();
                y += height;

                height = itemHeight + (0 < remain_height-- ? 1 : 0);
                remain_width = widthRemain;
            }

            d->setItemGeometry(item, QRect(x, y, width, height));
            x += width;
        }
    }
    else
    {
        int width = itemWidth + (0 < remain_width-- ? 1 : 0);
        foreach(QLayoutItem *item, d->mItems)
        {
            if (!item->widget() || item->widget()->isHidden())
                continue;
            int height = itemHeight + (0 < remain_height-- ? 1 : 0);

            if (y + height > maxY)
            {
                y = geometry.top();
                x += width;

                width = itemWidth + (0 < remain_width-- ? 1 : 0);
                remain_height = heightRemain;
            }
            d->setItemGeometry(item, QRect(x, y, width, height));
            y += height;
        }
    }
    d->mAnimate = false;
}

/************************************************

 ************************************************/
QRect GridLayout::occupiedGeometry() const
{
    return d_func()->mOccupiedGeometry;
}
<commit_msg>gridlayout: Use linear animation<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXQt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "lxqtgridlayout.h"
#include <QDebug>
#include <math.h>
#include <QWidget>
#include <QVariantAnimation>

using namespace LXQt;

namespace
{
    class ItemMoveAnimation : public QVariantAnimation
    {
    public:
        static void animate(QLayoutItem * item, QRect const & geometry)
        {
            ItemMoveAnimation* animation = new ItemMoveAnimation(item);
            animation->setStartValue(item->geometry());
            animation->setEndValue(geometry);
            animation->start(DeleteWhenStopped);
        }

        ItemMoveAnimation(QLayoutItem *item)
            : mItem(item)
        {
            setDuration(150);
        }

        void updateCurrentValue(const QVariant &current)
        {
            mItem->setGeometry(current.toRect());
        }

    private:
        QLayoutItem* mItem;

    };
}

class LXQt::GridLayoutPrivate
{
public:
    GridLayoutPrivate();

    QList<QLayoutItem*> mItems;
    int mRowCount;
    int mColumnCount;
    GridLayout::Direction mDirection;

    bool mIsValid;
    QSize mCellSizeHint;
    QSize mCellMaxSize;
    int mVisibleCount;
    GridLayout::Stretch mStretch;
    bool mAnimate;

    void updateCache();
    int rows() const;
    int cols() const;
    void setItemGeometry(QLayoutItem * item, QRect const & geometry);
    QSize mPrefCellMinSize;
    QSize mPrefCellMaxSize;
    QRect mOccupiedGeometry;
};

/************************************************

 ************************************************/
GridLayoutPrivate::GridLayoutPrivate()
{
    mColumnCount = 0;
    mRowCount = 0;
    mDirection = GridLayout::LeftToRight;
    mIsValid = false;
    mVisibleCount = 0;
    mStretch = GridLayout::StretchHorizontal | GridLayout::StretchVertical;
    mAnimate = false;
    mPrefCellMinSize = QSize(0,0);
    mPrefCellMaxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
}

/************************************************

 ************************************************/
void GridLayoutPrivate::updateCache()
{
    mCellSizeHint = QSize(0, 0);
    mCellMaxSize = QSize(0, 0);
    mVisibleCount = 0;

    for (int i=0; i<mItems.count(); ++i)
    {
        QLayoutItem *item = mItems.at(i);
        if (!item->widget() || item->widget()->isHidden())
            continue;

        int h = qBound(item->minimumSize().height(),
                       item->sizeHint().height(),
                       item->maximumSize().height());

        int w = qBound(item->minimumSize().width(),
                       item->sizeHint().width(),
                       item->maximumSize().width());

        mCellSizeHint.rheight() = qMax(mCellSizeHint.height(), h);
        mCellSizeHint.rwidth()  = qMax(mCellSizeHint.width(), w);

        mCellMaxSize.rheight() = qMax(mCellMaxSize.height(), item->maximumSize().height());
        mCellMaxSize.rwidth()  = qMax(mCellMaxSize.width(), item->maximumSize().width());
        mVisibleCount++;

#if 0
        qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
        qDebug() << "item.min" << item->minimumSize().width();
        qDebug() << "item.sz " << item->sizeHint().width();
        qDebug() << "item.max" << item->maximumSize().width();
        qDebug() << "w h" << w << h;
        qDebug() << "wid.sizeHint" << item->widget()->sizeHint();
        qDebug() << "mCellSizeHint:" << mCellSizeHint;
        qDebug() << "mCellMaxSize: " << mCellMaxSize;
        qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
#endif

    }
    mCellSizeHint.rwidth() = qBound(mPrefCellMinSize.width(),  mCellSizeHint.width(),  mPrefCellMaxSize.width());
    mCellSizeHint.rheight()= qBound(mPrefCellMinSize.height(), mCellSizeHint.height(), mPrefCellMaxSize.height());
    mIsValid = !mCellSizeHint.isEmpty();
}

/************************************************

 ************************************************/
int GridLayoutPrivate::rows() const
{
    if (mRowCount)
        return mRowCount;

    if (!mColumnCount)
        return 1;

    return ceil(mVisibleCount * 1.0 / mColumnCount);
}

/************************************************

 ************************************************/
int GridLayoutPrivate::cols() const
{
    if (mColumnCount)
        return mColumnCount;

    int rows = mRowCount;
    if (!rows)
        rows = 1;

    return ceil(mVisibleCount * 1.0 / rows);
}

void GridLayoutPrivate::setItemGeometry(QLayoutItem * item, QRect const & geometry)
{
    mOccupiedGeometry |= geometry;
    if (mAnimate)
    {
        ItemMoveAnimation::animate(item, geometry);
    } else
    {
        item->setGeometry(geometry);
    }
}

/************************************************

 ************************************************/
GridLayout::GridLayout(QWidget *parent):
    QLayout(parent),
    d_ptr(new GridLayoutPrivate())
{
}

/************************************************

 ************************************************/
GridLayout::~GridLayout()
{
    delete d_ptr;
}

/************************************************

 ************************************************/
void GridLayout::addItem(QLayoutItem *item)
{
    d_ptr->mItems.append(item);
}

/************************************************

 ************************************************/
QLayoutItem *GridLayout::itemAt(int index) const
{
    Q_D(const GridLayout);
    if (index < 0 || index >= d->mItems.count())
        return 0;

    return d->mItems.at(index);
}

/************************************************

 ************************************************/
QLayoutItem *GridLayout::takeAt(int index)
{
    Q_D(GridLayout);
    if (index < 0 || index >= d->mItems.count())
        return 0;

    QLayoutItem *item = d->mItems.takeAt(index);
    return item;
}

/************************************************

 ************************************************/
int GridLayout::count() const
{
    Q_D(const GridLayout);
    return d->mItems.count();
}

/************************************************

 ************************************************/
void GridLayout::invalidate()
{
    Q_D(GridLayout);
    d->mIsValid = false;
    QLayout::invalidate();
}

/************************************************

 ************************************************/
int GridLayout::rowCount() const
{
    Q_D(const GridLayout);
    return d->mRowCount;
}

/************************************************

 ************************************************/
void GridLayout::setRowCount(int value)
{
    Q_D(GridLayout);
    if (d->mRowCount != value)
    {
        d->mRowCount = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
int GridLayout::columnCount() const
{
    Q_D(const GridLayout);
    return d->mColumnCount;
}

/************************************************

 ************************************************/
void GridLayout::setColumnCount(int value)
{
    Q_D(GridLayout);
    if (d->mColumnCount != value)
    {
        d->mColumnCount = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
GridLayout::Direction GridLayout::direction() const
{
    Q_D(const GridLayout);
    return d->mDirection;
}

/************************************************

 ************************************************/
void GridLayout::setDirection(GridLayout::Direction value)
{
    Q_D(GridLayout);
    if (d->mDirection != value)
    {
        d->mDirection = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
GridLayout::Stretch GridLayout::stretch() const
{
    Q_D(const GridLayout);
    return d->mStretch;
}

/************************************************

 ************************************************/
void GridLayout::setStretch(Stretch value)
{
    Q_D(GridLayout);
    if (d->mStretch != value)
    {
        d->mStretch = value;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::moveItem(int from, int to, bool withAnimation /*= false*/)
{
    Q_D(GridLayout);
    d->mAnimate = withAnimation;
    d->mItems.move(from, to);
    invalidate();
}

/************************************************

 ************************************************/
QSize GridLayout::cellMinimumSize() const
{
    Q_D(const GridLayout);
    return d->mPrefCellMinSize;
}

/************************************************

 ************************************************/
void GridLayout::setCellMinimumSize(QSize minSize)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize != minSize)
    {
        d->mPrefCellMinSize = minSize;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMinimumHeight(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.height() != value)
    {
        d->mPrefCellMinSize.setHeight(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMinimumWidth(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.width() != value)
    {
        d->mPrefCellMinSize.setWidth(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
QSize GridLayout::cellMaximumSize() const
{
    Q_D(const GridLayout);
    return d->mPrefCellMaxSize;
}

/************************************************

 ************************************************/
void GridLayout::setCellMaximumSize(QSize maxSize)
{
    Q_D(GridLayout);
    if (d->mPrefCellMaxSize != maxSize)
    {
        d->mPrefCellMaxSize = maxSize;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMaximumHeight(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMaxSize.height() != value)
    {
        d->mPrefCellMaxSize.setHeight(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellMaximumWidth(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMaxSize.width() != value)
    {
        d->mPrefCellMaxSize.setWidth(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellFixedSize(QSize size)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize != size ||
        d->mPrefCellMaxSize != size)
    {
        d->mPrefCellMinSize = size;
        d->mPrefCellMaxSize = size;
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellFixedHeight(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.height() != value ||
        d->mPrefCellMaxSize.height() != value)
    {
        d->mPrefCellMinSize.setHeight(value);
        d->mPrefCellMaxSize.setHeight(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
void GridLayout::setCellFixedWidth(int value)
{
    Q_D(GridLayout);
    if (d->mPrefCellMinSize.width() != value ||
        d->mPrefCellMaxSize.width() != value)
    {
        d->mPrefCellMinSize.setWidth(value);
        d->mPrefCellMaxSize.setWidth(value);
        invalidate();
    }
}

/************************************************

 ************************************************/
QSize GridLayout::sizeHint() const
{
    Q_D(const GridLayout);

    if (!d->mIsValid)
        const_cast<GridLayoutPrivate*>(d)->updateCache();

    return QSize(d->cols() * d->mCellSizeHint.width(),
                 d->rows() * d->mCellSizeHint.height());
}

/************************************************

 ************************************************/
void GridLayout::setGeometry(const QRect &geometry)
{
    Q_D(GridLayout);

    QLayout::setGeometry(geometry);
    d->mOccupiedGeometry.setTopLeft(geometry.topLeft());
    d->mOccupiedGeometry.setBottomRight(geometry.topLeft());

    if (!d->mIsValid)
        d->updateCache();

    int y = geometry.top();
    int x = geometry.left();

    // For historical reasons QRect::right returns left() + width() - 1
    // and QRect::bottom() returns top() + height() - 1;
    // So we use left() + height() and top() + height()
    //
    // http://qt-project.org/doc/qt-4.8/qrect.html

    const int maxX = geometry.left() + geometry.width();
    const int maxY = geometry.top() + geometry.height();

    const bool stretch_h = d->mStretch.testFlag(StretchHorizontal);
    const bool stretch_v = d->mStretch.testFlag(StretchVertical);

    const int cols = d->cols();
    int itemWidth = 0;
    if (stretch_h && 0 < cols)
        itemWidth = qMin(geometry.width() / cols, d->mCellMaxSize.width());
    else
        itemWidth = d->mCellSizeHint.width();
    itemWidth = qBound(qMin(d->mPrefCellMinSize.width(), maxX), itemWidth, d->mPrefCellMaxSize.width());
    const int widthRemain = stretch_h && 0 < itemWidth ? geometry.width() % itemWidth : 0;

    const int rows = d->rows();
    int itemHeight = 0;
    if (stretch_v && 0 < rows)
        itemHeight = qMin(geometry.height() / rows, d->mCellMaxSize.height());
    else
        itemHeight = d->mCellSizeHint.height();
    itemHeight = qBound(qMin(d->mPrefCellMinSize.height(), maxY), itemHeight, d->mPrefCellMaxSize.height());
    const int heightRemain = stretch_v && 0 < itemHeight ? geometry.height() % itemHeight : 0;

#if 0
    qDebug() << "** GridLayout::setGeometry *******************************";
    qDebug() << "Geometry:" << geometry;
    qDebug() << "CellSize:" << d->mCellSizeHint;
    qDebug() << "Constraints:" << "min" << d->mPrefCellMinSize << "max" << d->mPrefCellMaxSize;
    qDebug() << "Count" << count();
    qDebug() << "Cols:" << d->cols() << "(" << d->mColumnCount << ")";
    qDebug() << "Rows:" << d->rows() << "(" << d->mRowCount << ")";
    qDebug() << "Stretch:" << "h:" << (d->mStretch.testFlag(StretchHorizontal)) << " v:" << (d->mStretch.testFlag(StretchVertical));
    qDebug() << "Item:" << "h:" << itemHeight << " w:" << itemWidth;
#endif

    int remain_height = heightRemain;
    int remain_width = widthRemain;
    if (d->mDirection == LeftToRight)
    {
        int height = itemHeight + (0 < remain_height-- ? 1 : 0);
        foreach(QLayoutItem *item, d->mItems)
        {
            if (!item->widget() || item->widget()->isHidden())
                continue;
            int width = itemWidth + (0 < remain_width-- ? 1 : 0);

            if (x + width > maxX)
            {
                x = geometry.left();
                y += height;

                height = itemHeight + (0 < remain_height-- ? 1 : 0);
                remain_width = widthRemain;
            }

            d->setItemGeometry(item, QRect(x, y, width, height));
            x += width;
        }
    }
    else
    {
        int width = itemWidth + (0 < remain_width-- ? 1 : 0);
        foreach(QLayoutItem *item, d->mItems)
        {
            if (!item->widget() || item->widget()->isHidden())
                continue;
            int height = itemHeight + (0 < remain_height-- ? 1 : 0);

            if (y + height > maxY)
            {
                y = geometry.top();
                x += width;

                width = itemWidth + (0 < remain_width-- ? 1 : 0);
                remain_height = heightRemain;
            }
            d->setItemGeometry(item, QRect(x, y, width, height));
            y += height;
        }
    }
    d->mAnimate = false;
}

/************************************************

 ************************************************/
QRect GridLayout::occupiedGeometry() const
{
    return d_func()->mOccupiedGeometry;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: autonamecache.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-09-27 13:51:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_AUTONAMECACHE_HXX
#define SC_AUTONAMECACHE_HXX

#include <vector>
#include <hash_map>

#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif
#include "global.hxx"

typedef ::std::vector< ScAddress > ScAutoNameAddresses;
typedef ::std::hash_map< String, ScAutoNameAddresses, ScStringHashCode, ::std::equal_to< String > > ScAutoNameHashMap;

//
//  Cache for faster lookup of automatic names during CompileXML
//  (during CompileXML, no document content is changed)
//

class ScAutoNameCache
{
    ScAutoNameHashMap   aNames;
    ScDocument*         pDoc;
    SCTAB               nCurrentTab;

public:
            ScAutoNameCache( ScDocument* pD );
            ~ScAutoNameCache();

    const ScAutoNameAddresses& GetNameOccurences( const String& rName, SCTAB nTab );
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.176); FILE MERGED 2008/04/01 12:35:50 thb 1.3.176.2: #i85898# Stripping all external header guards 2008/03/31 17:13:26 rt 1.3.176.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: autonamecache.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_AUTONAMECACHE_HXX
#define SC_AUTONAMECACHE_HXX

#include <vector>
#include <hash_map>
#include "address.hxx"
#include "global.hxx"

typedef ::std::vector< ScAddress > ScAutoNameAddresses;
typedef ::std::hash_map< String, ScAutoNameAddresses, ScStringHashCode, ::std::equal_to< String > > ScAutoNameHashMap;

//
//  Cache for faster lookup of automatic names during CompileXML
//  (during CompileXML, no document content is changed)
//

class ScAutoNameCache
{
    ScAutoNameHashMap   aNames;
    ScDocument*         pDoc;
    SCTAB               nCurrentTab;

public:
            ScAutoNameCache( ScDocument* pD );
            ~ScAutoNameCache();

    const ScAutoNameAddresses& GetNameOccurences( const String& rName, SCTAB nTab );
};

#endif

<|endoftext|>


<commit_before>#include "DissentTest.hpp"

namespace Dissent {
namespace Tests {
  TEST(Crypto, DSAEncrypt)
  {
    QSharedPointer<CppDsaPrivateKey> private_key(new CppDsaPrivateKey());
    QSharedPointer<AsymmetricKey> public_key(private_key->GetPublicKey());

    Integer generator = private_key->GetGenerator();
    Integer modulus = private_key->GetModulus();
    Integer subgroup = private_key->GetSubgroup();

    Integer val = generator.Pow(Integer::GetRandomInteger(0, subgroup), modulus);
    QByteArray initial = val.GetByteArray();
    QByteArray encrypted = public_key->Encrypt(initial);
    QByteArray decrypted = private_key->Decrypt(encrypted);

    QByteArray encrypted0 = public_key->Encrypt(initial);
    QByteArray decrypted0 = private_key->Decrypt(encrypted0);

    EXPECT_EQ(initial, decrypted);
    EXPECT_NE(encrypted0, encrypted);
    EXPECT_EQ(decrypted0, decrypted);
  }

  TEST(Crypto, DSASeriesEncrypt)
  {
    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();
    Integer modulus = base_key->GetModulus();

    QVector<QSharedPointer<CppDsaPrivateKey> > private_keys;
    QVector<QSharedPointer<AsymmetricKey> > public_keys;
    int keys = 10;

    for(int idx = 0; idx < keys; idx++) {
      QSharedPointer<CppDsaPrivateKey> private_key(
          new CppDsaPrivateKey(modulus, subgroup, generator));
      private_keys.append(private_key);
      public_keys.append(QSharedPointer<AsymmetricKey>(private_key->GetPublicKey()));
    }

    Integer val = generator.Pow(Integer::GetRandomInteger(0, subgroup), modulus);
    QByteArray initial = val.GetByteArray();
    QByteArray encrypted = CppDsaPublicKey::SeriesEncrypt(public_keys,
        val.GetByteArray());

    QByteArray decrypted = encrypted;
    for(int idx = 0; idx < keys - 1; idx++) {
      decrypted = private_keys[idx]->SeriesDecrypt(decrypted);
    }
    decrypted = private_keys.last()->Decrypt(decrypted);

    QByteArray encrypted0 = CppDsaPublicKey::SeriesEncrypt(public_keys,
        val.GetByteArray());

    QByteArray decrypted0 = encrypted0;
    for(int idx = 0; idx < keys - 1; idx++) {
      decrypted0 = private_keys[idx]->SeriesDecrypt(decrypted0);
    }
    QByteArray decrypted0_0 = private_keys[keys - 1]->SeriesDecrypt(decrypted0);
    decrypted0_0 = private_keys[keys - 1]->SeriesDecryptFinish(decrypted0_0);
    decrypted0 = private_keys.last()->Decrypt(decrypted0);

    EXPECT_EQ(initial, decrypted);
    EXPECT_NE(encrypted0, encrypted);
    EXPECT_EQ(decrypted0, decrypted);
    EXPECT_EQ(decrypted0_0, decrypted);
  }

  TEST(Crypto, CppDsaNeff)
  {
    int keys = 50;
    int servers = 10;
    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();
    Integer modulus = base_key->GetModulus();

    QVector<QSharedPointer<CppDsaPrivateKey> > private_keys;
    QVector<Integer> public_elements;

    for(int idx = 0; idx < keys; idx++) {
      QSharedPointer<CppDsaPrivateKey> private_key(
          new CppDsaPrivateKey(modulus, subgroup, generator));
      EXPECT_EQ(modulus, private_key->GetModulus());
      EXPECT_EQ(subgroup, private_key->GetSubgroup());
      EXPECT_EQ(generator, private_key->GetGenerator());
      private_keys.append(private_key);

      public_elements.append(private_key->GetPublicElement());
      EXPECT_NE(generator, private_key->GetPublicElement());
      EXPECT_NE(modulus, private_key->GetPublicElement());

      EXPECT_TRUE(private_key->VerifyKey(*private_key->GetPublicKey()));
      EXPECT_TRUE(private_key->GetPublicKey()->VerifyKey(*private_key));
    }

    for(int idx = 0; idx < servers; idx++) {
      QSharedPointer<CppDsaPrivateKey> private_key(new CppDsaPrivateKey());
      Integer local_generator = private_key->GetPrivateExponent();
      generator = generator.Pow(local_generator, modulus);

      for(int jdx = 0; jdx < keys; jdx++) {
        public_elements[jdx] = public_elements[jdx].Pow(local_generator, modulus);
      }
    }

    QVector<QSharedPointer<CppDsaPublicKey> > public_keys;

    for(int idx = 0; idx < keys; idx++) {
      QSharedPointer<CppDsaPrivateKey> private_key(
          new CppDsaPrivateKey(modulus, subgroup, generator,
            private_keys[idx]->GetPrivateExponent()));
      private_keys[idx] = private_key;

      public_keys.append(QSharedPointer<CppDsaPublicKey>(
            new CppDsaPublicKey(modulus, subgroup, generator, public_elements[idx])));
    }

    QScopedPointer<Random> rng(CryptoFactory::GetInstance().
        GetLibrary()->GetRandomNumberGenerator());
    QByteArray data(1500, 0);
    rng->GenerateBlock(data);

    for(int idx = 0; idx < keys; idx++) {
      EXPECT_TRUE(private_keys[idx]->VerifyKey(*public_keys[idx].data()));
      EXPECT_TRUE(public_keys[idx]->Verify(data, private_keys[idx]->Sign(data)));
    }
  }

  TEST(Crypto, CppDsaSanityCheck)
  {
    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key;
    CryptoPP::AutoSeededX917RNG<CryptoPP::DES_EDE3> rng;
    key.GenerateRandom(rng,
        CryptoPP::MakeParameters
        (CryptoPP::Name::ModulusSize(), 2048)
        (CryptoPP::Name::SubgroupOrderSize(), 256));
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key.Validate(rng, idx));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key0;
    key0.GenerateRandom(rng,
        CryptoPP::MakeParameters
        (CryptoPP::Name::Modulus(), key.GetGroupParameters().GetModulus())
        (CryptoPP::Name::SubgroupOrder(), key.GetGroupParameters().GetSubgroupOrder())
        (CryptoPP::Name::SubgroupGenerator(), key.GetGroupParameters().GetGenerator()));
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key0.Validate(rng, idx));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key1;
    key1.Initialize(rng, key.GetGroupParameters().GetModulus(), key.GetGroupParameters().GetGenerator());
    // Some of these will fail since we ignore the subgoup
    EXPECT_FALSE(key1.Validate(rng, 3));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key2;
    key2.Initialize(key.GetGroupParameters().GetModulus(), key.GetGroupParameters().GetSubgroupOrder(),
        key.GetGroupParameters().GetGenerator(), key.GetPrivateExponent());
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key2.Validate(rng, idx));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key3;
    key3.GenerateRandomWithKeySize(rng, 1024);
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key3.Validate(rng, idx));
  }

  TEST(Crypto, LRSTest)
  {
    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();
    Integer modulus = base_key->GetModulus();

    QVector<QSharedPointer<AsymmetricKey> > priv_keys;
    QVector<QSharedPointer<AsymmetricKey> > pub_keys;

    int count = 8;

    for(int idx = 0; idx < count; idx++) {
      QSharedPointer<CppDsaPrivateKey> key(
          new CppDsaPrivateKey(modulus, subgroup, generator));
      priv_keys.append(key);
      pub_keys.append(QSharedPointer<AsymmetricKey>(key->GetPublicKey()));
    }

    CppRandom rng;
    QByteArray context(1024, 0);
    rng.GenerateBlock(context);

    QVector<QSharedPointer<LRSPrivateKey> > lrss;
    LRSPublicKey lrp(pub_keys, context);

    for(int idx = 0; idx < count; idx++) {
      lrss.append(QSharedPointer<LRSPrivateKey>(
            new LRSPrivateKey(priv_keys[idx], pub_keys, context)));
    }

    QByteArray msg(1500, 0);
    rng.GenerateBlock(msg);

    foreach(const QSharedPointer<LRSPrivateKey> &lrs, lrss) {
      QByteArray signature = lrs->Sign(msg);
      lrp.Verify(msg, signature);
      EXPECT_TRUE(lrp.VerifyKey(*(lrs.data())));
    }
  }

  TEST(Crypto, Reencrypt)
  {
    QSharedPointer<CppDsaPrivateKey> private_key(new CppDsaPrivateKey());

    Integer modulus = private_key->GetModulus();
    Integer generator = private_key->GetGenerator();
    Integer subgroup = private_key->GetSubgroup();
    Integer h = private_key->GetPublicElement();
    Integer x = private_key->GetPrivateExponent();

    Integer value_exp = Integer::GetRandomInteger(2, subgroup);
    Integer value = generator.Pow(value_exp, modulus);

    Integer secret = Integer::GetRandomInteger(2, subgroup);
    Integer shared = generator.Pow(secret, modulus);
    Integer encrypted = (value * h.Pow(secret, modulus)) % modulus;

    Integer decrypted = (encrypted * shared.Pow(x, modulus).MultiplicativeInverse(modulus)) % modulus;
    EXPECT_EQ(decrypted, value);

    Integer beta = Integer::GetRandomInteger(2, subgroup);

    shared = (shared * generator.Pow(beta, modulus)) % modulus;
    encrypted = (encrypted * h.Pow(beta, modulus)) % modulus;

    decrypted = (encrypted * shared.Pow(x, modulus).MultiplicativeInverse(modulus)) % modulus;
    EXPECT_EQ(decrypted, value);
  }

  TEST(Crypto, NeffShuffle)
  {
    int values = 50;
    int keys = 10;

    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer modulus = base_key->GetModulus();
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();

    QVector<QSharedPointer<CppDsaPrivateKey> > pr_keys;
    QVector<QSharedPointer<AsymmetricKey> > pub_keys;
    for(int idx = 0; idx < keys; idx++) {
      pr_keys.append(QSharedPointer<CppDsaPrivateKey>(new CppDsaPrivateKey(
              modulus, subgroup, generator)));
      pub_keys.append(QSharedPointer<AsymmetricKey>(pr_keys.last()->GetPublicKey()));
    }

    QVector<QByteArray> input;
    QVector<Integer> x;

    for(int idx = 0; idx < values; idx++) {
      Integer tmp_val = Integer::GetRandomInteger(0, subgroup);
      x.append(generator.Pow(tmp_val, modulus));

      input.append(CppDsaPublicKey::SeriesEncrypt(pub_keys,
            x.last().GetByteArray()));
    }

    CppNeffShuffle shuffle;

    QVector<QByteArray> output;
    QByteArray proof;
    QVector<QSharedPointer<AsymmetricKey> > npub_keys = pub_keys;
    QVector<QSharedPointer<AsymmetricKey> > cpub_keys = pub_keys;

    foreach(const QSharedPointer<CppDsaPrivateKey> &private_key, pr_keys) {
      npub_keys.pop_front();
      EXPECT_TRUE(shuffle.Shuffle(input, private_key, npub_keys, output, proof));
      EXPECT_TRUE(shuffle.Verify(input, cpub_keys, proof, output));
      input = output;
      cpub_keys = npub_keys;
    }

    foreach(const QByteArray &encrypted, output) {
      QByteArray decrypted = CppDsaPrivateKey::SeriesDecryptFinish(encrypted);
      Integer val(decrypted);
      EXPECT_TRUE(x.contains(val));
    }
  }
}
}
<commit_msg>[Tests] Removed unnecessary tests<commit_after>#include "DissentTest.hpp"

namespace Dissent {
namespace Tests {
  TEST(Crypto, DSAEncrypt)
  {
    QSharedPointer<CppDsaPrivateKey> private_key(new CppDsaPrivateKey());
    QSharedPointer<AsymmetricKey> public_key(private_key->GetPublicKey());

    Integer generator = private_key->GetGenerator();
    Integer modulus = private_key->GetModulus();
    Integer subgroup = private_key->GetSubgroup();

    Integer val = generator.Pow(Integer::GetRandomInteger(0, subgroup), modulus);
    QByteArray initial = val.GetByteArray();
    QByteArray encrypted = public_key->Encrypt(initial);
    QByteArray decrypted = private_key->Decrypt(encrypted);

    QByteArray encrypted0 = public_key->Encrypt(initial);
    QByteArray decrypted0 = private_key->Decrypt(encrypted0);

    EXPECT_EQ(initial, decrypted);
    EXPECT_NE(encrypted0, encrypted);
    EXPECT_EQ(decrypted0, decrypted);
  }

  TEST(Crypto, DSASeriesEncrypt)
  {
    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();
    Integer modulus = base_key->GetModulus();

    QVector<QSharedPointer<CppDsaPrivateKey> > private_keys;
    QVector<QSharedPointer<AsymmetricKey> > public_keys;
    int keys = 10;

    for(int idx = 0; idx < keys; idx++) {
      QSharedPointer<CppDsaPrivateKey> private_key(
          new CppDsaPrivateKey(modulus, subgroup, generator));
      private_keys.append(private_key);
      public_keys.append(QSharedPointer<AsymmetricKey>(private_key->GetPublicKey()));
    }

    Integer val = generator.Pow(Integer::GetRandomInteger(0, subgroup), modulus);
    QByteArray initial = val.GetByteArray();
    QByteArray encrypted = CppDsaPublicKey::SeriesEncrypt(public_keys,
        val.GetByteArray());

    QByteArray decrypted = encrypted;
    for(int idx = 0; idx < keys - 1; idx++) {
      decrypted = private_keys[idx]->SeriesDecrypt(decrypted);
    }
    decrypted = private_keys.last()->Decrypt(decrypted);

    QByteArray encrypted0 = CppDsaPublicKey::SeriesEncrypt(public_keys,
        val.GetByteArray());

    QByteArray decrypted0 = encrypted0;
    for(int idx = 0; idx < keys - 1; idx++) {
      decrypted0 = private_keys[idx]->SeriesDecrypt(decrypted0);
    }
    QByteArray decrypted0_0 = private_keys[keys - 1]->SeriesDecrypt(decrypted0);
    decrypted0_0 = private_keys[keys - 1]->SeriesDecryptFinish(decrypted0_0);
    decrypted0 = private_keys.last()->Decrypt(decrypted0);

    EXPECT_EQ(initial, decrypted);
    EXPECT_NE(encrypted0, encrypted);
    EXPECT_EQ(decrypted0, decrypted);
    EXPECT_EQ(decrypted0_0, decrypted);
  }

  TEST(Crypto, CppDsaSanityCheck)
  {
    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key;
    CryptoPP::AutoSeededX917RNG<CryptoPP::DES_EDE3> rng;
    key.GenerateRandom(rng,
        CryptoPP::MakeParameters
        (CryptoPP::Name::ModulusSize(), 2048)
        (CryptoPP::Name::SubgroupOrderSize(), 256));
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key.Validate(rng, idx));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key0;
    key0.GenerateRandom(rng,
        CryptoPP::MakeParameters
        (CryptoPP::Name::Modulus(), key.GetGroupParameters().GetModulus())
        (CryptoPP::Name::SubgroupOrder(), key.GetGroupParameters().GetSubgroupOrder())
        (CryptoPP::Name::SubgroupGenerator(), key.GetGroupParameters().GetGenerator()));
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key0.Validate(rng, idx));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key1;
    key1.Initialize(rng, key.GetGroupParameters().GetModulus(), key.GetGroupParameters().GetGenerator());
    // Some of these will fail since we ignore the subgoup
    EXPECT_FALSE(key1.Validate(rng, 3));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key2;
    key2.Initialize(key.GetGroupParameters().GetModulus(), key.GetGroupParameters().GetSubgroupOrder(),
        key.GetGroupParameters().GetGenerator(), key.GetPrivateExponent());
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key2.Validate(rng, idx));

    CryptoPP::GDSA<CryptoPP::SHA256>::PrivateKey key3;
    key3.GenerateRandomWithKeySize(rng, 1024);
    for(int idx = 0; idx < 4; idx++)
      EXPECT_TRUE(key3.Validate(rng, idx));
  }

  TEST(Crypto, LRSTest)
  {
    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();
    Integer modulus = base_key->GetModulus();

    QVector<QSharedPointer<AsymmetricKey> > priv_keys;
    QVector<QSharedPointer<AsymmetricKey> > pub_keys;

    int count = 8;

    for(int idx = 0; idx < count; idx++) {
      QSharedPointer<CppDsaPrivateKey> key(
          new CppDsaPrivateKey(modulus, subgroup, generator));
      priv_keys.append(key);
      pub_keys.append(QSharedPointer<AsymmetricKey>(key->GetPublicKey()));
    }

    CppRandom rng;
    QByteArray context(1024, 0);
    rng.GenerateBlock(context);

    QVector<QSharedPointer<LRSPrivateKey> > lrss;
    LRSPublicKey lrp(pub_keys, context);

    for(int idx = 0; idx < count; idx++) {
      lrss.append(QSharedPointer<LRSPrivateKey>(
            new LRSPrivateKey(priv_keys[idx], pub_keys, context)));
    }

    QByteArray msg(1500, 0);
    rng.GenerateBlock(msg);

    foreach(const QSharedPointer<LRSPrivateKey> &lrs, lrss) {
      QByteArray signature = lrs->Sign(msg);
      lrp.Verify(msg, signature);
      EXPECT_TRUE(lrp.VerifyKey(*(lrs.data())));
    }
  }

  TEST(Crypto, NeffShuffle)
  {
    int values = 50;
    int keys = 10;

    QSharedPointer<CppDsaPrivateKey> base_key(new CppDsaPrivateKey());
    Integer modulus = base_key->GetModulus();
    Integer generator = base_key->GetGenerator();
    Integer subgroup = base_key->GetSubgroup();

    QVector<QSharedPointer<CppDsaPrivateKey> > pr_keys;
    QVector<QSharedPointer<AsymmetricKey> > pub_keys;
    for(int idx = 0; idx < keys; idx++) {
      pr_keys.append(QSharedPointer<CppDsaPrivateKey>(new CppDsaPrivateKey(
              modulus, subgroup, generator)));
      pub_keys.append(QSharedPointer<AsymmetricKey>(pr_keys.last()->GetPublicKey()));
    }

    QVector<QByteArray> input;
    QVector<Integer> x;

    for(int idx = 0; idx < values; idx++) {
      Integer tmp_val = Integer::GetRandomInteger(0, subgroup);
      x.append(generator.Pow(tmp_val, modulus));

      input.append(CppDsaPublicKey::SeriesEncrypt(pub_keys,
            x.last().GetByteArray()));
    }

    CppNeffShuffle shuffle;

    QVector<QByteArray> output;
    QByteArray proof;
    QVector<QSharedPointer<AsymmetricKey> > npub_keys = pub_keys;
    QVector<QSharedPointer<AsymmetricKey> > cpub_keys = pub_keys;

    foreach(const QSharedPointer<CppDsaPrivateKey> &private_key, pr_keys) {
      npub_keys.pop_front();
      EXPECT_TRUE(shuffle.Shuffle(input, private_key, npub_keys, output, proof));
      EXPECT_TRUE(shuffle.Verify(input, cpub_keys, proof, output));
      input = output;
      cpub_keys = npub_keys;
    }

    foreach(const QByteArray &encrypted, output) {
      QByteArray decrypted = CppDsaPrivateKey::SeriesDecryptFinish(encrypted);
      Integer val(decrypted);
      EXPECT_TRUE(x.contains(val));
    }
  }
}
}
<|endoftext|>