<commit_before>/*
 *  Copyright 2010-2011 Fabric Technologies Inc. All rights reserved.
 */

#include <Fabric/Clients/NPAPI/Linux/X11ViewPort.h>
#include <Fabric/Clients/NPAPI/Interface.h>
#include <Fabric/Base/JSON/Value.h>
#include <Fabric/Base/Exception.h>
#include <Fabric/Clients/NPAPI/Context.h>
#include <Fabric/Core/DG/Event.h>
#include <Fabric/Core/MT/LogCollector.h>

namespace Fabric
{
  namespace NPAPI
  {
    RC::Handle<ViewPort> X11ViewPort::Create( RC::ConstHandle<Interface> const &interface )
    {
      NPP npp = interface->getNPP();

      NPBool supportsXEmbed;
      if ( NPN_GetValue( NULL, NPNVSupportsXEmbedBool, (void *)&supportsXEmbed ) != NPERR_NO_ERROR )
        supportsXEmbed = false;

      if ( !supportsXEmbed )
        return 0;

      return new X11ViewPort( interface );
    }

    X11ViewPort::X11ViewPort( RC::ConstHandle<Interface> const &interface )
      : ViewPort( interface )
      , m_logCollector( interface->getContext()->getLogCollector() )
      , m_gdkNativeWindow( 0 )
      , m_plug( 0 )
      , m_drawingArea( 0 )
      , m_windowWidth( -1 )
      , m_windowHeight( -1 )
    {
    }

    X11ViewPort::~X11ViewPort()
    {
      if ( m_drawingArea )
        g_object_unref( m_drawingArea );
      if ( m_plug )
        g_object_unref( m_plug );
    }

    void X11ViewPort::redraw()
    {
      if ( m_drawingArea )
      {
        GdkGLDrawable *gdkGLDrawable = gtk_widget_get_gl_drawable( m_drawingArea );
        FABRIC_ASSERT( gdkGLDrawable );
        GdkGLContext *gdkGLContext = gtk_widget_get_gl_context( m_drawingArea );
        FABRIC_ASSERT( gdkGLContext );

        bool gdkGLDrawableMakeCurrentResult = gdk_gl_drawable_make_current( gdkGLDrawable, gdkGLContext );
        FABRIC_ASSERT( gdkGLDrawableMakeCurrentResult );

        static bool printedOpenGLVersionString = false;
        if ( !printedOpenGLVersionString )
        {
          FABRIC_LOG( "OpenGL version string is '%s'", glGetString( GL_VERSION ) );
          printedOpenGLVersionString = true;
        }

        RC::Handle<DG::Event> dgRedrawEvent = getRedrawEvent();
        FABRIC_ASSERT( dgRedrawEvent );
        try
        {
          dgRedrawEvent->fire();
        }
        catch ( Exception e )
        {
          FABRIC_LOG( "redrawEvent: exception thrown: %s", (const char*)e.getDesc() );
        }
        catch ( ... )
        {
          FABRIC_LOG( "redrawEvent: unknown exception thrown" );
        }
        drawWatermark( m_windowWidth, m_windowHeight );
        glFinish();

        if ( gdk_gl_drawable_is_double_buffered( gdkGLDrawable ) )
          gdk_gl_drawable_swap_buffers( gdkGLDrawable );

        redrawFinished();
      }
    }

    struct ViewPortAndJSONValue
    {
      ViewPort const *viewPort;
      JSON::Value const *value;
    };

    void X11ViewPort::MenuItemActivateCallback( void *_viewPortAndJSONValue )
    {
      ViewPortAndJSONValue const *viewPortAndJSONValue = (ViewPortAndJSONValue const *)_viewPortAndJSONValue;
      viewPortAndJSONValue->viewPort->jsonNotifyPopUpItem( viewPortAndJSONValue->value );
    }

    gboolean X11ViewPort::EventCallback( GtkWidget *widget, GdkEvent *event, gpointer user_data )
    {
      X11ViewPort *x11ViewPort = static_cast< X11ViewPort * >( user_data );
      switch ( event->type )
      {
        case GDK_EXPOSE:
          x11ViewPort->redraw();
          return TRUE;

        case GDK_BUTTON_PRESS:
        {
          GdkEventButton *button = (GdkEventButton *)event;
          if ( button->button == 3 )
          {
            if ( !x11ViewPort->m_popUpItems.empty() )
            {
              GtkWidget *menu = gtk_menu_new();

              for ( PopUpItems::const_iterator it=x11ViewPort->m_popUpItems.begin(); it!=x11ViewPort->m_popUpItems.end(); ++it )
              {
                PopUpItem const &popUpItem = *it;

                GtkWidget *menuItem = gtk_menu_item_new_with_label( popUpItem.desc.c_str() );
                gtk_menu_shell_append( GTK_MENU_SHELL(menu), menuItem );

                ViewPortAndJSONValue *viewPortAndJSONValue = new ViewPortAndJSONValue;
                viewPortAndJSONValue->viewPort = x11ViewPort;
                viewPortAndJSONValue->value = popUpItem.value.ptr();
                g_signal_connect_swapped( G_OBJECT(menuItem), "activate",
                  G_CALLBACK(&X11ViewPort::MenuItemActivateCallback),
                  viewPortAndJSONValue );
                gtk_widget_show( menuItem );
              }

              gtk_menu_popup( GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time() );

              return TRUE;
            }
          }
        }
        break;
      }
      return FALSE;
    }

    NPError X11ViewPort::nppSetWindow( NPWindow *window )
    {
      static bool calledGtkGLInit = false;
      if ( !calledGtkGLInit )
      {
        int argc = 1;
        char **argv;
        argv = new char *[2];
        argv[0] = strdup("libFabricNPAPIPlugin.so");
        argv[1] = NULL;
        gtk_gl_init( &argc, &argv );
        gdk_gl_init( &argc, &argv );
        calledGtkGLInit = true;
      }

      GdkNativeWindow gdkNativeWindow = (GdkNativeWindow)(size_t)window->window;

      if ( gdkNativeWindow != m_gdkNativeWindow )
      {
        if ( m_drawingArea )
        {
          g_object_unref( m_drawingArea );
          m_drawingArea = 0;
        }

        if ( m_plug )
        {
          g_object_unref( m_plug );
          m_plug = 0;
        }

        m_gdkNativeWindow = gdkNativeWindow;

        if ( gdkNativeWindow )
        {
          GdkGLConfig *gdkGLConfig = gdk_gl_config_new_by_mode( GdkGLConfigMode(GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE) );
          FABRIC_ASSERT( gdkGLConfig );

          m_drawingArea = gtk_drawing_area_new();
          FABRIC_ASSERT( m_drawingArea );
          g_object_ref( m_drawingArea );
          bool gtkWidgetSetGLCapabilityResult = gtk_widget_set_gl_capability( m_drawingArea, gdkGLConfig, NULL, true, GDK_GL_RGBA_TYPE );
          FABRIC_ASSERT( gtkWidgetSetGLCapabilityResult );
          gtk_widget_set_events( m_drawingArea,
            GDK_EXPOSURE_MASK
            /* disabled the button press masks, since javascript
               events stopped to work
            | GDK_BUTTON_PRESS_MASK
            | GDK_BUTTON_RELEASE_MASK
              */
            );

          m_plug = gtk_plug_new( gdkNativeWindow );
          FABRIC_ASSERT( m_plug );
          g_object_ref( m_plug );
          gtk_container_add( GTK_CONTAINER(m_plug), m_drawingArea );

          gtk_widget_show_all( GTK_WIDGET(m_plug) );

          g_signal_connect( G_OBJECT(m_drawingArea), "event", G_CALLBACK( &X11ViewPort::EventCallback ), this );
        }
      }

      if ( m_windowLeft != window->x || m_windowTop != window->y
        || m_windowWidth != window->width || m_windowHeight != window->height )
      {
        m_windowLeft = window->x;
        m_windowTop = window->y;
        m_windowWidth = window->width;
        m_windowHeight = window->height;

        didResize( m_windowWidth, m_windowHeight );
      }

      return NPERR_NO_ERROR;
    }

    NPError X11ViewPort::nppGetValue( NPPVariable variable, void *value )
    {
      if ( variable == NPPVpluginNeedsXEmbed )
      {
        *(static_cast<NPBool*>(value)) = true;
        return NPERR_NO_ERROR;
      }

      return ViewPort::nppGetValue( variable, value );
    }

    void X11ViewPort::needsRedraw()
    {
      gdk_window_invalidate_rect(
        gtk_widget_get_window( m_drawingArea ),
        NULL,
        false
        );
    }

    void X11ViewPort::pushOGLContext()
    {
      m_gdkGLStack.push_back( GdkGLDrawableAndContext( gdk_gl_drawable_get_current(), gdk_gl_context_get_current() ) );

      if ( m_drawingArea )
      {
        GdkGLDrawable *gdkGLDrawable = gtk_widget_get_gl_drawable( m_drawingArea );
        FABRIC_ASSERT( gdkGLDrawable );
        GdkGLContext *gdkGLContext = gtk_widget_get_gl_context( m_drawingArea );
        FABRIC_ASSERT( gdkGLContext );

        bool gdkGLDrawableMakeCurrentResult = gdk_gl_drawable_make_current( gdkGLDrawable, gdkGLContext );
        FABRIC_ASSERT( gdkGLDrawableMakeCurrentResult );
      }
    }

    void X11ViewPort::popOGLContext()
    {
      FABRIC_ASSERT( !m_gdkGLStack.empty() );

      bool gdkGLDrawableMakeCurrentResult = gdk_gl_drawable_make_current( m_gdkGLStack.back().first, m_gdkGLStack.back().second );
      FABRIC_ASSERT( gdkGLDrawableMakeCurrentResult );

      m_gdkGLStack.pop_back();
    }

    std::string X11ViewPort::getPathFromSaveAsDialog( std::string const &defaultFilename, std::string const &extension )
    {
      GtkWidget *dialog = gtk_file_chooser_dialog_new( "Save File...",
        NULL,
        GTK_FILE_CHOOSER_ACTION_SAVE,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
        NULL
        );
      gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );
      //gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), default_folder_for_saving );
      gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER(dialog), defaultFilename.c_str() );

      std::string result;
      gint runResult = gtk_dialog_run(GTK_DIALOG(dialog));
      if ( runResult == GTK_RESPONSE_ACCEPT )
      {
        char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        result = std::string( filename );
        g_free(filename);
      }
      gtk_widget_destroy (dialog);
      if ( runResult != GTK_RESPONSE_ACCEPT )
        throw Exception( "File save failed or was canceled by user" );
      return result;
    }
  };
};
<commit_msg>issue-442: add notification bracket for Linux redraw<commit_after>/*
 *  Copyright 2010-2011 Fabric Technologies Inc. All rights reserved.
 */

#include <Fabric/Clients/NPAPI/Linux/X11ViewPort.h>
#include <Fabric/Clients/NPAPI/Interface.h>
#include <Fabric/Base/JSON/Value.h>
#include <Fabric/Base/Exception.h>
#include <Fabric/Clients/NPAPI/Context.h>
#include <Fabric/Core/DG/Event.h>
#include <Fabric/Core/MT/LogCollector.h>

