コード例 #1
0
ファイル: levels.c プロジェクト: gapato/darktable
static void dt_iop_levels_pick_general_handler(GtkToggleButton *togglebutton, dt_iop_module_t *self, double xpick, double ypick, dt_iop_levels_pick_t picklevel)
{
  dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data;

  darktable.gui->reset = 1;
  // we do not require the callback if we deactivate it here
  if (c->activeToggleButton != NULL) gtk_toggle_button_set_active(c->activeToggleButton, FALSE);
  darktable.gui->reset = 0;

  gboolean toggle = gtk_toggle_button_get_active(togglebutton);
  if(darktable.gui->reset) return;

  if (TRUE == toggle)
  {
    self->request_color_pick = TRUE;
    dt_lib_colorpicker_set_point(darktable.lib, xpick, ypick);
    dt_iop_request_focus(self);
    c->activeToggleButton = togglebutton;
    c->current_pick = picklevel;
  }
  else
  {
    self->request_color_pick = FALSE;
    dt_iop_request_focus(self);
    c->activeToggleButton = NULL;
    c->current_pick = NONE;
    gtk_widget_queue_draw(self->widget);
  }

  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), TRUE);

  dt_control_queue_redraw();
}
コード例 #2
0
ファイル: exposure.c プロジェクト: hean01/darktable
static void
autoexp_callback (GtkToggleButton *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data;
  if(self->dt->gui->reset) return;

  deflicker_disable(self);

  self->request_color_pick = gtk_toggle_button_get_active(button);

  dt_iop_request_focus(self);

  if (self->request_color_pick > 0)
  {
    dt_lib_colorpicker_set_area(darktable.lib, 0.99);
    dt_dev_reprocess_all(self->dev);
  }
  else
    dt_control_queue_redraw();

  gtk_widget_set_sensitive(GTK_WIDGET(g->autoexpp), gtk_toggle_button_get_active(button));

  dt_dev_add_history_item(darktable.develop, self, TRUE);
}
コード例 #3
0
ファイル: blend_gui.c プロジェクト: minusdreidb/darktable
static void
_blendop_blendif_pick_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *module)
{
  if(darktable.gui->reset) return;

  /* if module itself already requested color pick (positive value in request_color_pick),
     don't tamper with it. A module color picker takes precedence. */
  if(module->request_color_pick > 0)
  {
    gtk_toggle_button_set_active(togglebutton, 0);
    return;
  }

  /* we put a negative value into request_color_pick to later see if color picker was
     requested by blendif. A module color picker may overwrite this. This is fine, blendif
     will use the color picker data, but not deactivate it. */
  module->request_color_pick = (gtk_toggle_button_get_active(togglebutton) ? -1 : 0);

  /* set the area sample size */
  if (module->request_color_pick)
  {
    dt_lib_colorpicker_set_point(darktable.lib, 0.5, 0.5);
    dt_dev_reprocess_all(module->dev);
  }
  else
    dt_control_queue_redraw();

  if(module->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), 1);
  dt_iop_request_focus(module);
}
コード例 #4
0
static void
request_pick_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *self)
{
  self->request_color_pick = gtk_toggle_button_get_active(togglebutton);
  if(darktable.gui->reset) return;
  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
  dt_iop_request_focus(self);
}
コード例 #5
0
ファイル: colorpicker.c プロジェクト: dirkbr/darktable
static void _picker_button_toggled(GtkToggleButton *button, gpointer p)
{
  dt_lib_colorpicker_t *data = ((dt_lib_module_t *)p)->data;
  gtk_widget_set_sensitive(GTK_WIDGET(data->add_sample_button), gtk_toggle_button_get_active(button));
  if(darktable.gui->reset) return;
  dt_iop_module_t *module = get_colorout_module();
  if(module)
  {
    dt_iop_request_focus(module);
    module->request_color_pick = gtk_toggle_button_get_active(button) ? DT_REQUEST_COLORPICK_MODULE
                                                                      : DT_REQUEST_COLORPICK_OFF;
    dt_dev_invalidate_from_gui(darktable.develop);
  }
  else
  {
    dt_iop_request_focus(NULL);
  }
  dt_control_queue_redraw();
}
コード例 #6
0
ファイル: blend_gui.c プロジェクト: minusdreidb/darktable
static void
_blendop_blendif_suppress_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *module)
{
  module->suppress_mask = gtk_toggle_button_get_active(togglebutton);
  if(darktable.gui->reset) return;

  if(module->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), 1);
  dt_iop_request_focus(module);

  dt_dev_reprocess_all(module->dev);
}
コード例 #7
0
static void
request_pick_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *self)
{
  self->request_color_pick = gtk_toggle_button_get_active(togglebutton);
  if(darktable.gui->reset) return;
  
  /* use point sample */
  if (self->request_color_pick)
    dt_lib_colorpicker_set_point(darktable.lib, 0.5, 0.5);
  
  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
  dt_iop_request_focus(self);
}
コード例 #8
0
ファイル: blend_gui.c プロジェクト: bgK/darktable
static void
_blendop_blendif_pick_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *module)
{
  module->request_color_pick = gtk_toggle_button_get_active(togglebutton);
  if(darktable.gui->reset) return;

  
  /* set the area sample size*/
  if (module->request_color_pick)
    dt_lib_colorpicker_set_point(darktable.lib, 0.5, 0.5);
  
  if(module->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), 1);
  dt_iop_request_focus(module);
}
コード例 #9
0
ファイル: spots.c プロジェクト: pryds/darktable
static gboolean _add_ellipse(GtkWidget *widget, GdkEventButton *e, dt_iop_module_t *self)
{
  _reset_form_creation(widget, self);
  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return FALSE;
  // we want to be sure that the iop has focus
  dt_iop_request_focus(self);
  // we create the new form
  dt_masks_form_t *spot = dt_masks_create(DT_MASKS_ELLIPSE | DT_MASKS_CLONE);
  dt_masks_change_form_gui(spot);
  darktable.develop->form_gui->creation = TRUE;
  darktable.develop->form_gui->creation_module = self;
  dt_control_queue_redraw_center();
  return FALSE;
}
コード例 #10
0
ファイル: temperature.c プロジェクト: rharrison10/darktable
static void
apply_preset(dt_iop_module_t *self)
{
    self->request_color_pick = 0;
    if(self->dt->gui->reset) return;
    dt_iop_temperature_gui_data_t *g = (dt_iop_temperature_gui_data_t *)self->gui_data;
    dt_iop_temperature_params_t *p  = (dt_iop_temperature_params_t *)self->params;
    dt_iop_temperature_params_t *fp = (dt_iop_temperature_params_t *)self->default_params;
    const int tune = dt_bauhaus_slider_get(g->finetune);
    const int pos = dt_bauhaus_combobox_get(g->presets);
    switch(pos)
    {
    case -1: // just un-setting.
        return;
    case 0: // camera wb
        for(int k=0; k<3; k++) p->coeffs[k] = fp->coeffs[k];
        break;
    case 1: // spot wb, exposure callback will set p->coeffs.
        for(int k=0; k<3; k++) p->coeffs[k] = fp->coeffs[k];
        dt_iop_request_focus(self);
        self->request_color_pick = 1;

        /* set the area sample size*/
        if (self->request_color_pick)
            dt_lib_colorpicker_set_area(darktable.lib, 0.99);

        break;
    case 2: // passthrough mode, raw data
        for(int k=0; k<3; k++) p->coeffs[k] = 1.0;
        break;
    default:
        for(int i=g->preset_num[pos]; i<wb_preset_count; i++)
        {
            char makermodel[1024];
            char *model = makermodel;
            dt_colorspaces_get_makermodel_split(makermodel, 1024, &model, self->dev->image_storage.exif_maker, self->dev->image_storage.exif_model);
            if(!strcmp(wb_preset[i].make,  makermodel) &&
                    !strcmp(wb_preset[i].model, model) && wb_preset[i].tuning == tune)
            {
                for(int k=0; k<3; k++) p->coeffs[k] = wb_preset[i].channel[k];
                break;
            }
        }
        break;
    }
    if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
    gui_update_from_coeffs(self);
    dt_dev_add_history_item(darktable.develop, self, TRUE);
}
コード例 #11
0
static void
autoexp_callback (GtkToggleButton *button, dt_iop_module_t *self)
{
  dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data;
  if(darktable.gui->reset) 
    return;
  
  self->request_color_pick = gtk_toggle_button_get_active(button);

  if (self->request_color_pick)
    dt_lib_colorpicker_set_area(darktable.lib, 0.99);

  dt_iop_request_focus(self);
  gtk_widget_set_sensitive(GTK_WIDGET(g->autoexpp), gtk_toggle_button_get_active(button));
}
コード例 #12
0
ファイル: relight.c プロジェクト: munialabs/openPablo
static void
picker_callback (GtkDarktableToggleButton *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
  {
    dt_iop_request_focus (self);
    self->request_color_pick = 1;
    
    /* set the area sample size*/
    dt_lib_colorpicker_set_area(darktable.lib, 0.99);
    
  }
  else
    self->request_color_pick = 0;
}
コード例 #13
0
ファイル: blend_gui.c プロジェクト: bgK/darktable
static void
_blendop_blendif_showmask_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *module)
{
  dt_develop_blend_params_t *bp = module->blend_params;

  module->request_mask_display = gtk_toggle_button_get_active(togglebutton);
  if(darktable.gui->reset) return;

  if(module->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), 1);
  dt_iop_request_focus(module);

  // hack! in order to force instant redraw we toggle an unused bit in blendif params
  // TODO: need to find a better way to trigger redraw
  bp->blendif ^= (1<<30);
  dt_dev_add_history_item(darktable.develop, module, TRUE);
}
コード例 #14
0
ファイル: invert.c プロジェクト: jmarca/darktable
static void
request_pick_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *self)
{
  if(darktable.gui->reset) return;

  self->request_color_pick = (gtk_toggle_button_get_active(togglebutton) ? 1 : 0);

  if(self->request_color_pick)
  {
    dt_lib_colorpicker_set_point(darktable.lib, 0.5, 0.5);
    dt_dev_reprocess_all(self->dev);
  }
  else
    dt_control_queue_redraw();

  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
  dt_iop_request_focus(self);
}
コード例 #15
0
ファイル: invert.c プロジェクト: olyoberdorf/darktable
static void request_pick_toggled(GtkToggleButton *togglebutton, dt_iop_module_t *self)
{
  if(darktable.gui->reset) return;

  self->request_color_pick
      = (gtk_toggle_button_get_active(togglebutton) ? DT_REQUEST_COLORPICK_MODULE : DT_REQUEST_COLORPICK_OFF);

  if(self->request_color_pick != DT_REQUEST_COLORPICK_OFF)
  {
    dt_lib_colorpicker_set_area(darktable.lib, 0.99);
    dt_dev_reprocess_all(self->dev);
  }
  else
    dt_control_queue_redraw();

  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
  dt_iop_request_focus(self);
}
コード例 #16
0
ファイル: colorchecker.c プロジェクト: PkmX/darktable
static void picker_callback(GtkWidget *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  if(darktable.gui->reset) return;

  if(self->request_color_pick == DT_REQUEST_COLORPICK_OFF)
    self->request_color_pick = DT_REQUEST_COLORPICK_MODULE;
  else
    self->request_color_pick = DT_REQUEST_COLORPICK_OFF;

  dt_iop_request_focus(self);

  if(self->request_color_pick != DT_REQUEST_COLORPICK_OFF)
    dt_dev_reprocess_all(self->dev);
  else
    dt_control_queue_redraw();

  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
}
コード例 #17
0
ファイル: relight.c プロジェクト: bleader/darktable
static void
picker_callback (GtkDarktableToggleButton *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  if(darktable.gui->reset) return;

  self->request_color_pick = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button)) ? 1 : 0);

  /* set the area sample size*/
  if (self->request_color_pick)
  {
    dt_lib_colorpicker_set_point(darktable.lib, 0.5, 0.5);
    dt_dev_reprocess_all(self->dev);
  }
  else
    dt_control_queue_redraw();

  if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
  dt_iop_request_focus(self);
}
コード例 #18
0
ファイル: spots.c プロジェクト: rikles/darktable
static void _add_circle(GtkWidget *widget, GdkEventButton *e, dt_iop_module_t *self)
{
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
    {
        //we unset the creation mode
        dt_masks_form_t *form = darktable.develop->form_visible;
        if (form) dt_masks_free_form(form);
        dt_masks_change_form_gui(NULL);
        dt_masks_init_formgui(darktable.develop);
        GTK_TOGGLE_BUTTON(widget)->active = FALSE;
        return;
    }
    //we want to be sure that the iop has focus
    dt_iop_request_focus(self);
    //we create the new form
    dt_masks_form_t *spot = dt_masks_create(DT_MASKS_CIRCLE|DT_MASKS_CLONE);
    dt_masks_change_form_gui(spot);
    darktable.develop->form_gui->creation = TRUE;
    darktable.develop->form_gui->creation_module = self;
    dt_control_queue_redraw_center();
}
コード例 #19
0
static void picker_callback(GtkToggleButton *button, gpointer user_data)
{
  dt_iop_module_t *self = (dt_iop_module_t *)user_data;
  if(darktable.gui->reset) return;

  self->request_color_pick
      = (gtk_toggle_button_get_active(button) ? DT_REQUEST_COLORPICK_MODULE : DT_REQUEST_COLORPICK_OFF);

  if(self->request_color_pick == DT_REQUEST_COLORPICK_MODULE)
  {
    dt_lib_colorpicker_set_area(darktable.lib, 0.99);
    dt_dev_reprocess_all(self->dev);
  }
  else
    dt_control_queue_redraw();

  // only activate if the color picker is selected, this is becasue the monochrome module as a draw signal.
  if (self->request_color_pick == DT_REQUEST_COLORPICK_MODULE)
  {
    if(self->off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->off), 1);
    dt_iop_request_focus(self);
  }
}
コード例 #20
0
void enter(dt_view_t *self)
{
  /* connect to ui pipe finished signal for redraw */
  dt_control_signal_connect(darktable.signals,
                            DT_SIGNAL_DEVELOP_UI_PIPE_FINISHED,G_CALLBACK(_darkroom_ui_pipe_finish_signal_callback),
                            (gpointer)self);

  dt_print(DT_DEBUG_CONTROL, "[run_job+] 11 %f in darkroom mode\n", dt_get_wtime());
  dt_develop_t *dev = (dt_develop_t *)self->data;

  dev->gui_leaving = 0;
  dev->gui_module = NULL;

  select_this_image(dev->image_storage.id);

  DT_CTL_SET_GLOBAL(dev_zoom, DT_ZOOM_FIT);
  DT_CTL_SET_GLOBAL(dev_zoom_x, 0);
  DT_CTL_SET_GLOBAL(dev_zoom_y, 0);
  DT_CTL_SET_GLOBAL(dev_closeup, 0);

  // take a copy of the image struct for convenience.

  dt_dev_load_image(darktable.develop, dev->image_storage.id);

  /*
   * Add view specific tool buttons
   */

  /* create favorite plugin preset popup tool */
  GtkWidget *favorite_presets = dtgtk_button_new(dtgtk_cairo_paint_presets, CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER);
  g_object_set(G_OBJECT(favorite_presets), "tooltip-text", _("quick access to presets of your favorites"),
               (char *)NULL);
  g_signal_connect (G_OBJECT (favorite_presets), "clicked",
                    G_CALLBACK (_darkroom_ui_favorite_presets_popupmenu),
                    NULL);
  dt_view_manager_view_toolbox_add(darktable.view_manager, favorite_presets);

  /* add IOP modules to plugin list */

  /* create quick styles popup menu tool */
  GtkWidget *styles = dtgtk_button_new (dtgtk_cairo_paint_styles,CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER);
  g_signal_connect (G_OBJECT (styles), "clicked",
                    G_CALLBACK (_darkroom_ui_apply_style_popupmenu),
                    NULL);
  g_object_set (G_OBJECT (styles), "tooltip-text", _("quick access for applying any of your styles"),
                (char *)NULL);
  dt_view_manager_view_toolbox_add(darktable.view_manager, styles);

  /*
   * add IOP modules to plugin list
   */
  // avoid triggering of events before plugin is ready:
  darktable.gui->reset = 1;
  char option[1024];
  GList *modules = g_list_last(dev->iop);
  while(modules)
  {
    dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);

    /* initialize gui if iop have one defined */
    if (!dt_iop_is_hidden(module))
    {
      module->gui_init(module);
      dt_iop_reload_defaults(module);

      /* add module to right panel */
      GtkWidget *expander = dt_iop_gui_get_expander(module);
      dt_ui_container_add_widget(darktable.gui->ui,
                                 DT_UI_CONTAINER_PANEL_RIGHT_CENTER, expander);

      snprintf(option, 1024, "plugins/darkroom/%s/expanded", module->op);
      dt_iop_gui_set_expanded(module, dt_conf_get_bool(option));
    }

    /* setup key accelerators */
    module->accel_closures = NULL;
    if(module->connect_key_accels)
      module->connect_key_accels(module);
    dt_iop_connect_common_accels(module);

    modules = g_list_previous(modules);
  }
  darktable.gui->reset = 0;

  /* signal that darktable.develop is initialized and ready to be used */
  dt_control_signal_raise(darktable.signals,DT_SIGNAL_DEVELOP_INITIALIZE);

  // synch gui and flag gegl pipe as dirty
  // this is done here and not in dt_read_history, as it would else be triggered before module->gui_init.
  dt_dev_pop_history_items(dev, dev->history_end);

  /* ensure that filmstrip shows current image */
  dt_view_filmstrip_scroll_to_image(darktable.view_manager, dev->image_storage.id, FALSE);

  // switch on groups as they where last time:
  dt_dev_modulegroups_set(dev, dt_conf_get_int("plugins/darkroom/groups"));

  // make signals work again:
  darktable.gui->reset = 0;

  // get last active plugin:
  gchar *active_plugin = dt_conf_get_string("plugins/darkroom/active");
  if(active_plugin)
  {
    GList *modules = dev->iop;
    while(modules)
    {
      dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
      if(!strcmp(module->op, active_plugin))
        dt_iop_request_focus(module);
      modules = g_list_next(modules);
    }
    g_free(active_plugin);
  }

  // image should be there now.
  float zoom_x, zoom_y;
  dt_dev_check_zoom_bounds(dev, &zoom_x, &zoom_y, DT_ZOOM_FIT, 0, NULL, NULL);
  DT_CTL_SET_GLOBAL(dev_zoom_x, zoom_x);
  DT_CTL_SET_GLOBAL(dev_zoom_y, zoom_y);

  /* connect signal for filmstrip image activate */
  dt_control_signal_connect(darktable.signals,
                            DT_SIGNAL_VIEWMANAGER_FILMSTRIP_ACTIVATE,
                            G_CALLBACK(_view_darkroom_filmstrip_activate_callback),
                            self);

  // prefetch next few from first selected image on.
  dt_view_filmstrip_prefetch();
}
コード例 #21
0
ファイル: modulegroups.c プロジェクト: AntonSh/darktable
static void _lib_modulegroups_update_iop_visibility(dt_lib_module_t *self)
{
  dt_lib_modulegroups_t *d = (dt_lib_modulegroups_t *)self->data;

  GList *modules = darktable.develop->iop;
  if(modules)
  {
    /*
     * iterate over ip modules and do various test to
     * detect if the modules should be shown or not.
     */
    do
    {
      dt_iop_module_t *module = (dt_iop_module_t*)modules->data;
      GtkWidget *w = module->expander;

      /* skip modules without an gui */
      if(dt_iop_is_hidden(module)) continue;

      /* lets show/hide modules dependent on current group*/
      switch(d->current)
      {
        case DT_MODULEGROUP_ACTIVE_PIPE:
        {
          if(module->enabled)
            gtk_widget_show(w);
          else
          {
            if(darktable.develop->gui_module == module) dt_iop_request_focus(NULL);
            gtk_widget_hide(w);
          }
        }
        break;

        case DT_MODULEGROUP_FAVORITES:
        {
          if(module->state == dt_iop_state_FAVORITE)
            gtk_widget_show(w);
          else
          {
            if(darktable.develop->gui_module == module) dt_iop_request_focus(NULL);
            gtk_widget_hide(w);
          }
        }
        break;

        case DT_MODULEGROUP_NONE:
        {
          /* show all exept hidden ones */
          if((module->state != dt_iop_state_HIDDEN || module->enabled) &&
              (!(module->flags() & IOP_FLAGS_DEPRECATED)))
            gtk_widget_show(w);
          else
          {
            if(darktable.develop->gui_module == module) dt_iop_request_focus(NULL);
            gtk_widget_hide(w);
          }
        }
        break;

        default:
        {
          if ( _lib_modulegroups_test(self,d->current, module->groups()) &&
               module->state != dt_iop_state_HIDDEN &&
               (!(module->flags() & IOP_FLAGS_DEPRECATED) || module->enabled))
            gtk_widget_show(w);
          else
          {
            if(darktable.develop->gui_module == module) dt_iop_request_focus(NULL);
            gtk_widget_hide(w);
          }
        }
      }
    }
    while((modules = g_list_next(modules))!=NULL);
  }
}
コード例 #22
0
static void
dt_dev_change_image(dt_develop_t *dev, const uint32_t imgid)
{
  // stop crazy users from sleeping on key-repeat spacebar:
  if(dev->image_loading) return;

  // get last active plugin, make sure focus out is called:
  gchar *active_plugin = dt_conf_get_string("plugins/darkroom/active");
  dt_iop_request_focus(NULL);
  // store last active group
  dt_conf_set_int("plugins/darkroom/groups", dt_dev_modulegroups_get(dev));

  // store last active plugin:
  if(darktable.develop->gui_module)
    dt_conf_set_string("plugins/darkroom/active", darktable.develop->gui_module->op);
  else
    dt_conf_set_string("plugins/darkroom/active", "");
  g_assert(dev->gui_attached);

  // commit image ops to db
  dt_dev_write_history(dev);

  // be sure light table will update the thumbnail
  // TODO: only if image changed!
  // if()
  {
    dt_mipmap_cache_remove(darktable.mipmap_cache, dev->image_storage.id);
    dt_image_synch_xmp(dev->image_storage.id);
  }

  select_this_image(imgid);

  while(dev->history)
  {
    // clear history of old image
    free(((dt_dev_history_item_t *)dev->history->data)->params);
    free( (dt_dev_history_item_t *)dev->history->data);
    dev->history = g_list_delete_link(dev->history, dev->history);
  }

  // get new image:
  dt_dev_reload_image(dev, imgid);

  // make sure no signals propagate here:
  darktable.gui->reset = 1;

  GList *modules = g_list_last(dev->iop);
  int nb_iop = g_list_length(dev->iop);
  dt_dev_pixelpipe_cleanup_nodes(dev->pipe);
  dt_dev_pixelpipe_cleanup_nodes(dev->preview_pipe);
  for (int i=nb_iop-1; i>0; i--)
  {
    dt_iop_module_t *module = (dt_iop_module_t *)(g_list_nth_data(dev->iop,i));
    if (module->multi_priority == 0) //if the module is the "base" instance, we keep it
    {
      dt_iop_reload_defaults(module);
      dt_iop_gui_update(module);
    }
    else  //else we delete it and remove it from the panel
    {
      if (!dt_iop_is_hidden(module))
      {
        gtk_container_remove (GTK_CONTAINER(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)),module->expander);
        dt_iop_gui_cleanup_module(module);
      }

      //we remove the module from the list
      dev->iop = g_list_remove_link(dev->iop,g_list_nth(dev->iop,i));

      //we cleanup the module
      dt_accel_disconnect_list(module->accel_closures);
      dt_accel_cleanup_locals_iop(module);
      module->accel_closures = NULL;
      dt_iop_cleanup_module(module);
      free(module);
    }
  }
  dt_dev_pixelpipe_create_nodes(dev->pipe, dev);
  dt_dev_pixelpipe_create_nodes(dev->preview_pipe, dev);
  dt_dev_read_history(dev);

  //we have to init all module instances other than "base" instance
  modules = dev->iop;
  while(modules)
  {
    dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
    if(module->multi_priority > 0)
    {
      if (!dt_iop_is_hidden(module))
      {
        module->gui_init(module);
        dt_iop_reload_defaults(module);
        //we search the base iop corresponding
        GList *mods = g_list_first(dev->iop);
        dt_iop_module_t *base = NULL;
        int pos_module = 0;
        int pos_base = 0;
        int pos = 0;
        while (mods)
        {
          dt_iop_module_t *mod = (dt_iop_module_t *)(mods->data);
          if (mod->multi_priority == 0 && mod->instance == module->instance)
          {
            base = mod;
            pos_base = pos;
          }
          else if (mod == module) pos_module = pos;
          mods = g_list_next(mods);
          pos++;
        }
        if (!base) continue;

        /* add module to right panel */
        GtkWidget *expander = dt_iop_gui_get_expander(module);
        dt_ui_container_add_widget(darktable.gui->ui,
                                   DT_UI_CONTAINER_PANEL_RIGHT_CENTER, expander);
        GValue gv = { 0, { { 0 } } };
        g_value_init(&gv,G_TYPE_INT);
        gtk_container_child_get_property(GTK_CONTAINER(dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER)),base->expander,"position",&gv);
        gtk_box_reorder_child (dt_ui_get_container(darktable.gui->ui, DT_UI_CONTAINER_PANEL_RIGHT_CENTER),expander,g_value_get_int(&gv)+pos_base-pos_module);
        dt_iop_gui_set_expanded(module, TRUE);
        dt_iop_gui_update_blending(module);
      }

      /* setup key accelerators */
      module->accel_closures = NULL;
      if(module->connect_key_accels)
        module->connect_key_accels(module);
      dt_iop_connect_common_accels(module);

      //we update show params for multi-instances for each other instances
      dt_dev_modules_update_multishow(module->dev);
    }
    modules = g_list_next(modules);
  }

  dt_dev_pop_history_items(dev, dev->history_end);

  if(active_plugin)
  {
    modules = dev->iop;
    while(modules)
    {
      dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
      if(!strcmp(module->op, active_plugin))
        dt_iop_request_focus(module);
      modules = g_list_next(modules);
    }
    g_free(active_plugin);
  }

  /* last set the group to update visibility of iop modules for new pipe */
  dt_dev_modulegroups_set(dev,dt_conf_get_int("plugins/darkroom/groups"));

  // make signals work again, but only after focus event,
  // to avoid crop/rotate for example to add another history item.
  darktable.gui->reset = 0;

  // Signal develop initialize
  dt_control_signal_raise(darktable.signals, DT_SIGNAL_DEVELOP_IMAGE_CHANGED);

  // prefetch next few from first selected image on.
  dt_view_filmstrip_prefetch();
}