namespace Fabric
{
  namespace NPAPI
  {
    RC::Handle<ViewPort> X11ViewPort::Create( RC::ConstHandle<Interface> const &interface )
    {
      NPP npp = interface->getNPP();

      NPBool supportsXEmbed;
      if ( NPN_GetValue( NULL, NPNVSupportsXEmbedBool, (void *)&supportsXEmbed ) != NPERR_NO_ERROR )
        supportsXEmbed = false;

      if ( !supportsXEmbed )
        return 0;

      return new X11ViewPort( interface );
    }

    X11ViewPort::X11ViewPort( RC::ConstHandle<Interface> const &interface )
      : ViewPort( interface )
      , m_logCollector( interface->getContext()->getLogCollector() )
      , m_gdkNativeWindow( 0 )
      , m_plug( 0 )
      , m_drawingArea( 0 )
      , m_windowWidth( -1 )
      , m_windowHeight( -1 )
    {
    }

    X11ViewPort::~X11ViewPort()
    {
      if ( m_drawingArea )
        g_object_unref( m_drawingArea );
      if ( m_plug )
        g_object_unref( m_plug );
    }

    void X11ViewPort::redraw()
    {
      if ( m_drawingArea )
      {
        DG::Context::NotificationBracket notificationBracket( getInterface()->getContext() );

        GdkGLDrawable *gdkGLDrawable = gtk_widget_get_gl_drawable( m_drawingArea );
        FABRIC_ASSERT( gdkGLDrawable );
        GdkGLContext *gdkGLContext = gtk_widget_get_gl_context( m_drawingArea );
        FABRIC_ASSERT( gdkGLContext );

        bool gdkGLDrawableMakeCurrentResult = gdk_gl_drawable_make_current( gdkGLDrawable, gdkGLContext );
        FABRIC_ASSERT( gdkGLDrawableMakeCurrentResult );

        static bool printedOpenGLVersionString = false;
        if ( !printedOpenGLVersionString )
        {
          FABRIC_LOG( "OpenGL version string is '%s'", glGetString( GL_VERSION ) );
          printedOpenGLVersionString = true;
        }

        RC::Handle<DG::Event> dgRedrawEvent = getRedrawEvent();
        FABRIC_ASSERT( dgRedrawEvent );
        try
        {
          dgRedrawEvent->fire();
        }
        catch ( Exception e )
        {
          FABRIC_LOG( "redrawEvent: exception thrown: %s", (const char*)e.getDesc() );
        }
        catch ( ... )
        {
          FABRIC_LOG( "redrawEvent: unknown exception thrown" );
        }
        drawWatermark( m_windowWidth, m_windowHeight );
        glFinish();

        if ( gdk_gl_drawable_is_double_buffered( gdkGLDrawable ) )
          gdk_gl_drawable_swap_buffers( gdkGLDrawable );

        redrawFinished();
      }
    }

    struct ViewPortAndJSONValue
    {
      ViewPort const *viewPort;
      JSON::Value const *value;
    };

    void X11ViewPort::MenuItemActivateCallback( void *_viewPortAndJSONValue )
    {
      ViewPortAndJSONValue const *viewPortAndJSONValue = (ViewPortAndJSONValue const *)_viewPortAndJSONValue;
      viewPortAndJSONValue->viewPort->jsonNotifyPopUpItem( viewPortAndJSONValue->value );
    }

    gboolean X11ViewPort::EventCallback( GtkWidget *widget, GdkEvent *event, gpointer user_data )
    {
      X11ViewPort *x11ViewPort = static_cast< X11ViewPort * >( user_data );
      switch ( event->type )
      {
        case GDK_EXPOSE:
          x11ViewPort->redraw();
          return TRUE;

        case GDK_BUTTON_PRESS:
        {
          GdkEventButton *button = (GdkEventButton *)event;
          if ( button->button == 3 )
          {
            if ( !x11ViewPort->m_popUpItems.empty() )
            {
              GtkWidget *menu = gtk_menu_new();

              for ( PopUpItems::const_iterator it=x11ViewPort->m_popUpItems.begin(); it!=x11ViewPort->m_popUpItems.end(); ++it )
              {
                PopUpItem const &popUpItem = *it;

                GtkWidget *menuItem = gtk_menu_item_new_with_label( popUpItem.desc.c_str() );
                gtk_menu_shell_append( GTK_MENU_SHELL(menu), menuItem );

                ViewPortAndJSONValue *viewPortAndJSONValue = new ViewPortAndJSONValue;
                viewPortAndJSONValue->viewPort = x11ViewPort;
                viewPortAndJSONValue->value = popUpItem.value.ptr();
                g_signal_connect_swapped( G_OBJECT(menuItem), "activate",
                  G_CALLBACK(&X11ViewPort::MenuItemActivateCallback),
                  viewPortAndJSONValue );
                gtk_widget_show( menuItem );
              }

              gtk_menu_popup( GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time() );

              return TRUE;
            }
          }
        }
        break;
      }
      return FALSE;
    }

    NPError X11ViewPort::nppSetWindow( NPWindow *window )
    {
      static bool calledGtkGLInit = false;
      if ( !calledGtkGLInit )
      {
        int argc = 1;
        char **argv;
        argv = new char *[2];
        argv[0] = strdup("libFabricNPAPIPlugin.so");
        argv[1] = NULL;
        gtk_gl_init( &argc, &argv );
        gdk_gl_init( &argc, &argv );
        calledGtkGLInit = true;
      }

      GdkNativeWindow gdkNativeWindow = (GdkNativeWindow)(size_t)window->window;

      if ( gdkNativeWindow != m_gdkNativeWindow )
      {
        if ( m_drawingArea )
        {
          g_object_unref( m_drawingArea );
          m_drawingArea = 0;
        }

        if ( m_plug )
        {
          g_object_unref( m_plug );
          m_plug = 0;
        }

        m_gdkNativeWindow = gdkNativeWindow;

        if ( gdkNativeWindow )
        {
          GdkGLConfig *gdkGLConfig = gdk_gl_config_new_by_mode( GdkGLConfigMode(GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE) );
          FABRIC_ASSERT( gdkGLConfig );

          m_drawingArea = gtk_drawing_area_new();
          FABRIC_ASSERT( m_drawingArea );
          g_object_ref( m_drawingArea );
          bool gtkWidgetSetGLCapabilityResult = gtk_widget_set_gl_capability( m_drawingArea, gdkGLConfig, NULL, true, GDK_GL_RGBA_TYPE );
          FABRIC_ASSERT( gtkWidgetSetGLCapabilityResult );
          gtk_widget_set_events( m_drawingArea,
            GDK_EXPOSURE_MASK
            /* disabled the button press masks, since javascript
               events stopped to work
            | GDK_BUTTON_PRESS_MASK
            | GDK_BUTTON_RELEASE_MASK
              */
            );

          m_plug = gtk_plug_new( gdkNativeWindow );
          FABRIC_ASSERT( m_plug );
          g_object_ref( m_plug );
          gtk_container_add( GTK_CONTAINER(m_plug), m_drawingArea );

          gtk_widget_show_all( GTK_WIDGET(m_plug) );

          g_signal_connect( G_OBJECT(m_drawingArea), "event", G_CALLBACK( &X11ViewPort::EventCallback ), this );
        }
      }

      if ( m_windowLeft != window->x || m_windowTop != window->y
        || m_windowWidth != window->width || m_windowHeight != window->height )
      {
        m_windowLeft = window->x;
        m_windowTop = window->y;
        m_windowWidth = window->width;
        m_windowHeight = window->height;

        didResize( m_windowWidth, m_windowHeight );
      }

      return NPERR_NO_ERROR;
    }

    NPError X11ViewPort::nppGetValue( NPPVariable variable, void *value )
    {
      if ( variable == NPPVpluginNeedsXEmbed )
      {
        *(static_cast<NPBool*>(value)) = true;
        return NPERR_NO_ERROR;
      }

      return ViewPort::nppGetValue( variable, value );
    }

    void X11ViewPort::needsRedraw()
    {
      gdk_window_invalidate_rect(
        gtk_widget_get_window( m_drawingArea ),
        NULL,
        false
        );
    }

    void X11ViewPort::pushOGLContext()
    {
      m_gdkGLStack.push_back( GdkGLDrawableAndContext( gdk_gl_drawable_get_current(), gdk_gl_context_get_current() ) );

      if ( m_drawingArea )
      {
        GdkGLDrawable *gdkGLDrawable = gtk_widget_get_gl_drawable( m_drawingArea );
        FABRIC_ASSERT( gdkGLDrawable );
        GdkGLContext *gdkGLContext = gtk_widget_get_gl_context( m_drawingArea );
        FABRIC_ASSERT( gdkGLContext );

        bool gdkGLDrawableMakeCurrentResult = gdk_gl_drawable_make_current( gdkGLDrawable, gdkGLContext );
        FABRIC_ASSERT( gdkGLDrawableMakeCurrentResult );
      }
    }

    void X11ViewPort::popOGLContext()
    {
      FABRIC_ASSERT( !m_gdkGLStack.empty() );

      bool gdkGLDrawableMakeCurrentResult = gdk_gl_drawable_make_current( m_gdkGLStack.back().first, m_gdkGLStack.back().second );
      FABRIC_ASSERT( gdkGLDrawableMakeCurrentResult );

      m_gdkGLStack.pop_back();
    }

    std::string X11ViewPort::getPathFromSaveAsDialog( std::string const &defaultFilename, std::string const &extension )
    {
      GtkWidget *dialog = gtk_file_chooser_dialog_new( "Save File...",
        NULL,
        GTK_FILE_CHOOSER_ACTION_SAVE,
        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
        GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
        NULL
        );
      gtk_file_chooser_set_do_overwrite_confirmation( GTK_FILE_CHOOSER(dialog), TRUE );
      //gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(dialog), default_folder_for_saving );
      gtk_file_chooser_set_current_name( GTK_FILE_CHOOSER(dialog), defaultFilename.c_str() );

      std::string result;
      gint runResult = gtk_dialog_run(GTK_DIALOG(dialog));
      if ( runResult == GTK_RESPONSE_ACCEPT )
      {
        char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        result = std::string( filename );
        g_free(filename);
      }
      gtk_widget_destroy (dialog);
      if ( runResult != GTK_RESPONSE_ACCEPT )
        throw Exception( "File save failed or was canceled by user" );
      return result;
    }
  };
};
<|endoftext|>


<commit_before>#include "common.h"

void SPCERuntime::run_umbrella_system() {
    cerr << "---- BEGIN - UMBRELLA SAMPLING ----" << endl;
    double window_lower_bound = 0.0, window_upper_bound = 2.0;
    Simulation * simulation = new Simulation();

    Ion * anion = simulation->IONS[0];
    Ion * cation = simulation->IONS[1];
    anion->charge = -1.0;
    cation->charge = 1.0;

    cerr << "Initializing anion-cation distance to be inside window [" << window_lower_bound << ", " << window_upper_bound << "] Angstroms......";
    while (anion->distance_from(cation) <= window_lower_bound or anion->distance_from(cation) > window_upper_bound)
        anion->set_random_coords();
    cerr << "done.\n" << endl;

    simulation->NUM_EQUILIBRATION_SWEEPS = 100000;
    simulation->turn_on_window_sampling_mc(window_lower_bound, window_upper_bound);
    simulation->equilibrate();

    simulation->SAMPLER_SET->turn_on_lammpstrj_sampler();
    simulation->DATA_SAMPLING_RATE = 20;
    simulation->NUM_MC_SWEEPS = 500000;
    simulation->run_mc();

    simulation->SAMPLER_SET->write_config_snapshot();
    cerr << "\n---- END - UMBRELLA SAMPLING ----\n" << endl;
    return;
}

void SPCERuntime::run_all_tests(int argc, char** argv) {
    run_umbrella_system();
    //test_water_rotation();
    //test_lammpstrj_output();
    //test_config_output();
    //test_config_input();
    //test_radial_dist();
    //test_ion_pair_dist();
    return;
}

void SPCERuntime::test_config_input() {
    cerr << "---- BEGIN TEST - CONFIG FILE INPUT ----" << endl
            << "Reading from input file sample.config...\n" << endl;
    Simulation * simulation = ConfigReader::new_simulation_with_config("sample.config");
    cout << simulation << endl;
    cerr << "\n---- END TEST - CONFIG FILE INPUT ----\n" << endl;
    return;
}

void SPCERuntime::test_lammpstrj_output() {
    cerr << "---- BEGIN TEST - LAMMPSTRJ (VMD) FILE OUTPUT ----" << endl;
    Simulation * s = new Simulation();
    s->SAMPLER_SET->turn_on_lammpstrj_sampler();
    s->DATA_SAMPLING_RATE = 2;
    s->NUM_MC_SWEEPS = 10;
    s->run_mc();
    cerr << "\n---- END TEST - LAMMPSTRJ (VMD) FILE OUTPUT ----\n" << endl;
    return;
}

void SPCERuntime::test_config_output() {
    cerr << "---- BEGIN TEST - CONFIG FILE OUTPUT ----" << endl;
    Simulation * s = new Simulation();
    s->IONS[0]->charge = -1.0;
    s->IONS[1]->charge = 1.0;
    s->NUM_MC_SWEEPS = 10;
    s->turn_on_window_sampling_mc(9.12, 12.56);
    s->run_mc();
    s->SAMPLER_SET->write_config_snapshot();
    cerr << "\n---- END TEST - CONFIG FILE OUTPUT ----" << endl;
    return;
}

void SPCERuntime::test_radial_dist() {
    cerr << "---- BEGIN TEST - RADIAL DISTRIBUTION SAMPLER ----" << endl;
    Simulation * simulation = new Simulation();
    simulation->IONS[0]->charge = -1.0;
    simulation->IONS[1]->charge = 1.0;
    simulation->NUM_MC_SWEEPS = 50000;
    simulation->SAMPLER_SET->add_rdf_sampler();
    simulation->run_mc();
    simulation->SAMPLER_SET->print_individual_sampler_results();
    cerr << "\n---- END TEST - RADIAL DISTRIBUTION SAMPLER ----\n" << endl;
    return;
}

void SPCERuntime::test_ion_pair_dist() {
    cerr << "---- BEGIN TEST - ION PAIR DISTANCE SAMPLER ----" << endl;
    Simulation * simulation = new Simulation();
    simulation->IONS[0]->charge = -1.0;
    simulation->IONS[1]->charge = 1.0;
    simulation->NUM_MC_SWEEPS = 50000;
    simulation->SAMPLER_SET->add_ion_pair_distance_sampler();
    simulation->run_mc();
    simulation->SAMPLER_SET->print_individual_sampler_results();
    cerr << "---- END TEST - ION PAIR DISTANCE SAMPLER ----\n" << endl;
    return;
}

void SPCERuntime::test_water_rotation() {
    cerr << "---- BEGIN TEST - WATER ROTATION ----" << endl;
    double * coords = new double [9];
    coords[0] = 1.34;
    coords[1] = 2.0;
    coords[2] = 3.2;
    for (int i = 3; i < 9; i++)
        coords[i] = RAN3()*5.0;
    Water * w = new Water(coords, 0.2, 0.17, 20.0, 20.0);
    delete [] coords;
    for (int k = 0; k < 10000; k++) {
        w->mc_rotate();
        cout << w << endl;
    }
    cerr << "---- END TEST - WATER ROTATION ----\n" << endl;
    return;
}
<commit_msg>setting new window<commit_after>#include "common.h"

void SPCERuntime::run_umbrella_system() {
    cerr << "---- BEGIN - UMBRELLA SAMPLING ----" << endl;
    double window_lower_bound = 0.0, window_upper_bound = 2.0;
    Simulation * simulation = new Simulation();

    Ion * anion = simulation->IONS[0];
    Ion * cation = simulation->IONS[1];
    anion->charge = -1.0;
    cation->charge = 1.0;

    cerr << "Initializing anion-cation distance to be inside window [" << window_lower_bound << ", " << window_upper_bound << "] Angstroms......";
    while (anion->distance_from(cation) <= window_lower_bound or anion->distance_from(cation) > window_upper_bound)
        anion->set_random_coords();
    cerr << "done.\n" << endl;

    simulation->NUM_EQUILIBRATION_SWEEPS = 100000;
    simulation->turn_on_window_sampling_mc(window_lower_bound, window_upper_bound);
    simulation->equilibrate();

    simulation->SAMPLER_SET->turn_on_lammpstrj_sampler();
    simulation->SAMPLER_SET->add_ion_pair_distance_sampler();
    simulation->DATA_SAMPLING_RATE = 20;
    simulation->NUM_MC_SWEEPS = 500000;
    simulation->run_mc();

    simulation->SAMPLER_SET->write_config_snapshot();
    cerr << "\n---- END - UMBRELLA SAMPLING ----\n" << endl;
    return;
}

void SPCERuntime::run_all_tests(int argc, char** argv) {
    run_umbrella_system();
    //test_water_rotation();
    //test_lammpstrj_output();
    //test_config_output();
    //test_config_input();
    //test_radial_dist();
    //test_ion_pair_dist();
    return;
}

void SPCERuntime::test_config_input() {
    cerr << "---- BEGIN TEST - CONFIG FILE INPUT ----" << endl
            << "Reading from input file sample.config...\n" << endl;
    Simulation * simulation = ConfigReader::new_simulation_with_config("sample.config");
    cout << simulation << endl;
    cerr << "\n---- END TEST - CONFIG FILE INPUT ----\n" << endl;
    return;
}

void SPCERuntime::test_lammpstrj_output() {
    cerr << "---- BEGIN TEST - LAMMPSTRJ (VMD) FILE OUTPUT ----" << endl;
    Simulation * s = new Simulation();
    s->SAMPLER_SET->turn_on_lammpstrj_sampler();
    s->DATA_SAMPLING_RATE = 2;
    s->NUM_MC_SWEEPS = 10;
    s->run_mc();
    cerr << "\n---- END TEST - LAMMPSTRJ (VMD) FILE OUTPUT ----\n" << endl;
    return;
}

void SPCERuntime::test_config_output() {
    cerr << "---- BEGIN TEST - CONFIG FILE OUTPUT ----" << endl;
    Simulation * s = new Simulation();
    s->IONS[0]->charge = -1.0;
    s->IONS[1]->charge = 1.0;
    s->NUM_MC_SWEEPS = 10;
    s->turn_on_window_sampling_mc(9.12, 12.56);
    s->run_mc();
    s->SAMPLER_SET->write_config_snapshot();
    cerr << "\n---- END TEST - CONFIG FILE OUTPUT ----" << endl;
    return;
}

void SPCERuntime::test_radial_dist() {
    cerr << "---- BEGIN TEST - RADIAL DISTRIBUTION SAMPLER ----" << endl;
    Simulation * simulation = new Simulation();
    simulation->IONS[0]->charge = -1.0;
    simulation->IONS[1]->charge = 1.0;
    simulation->NUM_MC_SWEEPS = 50000;
    simulation->SAMPLER_SET->add_rdf_sampler();
    simulation->run_mc();
    simulation->SAMPLER_SET->print_individual_sampler_results();
    cerr << "\n---- END TEST - RADIAL DISTRIBUTION SAMPLER ----\n" << endl;
    return;
}

void SPCERuntime::test_ion_pair_dist() {
    cerr << "---- BEGIN TEST - ION PAIR DISTANCE SAMPLER ----" << endl;
    Simulation * simulation = new Simulation();
    simulation->IONS[0]->charge = -1.0;
    simulation->IONS[1]->charge = 1.0;
    simulation->NUM_MC_SWEEPS = 50000;
    simulation->SAMPLER_SET->add_ion_pair_distance_sampler();
    simulation->run_mc();
    simulation->SAMPLER_SET->print_individual_sampler_results();
    cerr << "---- END TEST - ION PAIR DISTANCE SAMPLER ----\n" << endl;
    return;
}

void SPCERuntime::test_water_rotation() {
    cerr << "---- BEGIN TEST - WATER ROTATION ----" << endl;
    double * coords = new double [9];
    coords[0] = 1.34;
    coords[1] = 2.0;
    coords[2] = 3.2;
    for (int i = 3; i < 9; i++)
        coords[i] = RAN3()*5.0;
    Water * w = new Water(coords, 0.2, 0.17, 20.0, 20.0);
    delete [] coords;
    for (int k = 0; k < 10000; k++) {
        w->mc_rotate();
        cout << w << endl;
    }
    cerr << "---- END TEST - WATER ROTATION ----\n" << endl;
    return;
}
<|endoftext|>


<commit_before>#include "DMWriteTask.h"

#include "DMUtil.h"
#include "SkColorPriv.h"
#include "SkCommonFlags.h"
#include "SkData.h"
#include "SkImageEncoder.h"
#include "SkMD5.h"
#include "SkMallocPixelRef.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "SkString.h"

DEFINE_bool(nameByHash, false, "If true, write .../hash.png instead of .../mode/config/name.png");

namespace DM {

// Splits off the last N suffixes of name (splitting on _) and appends them to out.
// Returns the total number of characters consumed.
static int split_suffixes(int N, const char* name, SkTArray<SkString>* out) {
    SkTArray<SkString> split;
    SkStrSplit(name, "_", &split);
    int consumed = 0;
    for (int i = 0; i < N; i++) {
        // We're splitting off suffixes from the back to front.
        out->push_back(split[split.count()-i-1]);
        consumed += out->back().size() + 1;  // Add one for the _.
    }
    return consumed;
}

inline static SkString find_base_name(const Task& parent, SkTArray<SkString>* suffixList) {
    const int suffixes = parent.depth() + 1;
    const SkString& name = parent.name();
    const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), suffixList);
    return SkString(name.c_str(), name.size() - totalSuffixLength);
}

WriteTask::WriteTask(const Task& parent, const char* sourceType, SkBitmap bitmap)
    : CpuTask(parent)
    , fBaseName(find_base_name(parent, &fSuffixes))
    , fSourceType(sourceType)
    , fBitmap(bitmap)
    , fData(NULL)
    , fExtension(".png") {
}

WriteTask::WriteTask(const Task& parent,
                     const char* sourceType,
                     SkStreamAsset *data,
                     const char* ext)
    : CpuTask(parent)
    , fBaseName(find_base_name(parent, &fSuffixes))
    , fSourceType(sourceType)
    , fData(data)
    , fExtension(ext) {
    SkASSERT(fData.get());
    SkASSERT(fData->unique());
}

void WriteTask::makeDirOrFail(SkString dir) {
    if (!sk_mkdir(dir.c_str())) {
        this->fail();
    }
}

static SkString get_md5_string(SkMD5* hasher) {
    SkMD5::Digest digest;
    hasher->finish(digest);

    SkString md5;
    for (int i = 0; i < 16; i++) {
        md5.appendf("%02x", digest.data[i]);
    }
    return md5;
}

static SkString get_md5(const void* ptr, size_t len) {
    SkMD5 hasher;
    hasher.write(ptr, len);
    return get_md5_string(&hasher);
}

static SkString get_md5(SkStreamAsset* stream) {
    SkMD5 hasher;
    hasher.writeStream(stream, stream->getLength());
    return get_md5_string(&hasher);
}

struct JsonData {
    SkString name;            // E.g. "ninepatch-stretch", "desk-gws_skp"
    SkString config;          //      "gpu", "8888"
    SkString mode;            //      "direct", "default-tilegrid", "pipe"
    SkString sourceType;      //      "GM", "SKP"
    SkString md5;             // In ASCII, so 32 bytes long.
};
SkTArray<JsonData> gJsonData;
SK_DECLARE_STATIC_MUTEX(gJsonDataLock);

void WriteTask::draw() {
    SkString md5;
    {
        SkAutoLockPixels lock(fBitmap);
        md5 = fData ? get_md5(fData)
                    : get_md5(fBitmap.getPixels(), fBitmap.getSize());
    }

    SkASSERT(fSuffixes.count() > 0);
    SkString config = fSuffixes.back();
    SkString mode("direct");
    if (fSuffixes.count() > 1) {
        mode = fSuffixes.fromBack(1);
    }

    JsonData entry = { fBaseName, config, mode, fSourceType, md5 };
    {
        SkAutoMutexAcquire lock(&gJsonDataLock);
        gJsonData.push_back(entry);
    }

    SkString dir(FLAGS_writePath[0]);
#if defined(SK_BUILD_FOR_IOS)
    if (dir.equals("@")) {
        dir.set(FLAGS_resourcePath[0]);
    }
#endif
    this->makeDirOrFail(dir);

    SkString path;
    if (FLAGS_nameByHash) {
        // Flat directory of hash-named files.
        path = SkOSPath::Join(dir.c_str(), md5.c_str());
        path.append(fExtension);
        // We're content-addressed, so it's possible two threads race to write
        // this file.  We let the first one win.  This also means we won't
        // overwrite identical files from previous runs.
        if (sk_exists(path.c_str())) {
            return;
        }
    } else {
        // Nested by mode, config, etc.
        for (int i = 0; i < fSuffixes.count(); i++) {
            dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str());
            this->makeDirOrFail(dir);
        }
        path = SkOSPath::Join(dir.c_str(), fBaseName.c_str());
        path.append(fExtension);
        // The path is unique, so two threads can't both write to the same file.
        // If already present we overwrite here, since the content may have changed.
    }

    SkFILEWStream file(path.c_str());
    if (!file.isValid()) {
        return this->fail("Can't open file.");
    }

    bool ok = fData ? file.writeStream(fData, fData->getLength())
                    : SkImageEncoder::EncodeStream(&file, fBitmap, SkImageEncoder::kPNG_Type, 100);
    if (!ok) {
        return this->fail("Can't write to file.");
    }
}

SkString WriteTask::name() const {
    SkString name("writing ");
    for (int i = 0; i < fSuffixes.count(); i++) {
        name.appendf("%s/", fSuffixes[i].c_str());
    }
    name.append(fBaseName.c_str());
    return name;
}

bool WriteTask::shouldSkip() const {
    return FLAGS_writePath.isEmpty();
}

void WriteTask::DumpJson() {
    if (FLAGS_writePath.isEmpty()) {
        return;
    }

    Json::Value root;

    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
        root[FLAGS_properties[i-1]] = FLAGS_properties[i];
    }
    for (int i = 1; i < FLAGS_key.count(); i += 2) {
        root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
    }

    {
        SkAutoMutexAcquire lock(&gJsonDataLock);
        for (int i = 0; i < gJsonData.count(); i++) {
            Json::Value result;
            result["key"]["name"]            = gJsonData[i].name.c_str();
            result["key"]["config"]          = gJsonData[i].config.c_str();
            result["key"]["mode"]            = gJsonData[i].mode.c_str();
            result["options"]["source_type"] = gJsonData[i].sourceType.c_str();
            result["md5"]                    = gJsonData[i].md5.c_str();

            root["results"].append(result);
        }
    }

    SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
    SkFILEWStream stream(path.c_str());
    stream.writeText(Json::StyledWriter().write(root).c_str());
    stream.flush();
}

}  // namespace DM
<commit_msg>Fix DMWriteTask to write PDF files correctly<commit_after>#include "DMWriteTask.h"

#include "DMUtil.h"
#include "SkColorPriv.h"
#include "SkCommonFlags.h"
#include "SkData.h"
#include "SkImageEncoder.h"
#include "SkMD5.h"
#include "SkMallocPixelRef.h"
#include "SkOSFile.h"
#include "SkStream.h"
#include "SkString.h"

DEFINE_bool(nameByHash, false, "If true, write .../hash.png instead of .../mode/config/name.png");

namespace DM {

// Splits off the last N suffixes of name (splitting on _) and appends them to out.
// Returns the total number of characters consumed.
static int split_suffixes(int N, const char* name, SkTArray<SkString>* out) {
    SkTArray<SkString> split;
    SkStrSplit(name, "_", &split);
    int consumed = 0;
    for (int i = 0; i < N; i++) {
        // We're splitting off suffixes from the back to front.
        out->push_back(split[split.count()-i-1]);
        consumed += out->back().size() + 1;  // Add one for the _.
    }
    return consumed;
}

inline static SkString find_base_name(const Task& parent, SkTArray<SkString>* suffixList) {
    const int suffixes = parent.depth() + 1;
    const SkString& name = parent.name();
    const int totalSuffixLength = split_suffixes(suffixes, name.c_str(), suffixList);
    return SkString(name.c_str(), name.size() - totalSuffixLength);
}

WriteTask::WriteTask(const Task& parent, const char* sourceType, SkBitmap bitmap)
    : CpuTask(parent)
    , fBaseName(find_base_name(parent, &fSuffixes))
    , fSourceType(sourceType)
    , fBitmap(bitmap)
    , fData(NULL)
    , fExtension(".png") {
}

WriteTask::WriteTask(const Task& parent,
                     const char* sourceType,
                     SkStreamAsset *data,
                     const char* ext)
    : CpuTask(parent)
    , fBaseName(find_base_name(parent, &fSuffixes))
    , fSourceType(sourceType)
    , fData(data)
    , fExtension(ext) {
    SkASSERT(fData.get());
    SkASSERT(fData->unique());
}

void WriteTask::makeDirOrFail(SkString dir) {
    if (!sk_mkdir(dir.c_str())) {
        this->fail();
    }
}

static SkString get_md5_string(SkMD5* hasher) {
    SkMD5::Digest digest;
    hasher->finish(digest);

    SkString md5;
    for (int i = 0; i < 16; i++) {
        md5.appendf("%02x", digest.data[i]);
    }
    return md5;
}

static SkString get_md5(const void* ptr, size_t len) {
    SkMD5 hasher;
    hasher.write(ptr, len);
    return get_md5_string(&hasher);
}

static bool write_asset(SkStreamAsset* input, SkWStream* output) {
    return input->rewind() && output->writeStream(input, input->getLength());
}

static SkString get_md5(SkStreamAsset* stream) {
    SkMD5 hasher;
    write_asset(stream, &hasher);
    return get_md5_string(&hasher);
}

struct JsonData {
    SkString name;            // E.g. "ninepatch-stretch", "desk-gws_skp"
    SkString config;          //      "gpu", "8888"
    SkString mode;            //      "direct", "default-tilegrid", "pipe"
    SkString sourceType;      //      "GM", "SKP"
    SkString md5;             // In ASCII, so 32 bytes long.
};
SkTArray<JsonData> gJsonData;
SK_DECLARE_STATIC_MUTEX(gJsonDataLock);

void WriteTask::draw() {
    SkString md5;
    {
        SkAutoLockPixels lock(fBitmap);
        md5 = fData ? get_md5(fData)
                    : get_md5(fBitmap.getPixels(), fBitmap.getSize());
    }

    SkASSERT(fSuffixes.count() > 0);
    SkString config = fSuffixes.back();
    SkString mode("direct");
    if (fSuffixes.count() > 1) {
        mode = fSuffixes.fromBack(1);
    }

    JsonData entry = { fBaseName, config, mode, fSourceType, md5 };
    {
        SkAutoMutexAcquire lock(&gJsonDataLock);
        gJsonData.push_back(entry);
    }

    SkString dir(FLAGS_writePath[0]);
#if defined(SK_BUILD_FOR_IOS)
    if (dir.equals("@")) {
        dir.set(FLAGS_resourcePath[0]);
    }
#endif
    this->makeDirOrFail(dir);

    SkString path;
    if (FLAGS_nameByHash) {
        // Flat directory of hash-named files.
        path = SkOSPath::Join(dir.c_str(), md5.c_str());
        path.append(fExtension);
        // We're content-addressed, so it's possible two threads race to write
        // this file.  We let the first one win.  This also means we won't
        // overwrite identical files from previous runs.
        if (sk_exists(path.c_str())) {
            return;
        }
    } else {
        // Nested by mode, config, etc.
        for (int i = 0; i < fSuffixes.count(); i++) {
            dir = SkOSPath::Join(dir.c_str(), fSuffixes[i].c_str());
            this->makeDirOrFail(dir);
        }
        path = SkOSPath::Join(dir.c_str(), fBaseName.c_str());
        path.append(fExtension);
        // The path is unique, so two threads can't both write to the same file.
        // If already present we overwrite here, since the content may have changed.
    }

    SkFILEWStream file(path.c_str());
    if (!file.isValid()) {
        return this->fail("Can't open file.");
    }

    bool ok = fData ? write_asset(fData, &file)
                    : SkImageEncoder::EncodeStream(&file, fBitmap, SkImageEncoder::kPNG_Type, 100);
    if (!ok) {
        return this->fail("Can't write to file.");
    }
}

SkString WriteTask::name() const {
    SkString name("writing ");
    for (int i = 0; i < fSuffixes.count(); i++) {
        name.appendf("%s/", fSuffixes[i].c_str());
    }
    name.append(fBaseName.c_str());
    return name;
}

bool WriteTask::shouldSkip() const {
    return FLAGS_writePath.isEmpty();
}

void WriteTask::DumpJson() {
    if (FLAGS_writePath.isEmpty()) {
        return;
    }

    Json::Value root;

    for (int i = 1; i < FLAGS_properties.count(); i += 2) {
        root[FLAGS_properties[i-1]] = FLAGS_properties[i];
    }
    for (int i = 1; i < FLAGS_key.count(); i += 2) {
        root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
    }

    {
        SkAutoMutexAcquire lock(&gJsonDataLock);
        for (int i = 0; i < gJsonData.count(); i++) {
            Json::Value result;
            result["key"]["name"]            = gJsonData[i].name.c_str();
            result["key"]["config"]          = gJsonData[i].config.c_str();
            result["key"]["mode"]            = gJsonData[i].mode.c_str();
            result["options"]["source_type"] = gJsonData[i].sourceType.c_str();
            result["md5"]                    = gJsonData[i].md5.c_str();

            root["results"].append(result);
        }
    }

    SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
    SkFILEWStream stream(path.c_str());
    stream.writeText(Json::StyledWriter().write(root).c_str());
    stream.flush();
}

}  // namespace DM
<|endoftext|>


<commit_before><commit_msg>simplify size calculation<commit_after><|endoftext|>


<commit_before>#include "gtest/gtest.h"

#include "string-util/main.h"
#include "builtins/main.h"
#include "file/main.h"
#include "result-tree/main.h"
#include "node-util/main.h"
#include "parser/main.h"

int main(int argc, char ** argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<commit_msg>remove outdated result-tree tests<commit_after>#include "gtest/gtest.h"

#include "string-util/main.h"
#include "builtins/main.h"
#include "file/main.h"
#include "node-util/main.h"
#include "parser/main.h"

int main(int argc, char ** argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

<|endoftext|>


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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qapplication.h>
#include <qlayout.h>
#include <q3progressbar.h>
#include <qtimer.h>
#include <q3header.h>
#include <qobject.h>
#include <q3scrollview.h>
#include <qtoolbutton.h>
#include <qpushbutton.h>
#include <q3vbox.h>
#include <qtooltip.h>
//Added by qt3to4:
#include <QCloseEvent>
#include <QEvent>
#include <Q3Frame>
#include <QLabel>

#include <klocale.h>
#include <kdialog.h>
#include <kstdguiitem.h>
#include <kiconloader.h>
#include <kdebug.h>

#include "progressdialog.h"
#include "progressmanager.h"
#include "ssllabel.h"
#include <q3whatsthis.h>

namespace KPIM {

class TransactionItem;

TransactionItemView::TransactionItemView( QWidget * parent,
                                          const char * name,
                                          Qt::WFlags f )
    : Q3ScrollView( parent, name, f ) {
  setFrameStyle( NoFrame );
  mBigBox = new Q3VBox( viewport() );
  mBigBox->setSpacing( 5 );
  addChild( mBigBox );
  setResizePolicy( Q3ScrollView::AutoOneFit ); // Fit so that the box expands horizontally
}

TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
{
   TransactionItem *ti = new TransactionItem( mBigBox, item, first );
   ti->hide();
   QTimer::singleShot( 1000, ti, SLOT( show() ) );
   return ti;
}

void TransactionItemView::resizeContents( int w, int h )
{
  //kdDebug(5300) << k_funcinfo << w << "," << h << endl;
  Q3ScrollView::resizeContents( w, h );
  // Tell the layout in the parent (progressdialog) that our size changed
  updateGeometry();
  // Resize the parent (progressdialog) - this works but resize horizontally too often
  //parentWidget()->adjustSize();

  QApplication::sendPostedEvents( 0, QEvent::ChildInserted );
  QApplication::sendPostedEvents( 0, QEvent::LayoutHint );
  QSize sz = parentWidget()->sizeHint();
  int currentWidth = parentWidget()->width();
  // Don't resize to sz.width() every time when it only reduces a little bit
  if ( currentWidth < sz.width() || currentWidth > sz.width() + 100 )
    currentWidth = sz.width();
  parentWidget()->resize( currentWidth, sz.height() );
}

QSize TransactionItemView::sizeHint() const
{
  return minimumSizeHint();
}

QSize TransactionItemView::minimumSizeHint() const
{
  int f = 2 * frameWidth();
  // Make room for a vertical scrollbar in all cases, to avoid a horizontal one
  int vsbExt = verticalScrollBar()->sizeHint().width();
  int minw = topLevelWidget()->width() / 3;
  int maxh = topLevelWidget()->height() / 2;
  QSize sz( mBigBox->minimumSizeHint() );
  sz.setWidth( QMAX( sz.width(), minw ) + f + vsbExt );
  sz.setHeight( QMIN( sz.height(), maxh ) + f );
  return sz;
}

void TransactionItemView::slotLayoutFirstItem()
{
  /*
     The below relies on some details in Qt's behaviour regarding deleting
     objects. This slot is called from the destroyed signal of an item just
     going away. That item is at that point still in the  list of chilren, but
     since the vtable is already gone, it will have type QObject. The first
     one with both the right name and the right class therefor is what will
     be the first item very shortly. That's the one we want to remove the
     hline for.
  */
  QObject *o = mBigBox->child( "TransactionItem", "KPIM::TransactionItem" );
  TransactionItem *ti = dynamic_cast<TransactionItem*>( o );
  if ( ti ) {
    ti->hideHLine();
  }
}

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

TransactionItem::TransactionItem( QWidget* parent,
                                  ProgressItem *item, bool first )
  : Q3VBox( parent, "TransactionItem" ), mCancelButton( 0 ), mItem( item )

{
  setSpacing( 2 );
  setMargin( 2 );
  setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );

  mFrame = new Q3Frame( this );
  mFrame->setFrameShape( Q3Frame::HLine );
  mFrame->setFrameShadow( Q3Frame::Raised );
  mFrame->show();
  setStretchFactor( mFrame, 3 );

  Q3HBox *h = new Q3HBox( this );
  h->setSpacing( 5 );

  mItemLabel = new QLabel( item->label(), h );
  h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );

  mProgress = new Q3ProgressBar( 100, h );
  mProgress->setProgress( item->progress() );

  if ( item->canBeCanceled() ) {
    mCancelButton = new QPushButton( SmallIcon( "cancel" ), QString::null, h );
    QToolTip::add( mCancelButton, i18n("Cancel this operation.") );
    connect ( mCancelButton, SIGNAL( clicked() ),
              this, SLOT( slotItemCanceled() ));
  }

  h = new Q3HBox( this );
  h->setSpacing( 5 );
  h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
  mSSLLabel = new SSLLabel( h );
  mSSLLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
  mItemStatus =  new QLabel( item->status(), h );
  setCrypto( item->usesCrypto() );
  if( first ) hideHLine();
}

TransactionItem::~TransactionItem()
{
}

void TransactionItem::hideHLine()
{
    mFrame->hide();
}

void TransactionItem::setProgress( int progress )
{
  mProgress->setProgress( progress );
}

void TransactionItem::setLabel( const QString& label )
{
  mItemLabel->setText( label );
}

void TransactionItem::setStatus( const QString& status )
{
  mItemStatus->setText( status );
}

void TransactionItem::setCrypto( bool on )
{
  if (on)
    mSSLLabel->setEncrypted( true );
  else
    mSSLLabel->setEncrypted( false );

  mSSLLabel->setState( mSSLLabel->lastState() );
}

void TransactionItem::slotItemCanceled()
{
  if ( mItem )
    mItem->cancel();
}

void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
{

}

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

ProgressDialog::ProgressDialog( QWidget* alignWidget, QWidget* parent, const char* name )
    : OverlayWidget( alignWidget, parent, name ), mWasLastShown( false )
{
    setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken ); // QFrame
    setSpacing( 0 ); // QHBox
    setMargin( 1 );

    mScrollView = new TransactionItemView( this, "ProgressScrollView" );

    // No more close button for now, since there is no more autoshow
    /*
    QVBox* rightBox = new QVBox( this );
    QToolButton* pbClose = new QToolButton( rightBox );
    pbClose->setAutoRaise(true);
    pbClose->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
    pbClose->setFixedSize( 16, 16 );
    pbClose->setIconSet( KGlobal::iconLoader()->loadIconSet( "fileclose", KIcon::Small, 14 ) );
    QToolTip::add( pbClose, i18n( "Hide detailed progress window" ) );
    connect(pbClose, SIGNAL(clicked()), this, SLOT(slotClose()));
    QWidget* spacer = new QWidget( rightBox ); // don't let the close button take up all the height
    rightBox->setStretchFactor( spacer, 100 );
    */

    /*
     * Get the singleton ProgressManager item which will inform us of
     * appearing and vanishing items.
     */
    ProgressManager *pm = ProgressManager::instance();
    connect ( pm, SIGNAL( progressItemAdded( KPIM::ProgressItem* ) ),
              this, SLOT( slotTransactionAdded( KPIM::ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemCompleted( KPIM::ProgressItem* ) ),
              this, SLOT( slotTransactionCompleted( KPIM::ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemProgress( KPIM::ProgressItem*, unsigned int ) ),
              this, SLOT( slotTransactionProgress( KPIM::ProgressItem*, unsigned int ) ) );
    connect ( pm, SIGNAL( progressItemStatus( KPIM::ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionStatus( KPIM::ProgressItem*, const QString& ) ) );
    connect ( pm, SIGNAL( progressItemLabel( KPIM::ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionLabel( KPIM::ProgressItem*, const QString& ) ) );
    connect ( pm, SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ),
              this, SLOT( slotTransactionUsesCrypto( KPIM::ProgressItem*, bool ) ) );
    connect ( pm, SIGNAL( showProgressDialog() ),
              this, SLOT( slotShow() ) );
}

void ProgressDialog::closeEvent( QCloseEvent* e )
{
  e->accept();
  hide();
}

/*
 *  Destructor
 */
ProgressDialog::~ProgressDialog()
{
    // no need to delete child widgets.
}

void ProgressDialog::slotTransactionAdded( ProgressItem *item )
{
   TransactionItem *parent = 0;
   if ( item->parent() ) {
     if ( mTransactionsToListviewItems.contains( item->parent() ) ) {
       parent = mTransactionsToListviewItems[ item->parent() ];
       parent->addSubTransaction( item );
     }
   } else {
     const bool first = mTransactionsToListviewItems.empty();
     TransactionItem *ti = mScrollView->addTransactionItem( item, first );
     if ( ti )
       mTransactionsToListviewItems.replace( item, ti );
     if ( first && mWasLastShown )
       QTimer::singleShot( 1000, this, SLOT( slotShow() ) );

   }
}

void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     mTransactionsToListviewItems.remove( item );
     ti->setItemComplete();
     QTimer::singleShot( 3000, ti, SLOT( deleteLater() ) );
     // see the slot for comments as to why that works
     connect ( ti, SIGNAL( destroyed() ),
               mScrollView, SLOT( slotLayoutFirstItem() ) );
   }
   // This was the last item, hide.
   if ( mTransactionsToListviewItems.empty() )
     QTimer::singleShot( 3000, this, SLOT( slotHide() ) );
}

void ProgressDialog::slotTransactionCanceled( ProgressItem* )
{
}

void ProgressDialog::slotTransactionProgress( ProgressItem *item,
                                              unsigned int progress )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setProgress( progress );
   }
}

void ProgressDialog::slotTransactionStatus( ProgressItem *item,
                                            const QString& status )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setStatus( status );
   }
}

void ProgressDialog::slotTransactionLabel( ProgressItem *item,
                                           const QString& label )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setLabel( label );
   }
}

void ProgressDialog::slotTransactionUsesCrypto( ProgressItem *item,
                                                bool value )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setCrypto( value );
   }
}

void ProgressDialog::slotShow()
{
   setVisible( true );
}

void ProgressDialog::slotHide()
{
  // check if a new item showed up since we started the timer. If not, hide
  if ( mTransactionsToListviewItems.isEmpty() ) {
    setVisible( false );
  }
}

void ProgressDialog::slotClose()
{
  mWasLastShown = false;
  setVisible( false );
}

void ProgressDialog::setVisible( bool b )
{
  if ( b )
    show();
  else
    hide();
  emit visibilityChanged( b );
}

void ProgressDialog::slotToggleVisibility()
{
  /* Since we are only hiding with a timeout, there is a short period of
   * time where the last item is still visible, but clicking on it in
   * the statusbarwidget should not display the dialog, because there
   * are no items to be shown anymore. Guard against that.
   */
  mWasLastShown = !isShown();
  if ( isShown() || !mTransactionsToListviewItems.isEmpty() )
    setVisible( !isShown() );
}

}

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

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qapplication.h>
#include <qlayout.h>
#include <q3progressbar.h>
#include <qtimer.h>
#include <q3header.h>
#include <qobject.h>
#include <q3scrollview.h>
#include <qtoolbutton.h>
#include <qpushbutton.h>
#include <q3vbox.h>
#include <qtooltip.h>
//Added by qt3to4:
#include <QCloseEvent>
#include <QEvent>
#include <Q3Frame>
#include <QLabel>

#include <klocale.h>
#include <kdialog.h>
#include <kstdguiitem.h>
#include <kiconloader.h>
#include <kdebug.h>

#include "progressdialog.h"
#include "progressmanager.h"
#include "ssllabel.h"
#include <q3whatsthis.h>

namespace KPIM {

class TransactionItem;

TransactionItemView::TransactionItemView( QWidget * parent,
                                          const char * name,
                                          Qt::WFlags f )
    : Q3ScrollView( parent, name, f ) {
  setFrameStyle( NoFrame );
  mBigBox = new Q3VBox( viewport() );
  mBigBox->setSpacing( 5 );
  addChild( mBigBox );
  setResizePolicy( Q3ScrollView::AutoOneFit ); // Fit so that the box expands horizontally
}

TransactionItem* TransactionItemView::addTransactionItem( ProgressItem* item, bool first )
{
   TransactionItem *ti = new TransactionItem( mBigBox, item, first );
   ti->hide();
   QTimer::singleShot( 1000, ti, SLOT( show() ) );
   return ti;
}

void TransactionItemView::resizeContents( int w, int h )
{
  //kdDebug(5300) << k_funcinfo << w << "," << h << endl;
  Q3ScrollView::resizeContents( w, h );
  // Tell the layout in the parent (progressdialog) that our size changed
  updateGeometry();
  // Resize the parent (progressdialog) - this works but resize horizontally too often
  //parentWidget()->adjustSize();

  QApplication::sendPostedEvents( 0, QEvent::ChildInserted );
  QApplication::sendPostedEvents( 0, QEvent::LayoutHint );
  QSize sz = parentWidget()->sizeHint();
  int currentWidth = parentWidget()->width();
  // Don't resize to sz.width() every time when it only reduces a little bit
  if ( currentWidth < sz.width() || currentWidth > sz.width() + 100 )
    currentWidth = sz.width();
  parentWidget()->resize( currentWidth, sz.height() );
}

QSize TransactionItemView::sizeHint() const
{
  return minimumSizeHint();
}

QSize TransactionItemView::minimumSizeHint() const
{
  int f = 2 * frameWidth();
  // Make room for a vertical scrollbar in all cases, to avoid a horizontal one
  int vsbExt = verticalScrollBar()->sizeHint().width();
  int minw = topLevelWidget()->width() / 3;
  int maxh = topLevelWidget()->height() / 2;
  QSize sz( mBigBox->minimumSizeHint() );
  sz.setWidth( QMAX( sz.width(), minw ) + f + vsbExt );
  sz.setHeight( QMIN( sz.height(), maxh ) + f );
  return sz;
}

void TransactionItemView::slotLayoutFirstItem()
{
  /*
     The below relies on some details in Qt's behaviour regarding deleting
     objects. This slot is called from the destroyed signal of an item just
     going away. That item is at that point still in the  list of chilren, but
     since the vtable is already gone, it will have type QObject. The first
     one with both the right name and the right class therefor is what will
     be the first item very shortly. That's the one we want to remove the
     hline for.
  */
  QObject *o = mBigBox->child( "TransactionItem", "KPIM::TransactionItem" );
  TransactionItem *ti = dynamic_cast<TransactionItem*>( o );
  if ( ti ) {
    ti->hideHLine();
  }
}

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

TransactionItem::TransactionItem( QWidget* parent,
                                  ProgressItem *item, bool first )
  : Q3VBox( parent, "TransactionItem" ), mCancelButton( 0 ), mItem( item )

{
  setSpacing( 2 );
  setMargin( 2 );
  setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );

  mFrame = new Q3Frame( this );
  mFrame->setFrameShape( Q3Frame::HLine );
  mFrame->setFrameShadow( Q3Frame::Raised );
  mFrame->show();
  setStretchFactor( mFrame, 3 );

  Q3HBox *h = new Q3HBox( this );
  h->setSpacing( 5 );

  mItemLabel = new QLabel( item->label(), h );
  h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );

  mProgress = new Q3ProgressBar( 100, h );
  mProgress->setProgress( item->progress() );

  if ( item->canBeCanceled() ) {
    mCancelButton = new QPushButton( SmallIcon( "cancel" ), QString::null, h );
    QToolTip::add( mCancelButton, i18n("Cancel this operation.") );
    connect ( mCancelButton, SIGNAL( clicked() ),
              this, SLOT( slotItemCanceled() ));
  }

  h = new Q3HBox( this );
  h->setSpacing( 5 );
  h->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) );
  mSSLLabel = new SSLLabel( h );
  mSSLLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
  mItemStatus =  new QLabel( item->status(), h );
  setCrypto( item->usesCrypto() );
  if( first ) hideHLine();
}

TransactionItem::~TransactionItem()
{
}

void TransactionItem::hideHLine()
{
    mFrame->hide();
}

void TransactionItem::setProgress( int progress )
{
  mProgress->setProgress( progress );
}

void TransactionItem::setLabel( const QString& label )
{
  mItemLabel->setText( label );
}

void TransactionItem::setStatus( const QString& status )
{
  mItemStatus->setText( status );
}

void TransactionItem::setCrypto( bool on )
{
  if (on)
    mSSLLabel->setEncrypted( true );
  else
    mSSLLabel->setEncrypted( false );

  mSSLLabel->setState( mSSLLabel->lastState() );
}

void TransactionItem::slotItemCanceled()
{
  if ( mItem )
    mItem->cancel();
}

void TransactionItem::addSubTransaction( ProgressItem* /*item*/ )
{

}

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

ProgressDialog::ProgressDialog( QWidget* alignWidget, QWidget* parent, const char* name )
    : OverlayWidget( alignWidget, parent, name ), mWasLastShown( false )
{
    setFrameStyle( Q3Frame::Panel | Q3Frame::Sunken ); // QFrame
    setSpacing( 0 ); // QHBox
    setMargin( 1 );

    mScrollView = new TransactionItemView( this, "ProgressScrollView" );

    // No more close button for now, since there is no more autoshow
    /*
    QVBox* rightBox = new QVBox( this );
    QToolButton* pbClose = new QToolButton( rightBox );
    pbClose->setAutoRaise(true);
    pbClose->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
    pbClose->setFixedSize( 16, 16 );
    pbClose->setIconSet( KGlobal::iconLoader()->loadIconSet( "fileclose", KIcon::Small, 14 ) );
    QToolTip::add( pbClose, i18n( "Hide detailed progress window" ) );
    connect(pbClose, SIGNAL(clicked()), this, SLOT(slotClose()));
    QWidget* spacer = new QWidget( rightBox ); // don't let the close button take up all the height
    rightBox->setStretchFactor( spacer, 100 );
    */

    /*
     * Get the singleton ProgressManager item which will inform us of
     * appearing and vanishing items.
     */
    ProgressManager *pm = ProgressManager::instance();
    connect ( pm, SIGNAL( progressItemAdded( KPIM::ProgressItem* ) ),
              this, SLOT( slotTransactionAdded( KPIM::ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemCompleted( KPIM::ProgressItem* ) ),
              this, SLOT( slotTransactionCompleted( KPIM::ProgressItem* ) ) );
    connect ( pm, SIGNAL( progressItemProgress( KPIM::ProgressItem*, unsigned int ) ),
              this, SLOT( slotTransactionProgress( KPIM::ProgressItem*, unsigned int ) ) );
    connect ( pm, SIGNAL( progressItemStatus( KPIM::ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionStatus( KPIM::ProgressItem*, const QString& ) ) );
    connect ( pm, SIGNAL( progressItemLabel( KPIM::ProgressItem*, const QString& ) ),
              this, SLOT( slotTransactionLabel( KPIM::ProgressItem*, const QString& ) ) );
    connect ( pm, SIGNAL( progressItemUsesCrypto(KPIM::ProgressItem*, bool) ),
              this, SLOT( slotTransactionUsesCrypto( KPIM::ProgressItem*, bool ) ) );
    connect ( pm, SIGNAL( showProgressDialog() ),
              this, SLOT( slotShow() ) );
}

void ProgressDialog::closeEvent( QCloseEvent* e )
{
  e->accept();
  hide();
}

/*
 *  Destructor
 */
ProgressDialog::~ProgressDialog()
{
    // no need to delete child widgets.
}

void ProgressDialog::slotTransactionAdded( ProgressItem *item )
{
   TransactionItem *parent = 0;
   if ( item->parent() ) {
     if ( mTransactionsToListviewItems.contains( item->parent() ) ) {
       parent = mTransactionsToListviewItems[ item->parent() ];
       parent->addSubTransaction( item );
     }
   } else {
     const bool first = mTransactionsToListviewItems.empty();
     TransactionItem *ti = mScrollView->addTransactionItem( item, first );
     if ( ti )
       mTransactionsToListviewItems.replace( item, ti );
     if ( first && mWasLastShown )
       QTimer::singleShot( 1000, this, SLOT( slotShow() ) );

   }
}

void ProgressDialog::slotTransactionCompleted( ProgressItem *item )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     mTransactionsToListviewItems.remove( item );
     ti->setItemComplete();
     QTimer::singleShot( 3000, ti, SLOT( deleteLater() ) );
     // see the slot for comments as to why that works
     connect ( ti, SIGNAL( destroyed() ),
               mScrollView, SLOT( slotLayoutFirstItem() ) );
   }
   // This was the last item, hide.
   if ( mTransactionsToListviewItems.empty() )
     QTimer::singleShot( 3000, this, SLOT( slotHide() ) );
}

void ProgressDialog::slotTransactionCanceled( ProgressItem* )
{
}

void ProgressDialog::slotTransactionProgress( ProgressItem *item,
                                              unsigned int progress )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setProgress( progress );
   }
}

void ProgressDialog::slotTransactionStatus( ProgressItem *item,
                                            const QString& status )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setStatus( status );
   }
}

void ProgressDialog::slotTransactionLabel( ProgressItem *item,
                                           const QString& label )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setLabel( label );
   }
}

void ProgressDialog::slotTransactionUsesCrypto( ProgressItem *item,
                                                bool value )
{
   if ( mTransactionsToListviewItems.contains( item ) ) {
     TransactionItem *ti = mTransactionsToListviewItems[ item ];
     ti->setCrypto( value );
   }
}

void ProgressDialog::slotShow()
{
   setVisible( true );
}

void ProgressDialog::slotHide()
{
  // check if a new item showed up since we started the timer. If not, hide
  if ( mTransactionsToListviewItems.isEmpty() ) {
    setVisible( false );
  }
}

void ProgressDialog::slotClose()
{
  mWasLastShown = false;
  setVisible( false );
}

void ProgressDialog::setVisible( bool b )
{
  OverlayWidget::setVisible( b );
  emit visibilityChanged( b );
}

void ProgressDialog::slotToggleVisibility()
{
  /* Since we are only hiding with a timeout, there is a short period of
   * time where the last item is still visible, but clicking on it in
   * the statusbarwidget should not display the dialog, because there
   * are no items to be shown anymore. Guard against that.
   */
  mWasLastShown = !isShown();
  if ( isShown() || !mTransactionsToListviewItems.isEmpty() )
    setVisible( !isShown() );
}

}

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


<commit_before>/*
    Copyright (C) <2010>  Michael Zanetti <michael_zanetti@gmx.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

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

*/

#include "remote.h"

#include <KLocale>
#include <kdebug.h>

class ModeChangeHandler{
  public:
      virtual  bool isButtonModechange(const Remote *remote, const QString &button ) =0;
      virtual  void nextMode(Remote *remote, const QString &button)=0;
};

class GroupModechangehandler : public ModeChangeHandler{

  bool isButtonModechange(const Remote* remote, const QString& button) {
    foreach(Mode *mode, remote->m_modeList){
      if(mode->button() == button && ! (mode == remote->currentMode())){
	return true;
      }
    }
    return false;
  }

  void nextMode(Remote* remote, const QString& button) {
    int found=remote->m_modeList.indexOf(remote->currentMode());
    Mode *mode =0;
    for(int i = found +1; i < remote->m_modeList.size(); ++i){
      if(remote->m_modeList.at(found)->button() == button){
	mode = remote->m_modeList.at(found);
      }
    }
    if(mode== 0){
      for(int i = 0; i < found; ++i){
	if(remote->m_modeList.at(found)->button() == button){
	  mode = remote->m_modeList.at(found);
	}
      }
    }
    if(mode){
      remote->setCurrentMode(mode);
    }
  }
};

Remote::Remote() {
    // Always create the Master Mode and set it default
    Mode *masterMode = new Mode("Master");
    addMode(masterMode);
    setDefaultMode(masterMode);
    m_modechangeHandler = new GroupModechangehandler();
}

Remote::Remote(const QString &remote, const QList<Mode*> &modes) {
    m_modeList = modes;
    m_remoteName = remote;

    // Always create the Master Mode and set it default
    bool hasMaster = false;
    foreach(Mode *mode, m_modeList){
        if(mode->name() == "Master"){
            hasMaster = true;
            break;
        }
    }
    if(!hasMaster){
        Mode *masterMode = new Mode("Master");
        addMode(masterMode);
        setDefaultMode(masterMode);
    }

}

QString Remote::name() const {
  return m_remoteName;
}

QList<Mode*> Remote::allModes() const {
  return m_modeList;
}

void Remote::addMode(Mode *mode) {
  m_modeList.append(mode);
}

void Remote::removeMode(Mode *mode) {
    if(mode->name() == "Master"){
        kDebug() << "cannot delete the Master mode";
        return;
    }

    if(m_defaultMode == mode){
        // Deleting the Default Mode... Setting Master Mode to default
        foreach(Mode *tmp, m_modeList){
            if(tmp->name() == "Master"){
                m_defaultMode = tmp;
                break;
            }
        }
    }
    m_modeList.removeAll(mode);
}

Mode* Remote::masterMode() const {
    foreach(Mode *mode, m_modeList){
        kDebug() << "checking Mode" << mode->name();
        if(mode->name() == "Master"){
            return mode;
        }
    }
    kDebug() << "Master mode not found";
    // Huh??? No Master Mode? Should never happen as removeMode() doesn't delete the Master mode
    // and all ctors create a Master Mode...
    return 0;
}

Mode *Remote::defaultMode() const {
    return m_defaultMode;
}

void Remote::setDefaultMode(Mode *mode) {
    if(!m_modeList.contains(mode)){
        m_modeList.append(mode);
    }
    m_defaultMode = mode;
}

void Remote::setDefaultMode(const QString &modeName){
    foreach(Mode *mode, m_modeList){
        if(mode->name() == modeName){
            setDefaultMode(mode);
            return;
        }
    }
}

Mode* Remote::currentMode() const {
    if(m_currentMode != 0){
        return m_currentMode;
    }
    return m_defaultMode;
}

void Remote::setCurrentMode(Mode* mode) {
    m_currentMode = mode;
}

bool Remote::isAvailable() const {
    return Solid::Control::RemoteControl::allRemoteNames().contains(m_remoteName);
}

bool Remote::isButtonModechange(const QString& button) {
  return m_modechangeHandler->isButtonModechange(this,button);
}

void Remote::nextMode ( const QString& button ){
  m_modechangeHandler->nextMode(this, button);
}

<commit_msg>introduced modechangehandler<commit_after>/*
    Copyright (C) <2010>  Michael Zanetti <michael_zanetti@gmx.net>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

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

*/

#include "remote.h"

#include <KLocale>
#include <kdebug.h>

class ModeChangeHandler{
  public:
      virtual  bool isButtonModechange(const Remote *remote, const QString &button ) =0;
      virtual  void nextMode(Remote *remote, const QString &button)=0;
};

class GroupModechangehandler : public ModeChangeHandler{

  bool isButtonModechange(const Remote* remote, const QString& button) {
    foreach(Mode *mode, remote->m_modeList){
      if(mode->button() == button && ! (mode == remote->currentMode())){
	return true;
      }
    }
    return false;
  }

  void nextMode(Remote* remote, const QString& button) {
    int index=remote->m_modeList.indexOf(remote->currentMode());
    Mode *mode =0;
    int size = remote->m_modeList.size();
    if(index < size){
      for(int i = index +1; i < size ; ++i){
	if(remote->m_modeList.at(index)->button() == button){
	  mode = remote->m_modeList.at(index);
	}
      }
    }
    if(mode== 0){
      for(int i = 0; i < index; ++i){
	if(remote->m_modeList.at(index)->button() == button){
	  mode = remote->m_modeList.at(index);
	}
      }
    }
    if(mode){
      remote->setCurrentMode(mode);
    }
  }
};

Remote::Remote() {
    // Always create the Master Mode and set it default
    Mode *masterMode = new Mode("Master");
    addMode(masterMode);
    setDefaultMode(masterMode);
    m_modechangeHandler = new GroupModechangehandler();
}

Remote::Remote(const QString &remote, const QList<Mode*> &modes) {
    m_modeList = modes;
    m_remoteName = remote;

    // Always create the Master Mode and set it default
    bool hasMaster = false;
    foreach(Mode *mode, m_modeList){
        if(mode->name() == "Master"){
            hasMaster = true;
            break;
        }
    }
    if(!hasMaster){
        Mode *masterMode = new Mode("Master");
        addMode(masterMode);
        setDefaultMode(masterMode);
    }

}

QString Remote::name() const {
  return m_remoteName;
}

QList<Mode*> Remote::allModes() const {
  return m_modeList;
}

void Remote::addMode(Mode *mode) {
  m_modeList.append(mode);
}

void Remote::removeMode(Mode *mode) {
    if(mode->name() == "Master"){
        kDebug() << "cannot delete the Master mode";
        return;
    }

    if(m_defaultMode == mode){
        // Deleting the Default Mode... Setting Master Mode to default
        foreach(Mode *tmp, m_modeList){
            if(tmp->name() == "Master"){
                m_defaultMode = tmp;
                break;
            }
        }
    }
    m_modeList.removeAll(mode);
}

Mode* Remote::masterMode() const {
    foreach(Mode *mode, m_modeList){
        kDebug() << "checking Mode" << mode->name();
        if(mode->name() == "Master"){
            return mode;
        }
    }
    kDebug() << "Master mode not found";
    // Huh??? No Master Mode? Should never happen as removeMode() doesn't delete the Master mode
    // and all ctors create a Master Mode...
    return 0;
}

Mode *Remote::defaultMode() const {
    return m_defaultMode;
}

void Remote::setDefaultMode(Mode *mode) {
    if(!m_modeList.contains(mode)){
        m_modeList.append(mode);
    }
    m_defaultMode = mode;
}

void Remote::setDefaultMode(const QString &modeName){
    foreach(Mode *mode, m_modeList){
        if(mode->name() == modeName){
            setDefaultMode(mode);
            return;
        }
    }
}

Mode* Remote::currentMode() const {
    if(m_currentMode != 0){
        return m_currentMode;
    }
    return m_defaultMode;
}

void Remote::setCurrentMode(Mode* mode) {
    m_currentMode = mode;
}

bool Remote::isAvailable() const {
    return Solid::Control::RemoteControl::allRemoteNames().contains(m_remoteName);
}

bool Remote::isButtonModechange(const QString& button) {
  return m_modechangeHandler->isButtonModechange(this,button);
}

void Remote::nextMode ( const QString& button ){
  m_modechangeHandler->nextMode(this, button);
}

<|endoftext|>


<commit_before><commit_msg>made it so that profit_buy affects engraver and attuner<commit_after><|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Hunspell, based on MySpell.
 *
 * The Initial Developers of the Original Code are
 * Kevin Hendricks (MySpell) and Németh László (Hunspell).
 * Portions created by the Initial Developers are Copyright (C) 2002-2005
 * the Initial Developers. All Rights Reserved.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

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

#include "hunzip.hxx"

#define DESC                                                 \
  "hunzip - decompress a hzip file to the standard output\n" \
  "Usage: hunzip file.hz [password]\n"

int fail(const char* err, const char* par) {
  fprintf(stderr, err, par);
  return 1;
}

int main(int argc, char** argv) {
  if (argc == 1 || strcmp(argv[1], "-h") == 0)
    return fail(DESC, NULL);
  Hunzip h(argv[1], (argc > 2) ? argv[2] : NULL);
  if (!h.is_open())
    return 0;
  std::string s;
  while (h.getline(s))
    printf("%s", s.c_str());
  return 0;
}
<commit_msg>drop odd fail function<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Hunspell, based on MySpell.
 *
 * The Initial Developers of the Original Code are
 * Kevin Hendricks (MySpell) and Németh László (Hunspell).
 * Portions created by the Initial Developers are Copyright (C) 2002-2005
 * the Initial Developers. All Rights Reserved.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

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

#include "hunzip.hxx"

#define DESC                                                 \
  "hunzip - decompress a hzip file to the standard output\n" \
  "Usage: hunzip file.hz [password]\n"

int main(int argc, char** argv) {
  if (argc == 1 || strcmp(argv[1], "-h") == 0) {
    fprintf(stderr, DESC);
    return 1;
  }
  Hunzip h(argv[1], (argc > 2) ? argv[2] : NULL);
  if (!h.is_open())
    return 0;
  std::string s;
  while (h.getline(s))
    printf("%s", s.c_str());
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Medical Image Registration ToolKit (MIRTK)
 *
 * Copyright 2013-2015 Imperial College London
 * Copyright 2013-2015 Andreas Schuh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <mirtkImplicitSurfaceDistance.h>

#include <mirtkMath.h>
#include <mirtkMemory.h>
#include <mirtkParallel.h>
#include <mirtkDataStatistics.h>
#include <mirtkObjectFactory.h>

#include <vtkPoints.h>
#include <vtkDataArray.h>
#include <vtkFloatArray.h>

namespace mirtk {

// Register energy term with object factory during static initialization
mirtkAutoRegisterEnergyTermMacro(ImplicitSurfaceDistance);

// =============================================================================
// Auxiliary functions
// =============================================================================

namespace ImplicitSurfaceDistanceUtils {

// -----------------------------------------------------------------------------
/// Compute gradient of implicit surface distance force term (i.e., negative force)
struct ComputeGradient
{
  typedef ImplicitSurfaceDistance::GradientType GradientType;

  ImplicitSurfaceForce *_Force;
  vtkPoints            *_Points;
  vtkDataArray         *_Status;
  vtkDataArray         *_Normals;
  vtkDataArray         *_Distances;
  double                _MaxDistance;
  GradientType         *_Gradient;

  void operator ()(const blocked_range<int> &ptIds) const
  {
    double p[3], n[3], d, maxd;
    GradientType *g = _Gradient + ptIds.begin();
    for (vtkIdType ptId = ptIds.begin(); ptId != ptIds.end(); ++ptId, ++g) {
      if (_Status && _Status->GetComponent(ptId, 0) == .0) continue;
      _Normals->GetTuple(ptId, n);
      d = _Distances->GetComponent(ptId, 0);

      if (_MaxDistance > .0) { // e.g. _Force->DistanceMeasure() == DM_Normal

        if (!fequal(d, .0)) {
          _Points->GetPoint(ptId, p);
          maxd = .33 * _Force->IntersectWithRay(p, n, -d);
          if (maxd < abs(d)) d = copysign(maxd, d);
        }
        (*g) = (d / _MaxDistance) * GradientType(n[0], n[1], n[2]);

      } else { // _Force->DistanceMeasure() == DM_Minimum

        if (d < .0) (*g) = -GradientType(n[0], n[1], n[2]);
        else        (*g) =  GradientType(n[0], n[1], n[2]);
        d = fabs(d);
        if (d < 1.0) (*g) *= d;

      }
    }
  }
};

} // namespace ImplicitSurfaceDistanceUtils
using namespace ImplicitSurfaceDistanceUtils;

// =============================================================================
// Construction/Destruction
// =============================================================================

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance::ImplicitSurfaceDistance(const char *name, double weight)
:
  ImplicitSurfaceForce(name, weight)
{
  _MaxDistance = 5.0;
}

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance::ImplicitSurfaceDistance(const ImplicitSurfaceDistance &other)
:
  ImplicitSurfaceForce(other)
{
}

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance &ImplicitSurfaceDistance::operator =(const ImplicitSurfaceDistance &other)
{
  ImplicitSurfaceForce::operator =(other);
  return *this;
}

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance::~ImplicitSurfaceDistance()
{
}

// -----------------------------------------------------------------------------
void ImplicitSurfaceDistance::Initialize()
{
  ImplicitSurfaceForce::Initialize();
  InitializeDistances();
}

// =============================================================================
// Evaluation
// =============================================================================

// -----------------------------------------------------------------------------
void ImplicitSurfaceDistance::Update(bool gradient)
{
  ImplicitSurfaceForce::Update(gradient);
  UpdateDistances();
}

// -----------------------------------------------------------------------------
double ImplicitSurfaceDistance::Evaluate()
{
  if (_NumberOfPoints == 0) return .0;
  double sum = .0;
  vtkDataArray *distances = Distances();
  for (int ptId = 0; ptId < _NumberOfPoints; ++ptId) {
    sum += abs(distances->GetComponent(ptId, 0));
  }
  return sum / _NumberOfPoints;
}

// -----------------------------------------------------------------------------
void ImplicitSurfaceDistance::EvaluateGradient(double *gradient, double step, double weight)
{
  if (_NumberOfPoints == 0) return;

  memset(_Gradient, 0, _NumberOfPoints * sizeof(GradientType));

  vtkDataArray *distances = Distances();

  double max_distance = .0;
  if (_DistanceMeasure != DM_Minimum) {
    data::statistic::AbsPercentile::Calculate(95, distances);
  }

  ComputeGradient eval;
  eval._Force       = this;
  eval._Points      = _PointSet->SurfacePoints();
  eval._Status      = _PointSet->SurfaceStatus();
  eval._Normals     = _PointSet->SurfaceNormals();
  eval._Distances   = distances;
  eval._MaxDistance = max_distance;
  eval._Gradient    = _Gradient;
  // Attention: VTK cell locator used by SurfaceForce::IntersectWithRay
  //            is not thread-safe. Hence, execute this loop in main thread.
  //parallel_for(blocked_range<int>(0, _NumberOfPoints), eval);
  eval(blocked_range<int>(0, _NumberOfPoints));

  _GradientAveraging        = 2;
  _AverageGradientMagnitude = true;
  _AverageSignedGradients   = false;

  ImplicitSurfaceForce::EvaluateGradient(gradient, step, weight / _NumberOfPoints);
}

} // namespace mirtk
<commit_msg>enh: Scale implicit surface distance gradient relative to max distance<commit_after>/*
 * Medical Image Registration ToolKit (MIRTK)
 *
 * Copyright 2013-2015 Imperial College London
 * Copyright 2013-2015 Andreas Schuh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <mirtkImplicitSurfaceDistance.h>

#include <mirtkMath.h>
#include <mirtkMemory.h>
#include <mirtkParallel.h>
#include <mirtkDataStatistics.h>
#include <mirtkObjectFactory.h>

#include <vtkPoints.h>
#include <vtkDataArray.h>

namespace mirtk {

// Register energy term with object factory during static initialization
mirtkAutoRegisterEnergyTermMacro(ImplicitSurfaceDistance);

// =============================================================================
// Auxiliary functions
// =============================================================================

namespace ImplicitSurfaceDistanceUtils {

// -----------------------------------------------------------------------------
/// Compute gradient of implicit surface distance force term (i.e., negative force)
struct ComputeGradient
{
  typedef ImplicitSurfaceDistance::GradientType GradientType;

  ImplicitSurfaceForce *_Force;
  vtkPoints            *_Points;
  vtkDataArray         *_Status;
  vtkDataArray         *_Normals;
  vtkDataArray         *_Distances;
  double                _MaxDistance;
  double                _Scale;
  GradientType         *_Gradient;

  void operator ()(const blocked_range<int> &ptIds) const
  {
    double n[3], d;
    GradientType *g = _Gradient + ptIds.begin();
    for (vtkIdType ptId = ptIds.begin(); ptId != ptIds.end(); ++ptId, ++g) {
      if (_Status && _Status->GetComponent(ptId, 0) == .0) continue;
      _Normals->GetTuple(ptId, n);
      d = _Distances->GetComponent(ptId, 0);
      if (d < .0) (*g) = -GradientType(n[0], n[1], n[2]);
      else        (*g) =  GradientType(n[0], n[1], n[2]);

      if (_MaxDistance > .0) { // e.g. _Force->DistanceMeasure() == DM_Normal

        d /= _MaxDistance;
        d *= _Scale;
        d *= d;
        (*g) *= d / (1.0 + d);

      } else { // _Force->DistanceMeasure() == DM_Minimum

        d = fabs(d);
        if (d < 1.0) (*g) *= d;

      }
    }
  }
};

} // namespace ImplicitSurfaceDistanceUtils
using namespace ImplicitSurfaceDistanceUtils;

// =============================================================================
// Construction/Destruction
// =============================================================================

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance::ImplicitSurfaceDistance(const char *name, double weight)
:
  ImplicitSurfaceForce(name, weight)
{
  _MaxDistance = 5.0;
}

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance::ImplicitSurfaceDistance(const ImplicitSurfaceDistance &other)
:
  ImplicitSurfaceForce(other)
{
}

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance &ImplicitSurfaceDistance::operator =(const ImplicitSurfaceDistance &other)
{
  ImplicitSurfaceForce::operator =(other);
  return *this;
}

// -----------------------------------------------------------------------------
ImplicitSurfaceDistance::~ImplicitSurfaceDistance()
{
}

// -----------------------------------------------------------------------------
void ImplicitSurfaceDistance::Initialize()
{
  ImplicitSurfaceForce::Initialize();
  InitializeDistances();
}

// =============================================================================
// Evaluation
// =============================================================================

// -----------------------------------------------------------------------------
void ImplicitSurfaceDistance::Update(bool gradient)
{
  ImplicitSurfaceForce::Update(gradient);
  UpdateDistances();
}

// -----------------------------------------------------------------------------
double ImplicitSurfaceDistance::Evaluate()
{
  if (_NumberOfPoints == 0) return .0;
  double sum = .0;
  vtkDataArray *distances = Distances();
  for (int ptId = 0; ptId < _NumberOfPoints; ++ptId) {
    sum += abs(distances->GetComponent(ptId, 0));
  }
  return sum / _NumberOfPoints;
}

// -----------------------------------------------------------------------------
void ImplicitSurfaceDistance::EvaluateGradient(double *gradient, double step, double weight)
{
  if (_NumberOfPoints == 0) return;

  memset(_Gradient, 0, _NumberOfPoints * sizeof(GradientType));

  vtkDataArray *distances = this->Distances();

  double max_distance = .0;
  if (_DistanceMeasure != DM_Minimum) {
    data::statistic::AbsPercentile::Calculate(95, distances);
  }

  ComputeGradient eval;
  eval._Force       = this;
  eval._Points      = _PointSet->SurfacePoints();
  eval._Status      = _PointSet->SurfaceStatus();
  eval._Normals     = _PointSet->SurfaceNormals();
  eval._Distances   = distances;
  eval._MaxDistance = max_distance;
  eval._Scale       = 1.0;
  eval._Gradient    = _Gradient;
  parallel_for(blocked_range<int>(0, _NumberOfPoints), eval);

  ImplicitSurfaceForce::EvaluateGradient(gradient, step, weight / _NumberOfPoints);
}

} // namespace mirtk
<|endoftext|>