Example #1
0
static void _lib_tagging_redraw_callback(gpointer instance, gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_tagging_t *d = (dt_lib_tagging_t *)self->data;
  int imgsel = dt_control_get_mouse_over_id();
  if(imgsel != d->imgsel) update(self, 0);
}
Example #2
0
static void
_jump_to()
{
  int32_t imgid = dt_control_get_mouse_over_id();
  if(imgid == -1)
  {
    sqlite3_stmt *stmt;

    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                              "select imgid from selected_images", -1, &stmt, NULL);

    if(sqlite3_step(stmt) == SQLITE_ROW)
      imgid = sqlite3_column_int(stmt, 0);
    sqlite3_finalize(stmt);
  }
  if(imgid != -1)
  {
    char path[512];
    const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, imgid);
    dt_image_film_roll_directory(img, path, sizeof(path));
    dt_image_cache_read_release(darktable.image_cache, img);
    char collect[1024];
    snprintf(collect, sizeof(collect), "1:0:0:%s$", path);
    dt_collection_deserialize(collect);
  }
}
Example #3
0
static int hovered_cb(lua_State *L)
{
    int32_t mouse_over_id = dt_control_get_mouse_over_id();
    if(mouse_over_id ==-1) {
        lua_pushnil(L);
    } else {
        luaA_push(L,dt_lua_image_t,&mouse_over_id);
    }
    return 1;
}
Example #4
0
static gboolean _lib_filmstrip_discard_history_key_accel_callback(GtkAccelGroup *accel_group,
                                                                  GObject *aceeleratable, guint keyval,
                                                                  GdkModifierType modifier, gpointer data)
{
  int32_t mouse_over_id = dt_control_get_mouse_over_id();
  if(mouse_over_id <= 0) return FALSE;

  dt_history_delete_on_image(mouse_over_id);
  dt_control_queue_redraw_center();
  return TRUE;
}
Example #5
0
int try_enter(dt_view_t *self)
{
  dt_print_t *prt=(dt_print_t*)self->data;

  //  now check that there is at least one selected image

  prt->image_id = -1;

  int selected = dt_control_get_mouse_over_id();
  if(selected < 0)
  {
    // try last selected
    sqlite3_stmt *stmt;
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select * from selected_images", -1, &stmt,
                                NULL);
    if(sqlite3_step(stmt) == SQLITE_ROW) selected = sqlite3_column_int(stmt, 0);
    sqlite3_finalize(stmt);

    // Leave as selected only the image being edited
    DT_DEBUG_SQLITE3_EXEC(dt_database_get(darktable.db), "delete from selected_images", NULL, NULL, NULL);
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                                "insert or ignore into selected_images values (?1)", -1, &stmt, NULL);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, selected);
    sqlite3_step(stmt);
    sqlite3_finalize(stmt);
  }

  if(selected < 0)
  {
    // fail :(
    dt_control_log(_("no image selected!"));
    return 1;
  }

  // this loads the image from db if needed:
  const dt_image_t *img = dt_image_cache_get(darktable.image_cache, selected, 'r');
  // get image and check if it has been deleted from disk first!

  char imgfilename[PATH_MAX] = { 0 };
  gboolean from_cache = TRUE;
  dt_image_full_path(img->id, imgfilename, sizeof(imgfilename), &from_cache);
  if(!g_file_test(imgfilename, G_FILE_TEST_IS_REGULAR))
  {
    dt_control_log(_("image `%s' is currently unavailable"), img->filename);
    // dt_image_remove(selected);
    dt_image_cache_read_release(darktable.image_cache, img);
    return 1;
  }
  // and drop the lock again.
  dt_image_cache_read_release(darktable.image_cache, img);
  prt->image_id = selected;
  return 0;
}
Example #6
0
static gboolean _lib_filmstrip_copy_history_key_accel_callback(GtkAccelGroup *accel_group,
                                                               GObject *aceeleratable, guint keyval,
                                                               GdkModifierType modifier, gpointer data)
{
  dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)data;
  int32_t mouse_over_id = dt_control_get_mouse_over_id();
  if(mouse_over_id <= 0) return FALSE;
  strip->history_copy_imgid = mouse_over_id;

  /* check if images is currently loaded in darkroom */
  if(dt_dev_is_current_image(darktable.develop, mouse_over_id)) dt_dev_write_history(darktable.develop);
  return TRUE;
}
Example #7
0
static gboolean _lib_filmstrip_duplicate_image_key_accel_callback(GtkAccelGroup *accel_group,
                                                                  GObject *aceeleratable, guint keyval,
                                                                  GdkModifierType modifier, gpointer data)
{
  int32_t mouse_over_id = dt_control_get_mouse_over_id();
  if(mouse_over_id <= 0) return FALSE;

  /* check if images is currently loaded in darkroom */
  if(dt_dev_is_current_image(darktable.develop, mouse_over_id)) dt_dev_write_history(darktable.develop);

  int32_t newimgid = dt_image_duplicate(mouse_over_id);
  if(newimgid != -1) dt_history_copy_and_paste_on_image(mouse_over_id, newimgid, FALSE, NULL);

  dt_control_queue_redraw_center();
  return TRUE;
}
Example #8
0
static void on_mouse_over_image_changed(gpointer instance, gpointer user_data)
{
  int imgid = dt_control_get_mouse_over_id();
  if(imgid != -1) {
  dt_lua_async_call_alien(dt_lua_event_trigger_wrapper,
      0, NULL,NULL,
      LUA_ASYNC_TYPENAME,"char*","mouse-over-image-changed",
      LUA_ASYNC_TYPENAME,"dt_lua_image_t",imgid,
      LUA_ASYNC_DONE);
  } else {
  dt_lua_async_call_alien(dt_lua_event_trigger_wrapper,
      0, NULL,NULL,
      LUA_ASYNC_TYPENAME,"char*","mouse-over-image-changed",
      LUA_ASYNC_DONE);
  }
}
Example #9
0
static gboolean _lib_filmstrip_ratings_key_accel_callback(GtkAccelGroup *accel_group, GObject *aceeleratable,
                                                          guint keyval, GdkModifierType modifier,
                                                          gpointer data)
{
  int num = GPOINTER_TO_INT(data);
  switch(num)
  {
    case DT_VIEW_DESERT:
    case DT_VIEW_REJECT:
    case DT_VIEW_STAR_1:
    case DT_VIEW_STAR_2:
    case DT_VIEW_STAR_3:
    case DT_VIEW_STAR_4:
    case DT_VIEW_STAR_5:
    case 666:
    {
      int32_t mouse_over_id = dt_control_get_mouse_over_id();
      if(mouse_over_id <= 0) return FALSE;
      /* get image from cache */

      int32_t activated_image = -1;

      activated_image = darktable.view_manager->proxy.filmstrip.activated_image(
          darktable.view_manager->proxy.filmstrip.module);

      int offset = 0;
      if(mouse_over_id == activated_image) offset = dt_collection_image_offset(mouse_over_id);

      dt_ratings_apply_to_image(mouse_over_id, num);

      dt_collection_hint_message(darktable.collection); // More than this, we need to redraw all

      if(mouse_over_id == activated_image)
        if(_lib_filmstrip_imgid_in_collection(darktable.collection, mouse_over_id) == 0)
          dt_view_filmstrip_scroll_relative(0, offset);

      /* redraw all */
      dt_control_queue_redraw();
      break;
    }
    default:
      break;
  }
  return TRUE;
}
Example #10
0
static void update(dt_lib_module_t *self, int which)
{
    dt_lib_tagging_t *d = (dt_lib_tagging_t *)self->data;
    GList *tags = NULL;
    uint32_t count;

    if(which == 0) // tags of selected images
    {
        int imgsel = dt_control_get_mouse_over_id();
        d->imgsel = imgsel;
        count = dt_tag_get_attached(imgsel, &tags, FALSE);
    }
    else // related tags of typed text
        count = dt_tag_get_suggestions(d->keyword, &tags);

    GtkTreeIter iter;
    GtkTreeView *view;
    if(which == 0)
        view = d->current;
    else
        view = d->related;
    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
    g_object_ref(model);
    gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL);
    gtk_list_store_clear(GTK_LIST_STORE(model));

    if(count > 0 && tags)
    {
        do
        {
            gtk_list_store_append(GTK_LIST_STORE(model), &iter);
            gtk_list_store_set(GTK_LIST_STORE(model), &iter, DT_LIB_TAGGING_COL_TAG, ((dt_tag_t *)tags->data)->tag,
                               DT_LIB_TAGGING_COL_ID, ((dt_tag_t *)tags->data)->id, -1);
        } while((tags = g_list_next(tags)) != NULL);

        // Free result...
        dt_tag_free_result(&tags);
    }



    gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
    g_object_unref(model);
}
Example #11
0
static void on_mouse_over_image_changed(gpointer instance, gpointer user_data)
{
  dt_job_t *job = dt_control_job_create(&on_mouse_over_image_changed_callback_job, "lua: on mouse over image changed");
  if(job)
  {
    on_mouse_over_image_changed_callback_data_t *t
        = (on_mouse_over_image_changed_callback_data_t *)calloc(1, sizeof(on_mouse_over_image_changed_callback_data_t));
    if(!t)
    {
      dt_control_job_dispose(job);
    }
    else
    {
      dt_control_job_set_params(job, t);
      t->imgid = dt_control_get_mouse_over_id();
      dt_control_add_job(darktable.control, DT_JOB_QUEUE_USER_FG, job);
    }
  }
}
Example #12
0
static gboolean _lib_filmstrip_paste_history_key_accel_callback(GtkAccelGroup *accel_group,
                                                                GObject *aceeleratable, guint keyval,
                                                                GdkModifierType modifier, gpointer data)
{
  dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)data;
  int mode = dt_conf_get_int("plugins/lighttable/copy_history/pastemode");

  if(dt_history_copy_and_paste_on_selection(strip->history_copy_imgid, (mode == 0) ? TRUE : FALSE,
                                            strip->dg.selops) != 0)
  {
    int32_t mouse_over_id = dt_control_get_mouse_over_id();
    if(mouse_over_id <= 0) return FALSE;

    dt_history_copy_and_paste_on_image(strip->history_copy_imgid, mouse_over_id, (mode == 0) ? TRUE : FALSE,
                                       strip->dg.selops);
  }

  dt_control_queue_redraw_center();
  return TRUE;
}
Example #13
0
static void _lib_geotagging_calculate_offset_callback(GtkWidget *widget, dt_lib_module_t *self)
{
  dt_lib_geotagging_t *d = (dt_lib_geotagging_t *)self->data;
  const gchar *gps_time = gtk_entry_get_text(GTK_ENTRY(d->floating_window_entry));
  if(gps_time)
  {
    gchar **tokens = g_strsplit(gps_time, ":", 0);
    if(tokens[0] != '\0' && tokens[1] != '\0' && tokens[2] != '\0')
    {
      if(g_ascii_isdigit(tokens[0][0]) && g_ascii_isdigit(tokens[0][1]) && tokens[0][2] == '\0'
         && g_ascii_isdigit(tokens[1][0]) && g_ascii_isdigit(tokens[1][1]) && tokens[1][2] == '\0'
         && g_ascii_isdigit(tokens[2][0]) && g_ascii_isdigit(tokens[2][1]) && tokens[2][2] == '\0')
      {
        int h, m, s;
        h = (tokens[0][0] - '0') * 10 + tokens[0][1] - '0';
        m = (tokens[1][0] - '0') * 10 + tokens[1][1] - '0';
        s = (tokens[2][0] - '0') * 10 + tokens[2][1] - '0';
        if(h < 24 && m < 60 && s < 60)
        {
          // finally a valid time
          // get imgid
          int32_t imgid = -1;
          sqlite3_stmt *stmt;
          DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                                      "select imgid from selected_images order by imgid asc limit 1", -1,
                                      &stmt, NULL);
          if(sqlite3_step(stmt) == SQLITE_ROW)
            imgid = sqlite3_column_int(stmt, 0);
          else // no selection is used, use mouse over id
            imgid = dt_control_get_mouse_over_id();
          sqlite3_finalize(stmt);

          if(imgid > 0)
          {
            const dt_image_t *cimg = dt_image_cache_get(darktable.image_cache, imgid, 'r');
            // get the exif_datetime_taken and parse it
            gint year;
            gint month;
            gint day;
            gint hour;
            gint minute;
            gint second;

            if(sscanf(cimg->exif_datetime_taken, "%d:%d:%d %d:%d:%d", (int *)&year, (int *)&month,
                      (int *)&day, (int *)&hour, (int *)&minute, (int *)&second) == 6)
            {
              // calculate the offset
              long int exif_seconds = hour * 60 * 60 + minute * 60 + second;
              long int gps_seconds = h * 60 * 60 + m * 60 + s;
              long int offset = gps_seconds - exif_seconds;
              // transform the offset back into a string
              gchar sign = (offset < 0) ? '-' : '+';
              offset = labs(offset);
              gint offset_h = offset / (60 * 60);
              offset -= offset_h * 60 * 60;
              gint offset_m = offset / 60;
              offset -= offset_m * 60;
              gchar *offset_str = g_strdup_printf("%c%02d:%02d:%02ld", sign, offset_h, offset_m, offset);
              // write the offset into d->offset_entry
              gtk_entry_set_text(GTK_ENTRY(d->offset_entry), offset_str);
              g_free(offset_str);
            }

            dt_image_cache_read_release(darktable.image_cache, cimg);
          }
        }
      }
    }
    g_strfreev(tokens);
  }
  gtk_widget_destroy(d->floating_window);
}
Example #14
0
static void update(dt_lib_module_t *user_data, gboolean early_bark_out)
{
//   early_bark_out = FALSE; // FIXME: when barking out early we don't update on ctrl-a/ctrl-shift-a. but otherwise it's impossible to edit text
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_metadata_t *d  = (dt_lib_metadata_t *)self->data;
  int imgsel = dt_control_get_mouse_over_id();
  if(early_bark_out && imgsel == d->imgsel)
    return;

  d->imgsel = imgsel;

  sqlite3_stmt *stmt;

  GList *title       = NULL;
  uint32_t title_count       = 0;
  GList *description = NULL;
  uint32_t description_count = 0;
  GList *creator     = NULL;
  uint32_t creator_count     = 0;
  GList *publisher   = NULL;
  uint32_t publisher_count   = 0;
  GList *rights      = NULL;
  uint32_t rights_count     = 0;

  // using dt_metadata_get() is not possible here. we want to do all this in a single pass, everything else takes ages.
  if(imgsel < 0)  // selected images
  {
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select key, value from meta_data where id in (select imgid from selected_images) group by key, value order by value", -1, &stmt, NULL);
  }
  else     // single image under mouse cursor
  {
    char query[1024];
    snprintf(query, 1024, "select key, value from meta_data where id = %d group by key, value order by value", imgsel);
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
  }
  while(sqlite3_step(stmt) == SQLITE_ROW)
  {
    char *value = g_strdup((char *)sqlite3_column_text(stmt, 1));
    if(sqlite3_column_bytes(stmt,1))
    {
      switch(sqlite3_column_int(stmt, 0))
      {
        case DT_METADATA_XMP_DC_CREATOR:
          creator_count++;
          creator = g_list_append(creator, value);
          break;
        case DT_METADATA_XMP_DC_PUBLISHER:
          publisher_count++;
          publisher = g_list_append(publisher, value);
          break;
        case DT_METADATA_XMP_DC_TITLE:
          title_count++;
          title = g_list_append(title, value);
          break;
        case DT_METADATA_XMP_DC_DESCRIPTION:
          description_count++;
          description = g_list_append(description, value);
          break;
        case DT_METADATA_XMP_DC_RIGHTS:
          rights_count++;
          rights = g_list_append(rights, value);
          break;
      }
    }
  }
  sqlite3_finalize(stmt);

  fill_combo_box_entry(&(d->title), title_count, &title, &(d->multi_title));
  fill_combo_box_entry(&(d->description), description_count, &description, &(d->multi_description));
  fill_combo_box_entry(&(d->rights), rights_count, &rights, &(d->multi_rights));
  fill_combo_box_entry(&(d->creator), creator_count, &creator, &(d->multi_creator));
  fill_combo_box_entry(&(d->publisher), publisher_count, &publisher, &(d->multi_publisher));

  g_list_free(g_list_first(title));
  g_list_free(g_list_first(description));
  g_list_free(g_list_first(creator));
  g_list_free(g_list_first(publisher));
  g_list_free(g_list_first(rights));
}
Example #15
0
/* update all values to reflect mouse over image id or no data at all */
static void _metadata_view_update_values(dt_lib_module_t *self)
{
  dt_lib_metadata_view_t *d = (dt_lib_metadata_view_t *)self->data;
  int32_t mouse_over_id = dt_control_get_mouse_over_id();

  if (mouse_over_id == -1)
  {
    const dt_view_t *cv = dt_view_manager_get_current_view(darktable.view_manager);
    if(cv->view((dt_view_t*)cv) == DT_VIEW_DARKROOM)
    {
      mouse_over_id = darktable.develop->image_storage.id;
    }
    else
    {
      sqlite3_stmt *stmt;
      DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images limit 1", -1, &stmt, NULL);
      if(sqlite3_step(stmt) == SQLITE_ROW)
        mouse_over_id = sqlite3_column_int(stmt, 0);
      sqlite3_finalize(stmt);
    }
  }

  if(mouse_over_id >= 0)
  {
    char value[512];
    char pathname[PATH_MAX];
    const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, mouse_over_id);
    if(!img) goto fill_minuses;
    if(img->film_id == -1)
    {
      dt_image_cache_read_release(darktable.image_cache, img);
      goto fill_minuses;
    }

    /* update all metadata */

    dt_image_film_roll(img, value, sizeof(value));
    _metadata_update_value(d->metadata[md_internal_filmroll], value);
    const int tp = 512;
    char tooltip[tp];
    snprintf(tooltip, tp, _("double click to jump to film roll\n%s"), value);
    g_object_set(G_OBJECT(d->metadata[md_internal_filmroll]), "tooltip-text", tooltip, (char *)NULL);

    snprintf(value,sizeof(value),"%d", img->id);
    _metadata_update_value(d->metadata[md_internal_imgid], value);

    snprintf(value,sizeof(value),"%d", img->group_id);
    _metadata_update_value(d->metadata[md_internal_groupid], value);

    _metadata_update_value(d->metadata[md_internal_filename], img->filename);

    snprintf(value,sizeof(value),"%d", img->version);
    _metadata_update_value(d->metadata[md_internal_version], value);

    gboolean from_cache = FALSE;
    dt_image_full_path(img->id, pathname, sizeof(pathname), &from_cache);
    _metadata_update_value(d->metadata[md_internal_fullpath], pathname);

    snprintf(value, sizeof(value), "%s", (img->flags & DT_IMAGE_LOCAL_COPY)?_("yes"):_("no"));
    _metadata_update_value(d->metadata[md_internal_local_copy], value);

    // TODO: decide if this should be removed for a release. maybe #ifdef'ing to only add it to git compiles?

    // the bits of the flags
    {
      #define EMPTY_FIELD '.'
      #define FALSE_FIELD '.'
      #define TRUE_FIELD '!'

      char *tooltip = NULL;
      char *flag_descriptions[] = { N_("unused"),
                                    N_("unused/deprecated"),
                                    N_("ldr"),
                                    N_("raw"),
                                    N_("hdr"),
                                    N_("marked for deletion"),
                                    N_("auto-applying presets applied"),
                                    N_("legacy flag. set for all new images"),
                                    N_("local copy"),
                                    N_("has .txt"),
                                    N_("has .wav")
      };
      char *tooltip_parts[13] = { 0 };
      int next_tooltip_part = 0;

      memset(value, EMPTY_FIELD, sizeof(value));

      int stars = img->flags & 0x7;
      char *star_string = NULL;
      if(stars == 6)
      {
        value[0] = 'x';
        tooltip_parts[next_tooltip_part++] = _("image rejected");
      }
      else
      {
        value[0] = '0' + stars;
        tooltip_parts[next_tooltip_part++] = star_string = g_strdup_printf(ngettext("image has %d star", "image has %d stars", stars), stars);
      }


      if(img->flags & 8)
      {
        value[1] = TRUE_FIELD;
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[0]);
      }
      else
        value[1] = FALSE_FIELD;

      if(img->flags & DT_IMAGE_THUMBNAIL_DEPRECATED)
      {
        value[2] = TRUE_FIELD;
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[1]);
      }
      else
        value[2] = FALSE_FIELD;

      if(img->flags & DT_IMAGE_LDR)
      {
        value[3] = 'l';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[2]);
      }

      if(img->flags & DT_IMAGE_RAW)
      {
        value[4] = 'r';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[3]);
      }

      if(img->flags & DT_IMAGE_HDR)
      {
        value[5] = 'h';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[4]);
      }

      if(img->flags & DT_IMAGE_REMOVE)
      {
        value[6] = 'd';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[5]);
      }

      if(img->flags & DT_IMAGE_AUTO_PRESETS_APPLIED)
      {
        value[7] = 'a';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[6]);
      }

      if(img->flags & DT_IMAGE_NO_LEGACY_PRESETS)
      {
        value[8] = 'p';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[7]);
      }

      if(img->flags & DT_IMAGE_LOCAL_COPY)
      {
        value[9] = 'c';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[8]);
      }

      if(img->flags & DT_IMAGE_HAS_TXT)
      {
        value[10] = 't';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[9]);
      }

      if(img->flags & DT_IMAGE_HAS_WAV)
      {
        value[11] = 'w';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[10]);
      }

      value[12] = '\0';

      tooltip = g_strjoinv("\n", tooltip_parts);

      _metadata_update_value(d->metadata[md_internal_flags], value);
      g_object_set(G_OBJECT(d->metadata[md_internal_flags]), "tooltip-text", tooltip, (char *)NULL);

      g_free(star_string);
      g_free(tooltip);

      #undef EMPTY_FIELD
      #undef FALSE_FIELD
      #undef TRUE_FIELD
    }

    /* EXIF */
    _metadata_update_value_end(d->metadata[md_exif_model], img->exif_model);
    _metadata_update_value_end(d->metadata[md_exif_lens], img->exif_lens);
    _metadata_update_value_end(d->metadata[md_exif_maker], img->exif_maker);

    snprintf(value, sizeof(value), "F/%.1f", img->exif_aperture);
    _metadata_update_value(d->metadata[md_exif_aperture], value);

    if(img->exif_exposure <= 0.5) snprintf(value, sizeof(value), "1/%.0f", 1.0/img->exif_exposure);
    else                          snprintf(value, sizeof(value), "%.1f''", img->exif_exposure);
    _metadata_update_value(d->metadata[md_exif_exposure], value);

    snprintf(value, sizeof(value), "%.0f mm", img->exif_focal_length);
    _metadata_update_value(d->metadata[md_exif_focal_length], value);

    if (isnan(img->exif_focus_distance) || fpclassify(img->exif_focus_distance) == FP_ZERO)
    {
      _metadata_update_value(d->metadata[md_exif_focus_distance], NODATA_STRING);
    }
    else
    {
      snprintf(value, sizeof(value), "%.2f m", img->exif_focus_distance);
      _metadata_update_value(d->metadata[md_exif_focus_distance], value);
    }

    snprintf(value, sizeof(value), "%.0f", img->exif_iso);
    _metadata_update_value(d->metadata[md_exif_iso], value);

    _metadata_update_value(d->metadata[md_exif_datetime], img->exif_datetime_taken);

    snprintf(value, sizeof(value), "%d", img->height);
    _metadata_update_value(d->metadata[md_exif_height], value);
    snprintf(value, sizeof(value), "%d", img->width);
    _metadata_update_value(d->metadata[md_exif_width], value);

    /* XMP */
    GList *res;
    if((res = dt_metadata_get(img->id, "Xmp.dc.title", NULL))!=NULL)
    {
      snprintf(value, sizeof(value), "%s", (char*)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_title], value);

    if((res = dt_metadata_get(img->id, "Xmp.dc.creator", NULL))!=NULL)
    {
      snprintf(value, sizeof(value), "%s", (char*)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_creator], value);

    if((res = dt_metadata_get(img->id, "Xmp.dc.rights", NULL))!=NULL)
    {
      snprintf(value, sizeof(value), "%s", (char*)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_rights], value);

    /* geotagging */
    /* latitude */
    if(isnan(img->latitude))
    {
      _metadata_update_value(d->metadata[md_geotagging_lat], NODATA_STRING);
    }
    else
    {
#ifdef HAVE_MAP
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *latitude = osd_latitude_str(img->latitude);
        _metadata_update_value(d->metadata[md_geotagging_lat], latitude);
        g_free(latitude);
      }
      else
      {
#endif
        gchar NS = img->latitude<0?'S':'N';
        snprintf(value, sizeof(value), "%c %09.6f", NS, fabs(img->latitude));
        _metadata_update_value(d->metadata[md_geotagging_lat], value);
#ifdef HAVE_MAP
      }
#endif
    }
    /* longitude */
    if(isnan(img->longitude))
    {
      _metadata_update_value(d->metadata[md_geotagging_lon], NODATA_STRING);
    }
    else
    {
#ifdef HAVE_MAP
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *longitude = osd_longitude_str(img->longitude);
        _metadata_update_value(d->metadata[md_geotagging_lon], longitude);
        g_free(longitude);
      }
      else
      {
#endif
        gchar EW = img->longitude<0?'W':'E';
        snprintf(value, sizeof(value), "%c %010.6f", EW, fabs(img->longitude));
        _metadata_update_value(d->metadata[md_geotagging_lon], value);
#ifdef HAVE_MAP
      }
#endif
    }

    /* release img */
    dt_image_cache_read_release(darktable.image_cache, img);

  }

  return;

  /* reset */
fill_minuses:
  for(int k=0; k<md_size; k++)
    _metadata_update_value(d->metadata[k],NODATA_STRING);

}
Example #16
0
static gboolean _lib_tagging_tag_show(GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval,
                                      GdkModifierType modifier, dt_lib_module_t *self)
{
  int mouse_over_id = -1;
  int zoom = dt_conf_get_int("plugins/lighttable/images_in_row");

  // the order is:
  // if(zoom == 1) => currently shown image
  // else if(selection not empty) => selected images
  // else if(cursor over image) => hovered image
  // else => return
  if(zoom == 1 || dt_collection_get_selected_count(darktable.collection) == 0)
  {
    mouse_over_id = dt_control_get_mouse_over_id();
    if(mouse_over_id < 0) return TRUE;
  }

  dt_lib_tagging_t *d = (dt_lib_tagging_t *)self->data;
  d->floating_tag_imgid = mouse_over_id;

  gint x, y;
  gint px, py, w, h;
  GtkWidget *window = dt_ui_main_window(darktable.gui->ui);
  GtkWidget *center = dt_ui_center(darktable.gui->ui);
  gdk_window_get_origin(gtk_widget_get_window(center), &px, &py);

  w = gdk_window_get_width(gtk_widget_get_window(center));
  h = gdk_window_get_height(gtk_widget_get_window(center));

  x = px + 0.5 * (w - FLOATING_ENTRY_WIDTH);
  y = py + h - 50;

  /* put the floating box at the mouse pointer */
  //   gint pointerx, pointery;
  //   GdkDevice *device =
  //   gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gtk_widget_get_display(widget)));
  //   gdk_window_get_device_position (gtk_widget_get_window (widget), device, &pointerx, &pointery, NULL);
  //   x = px + pointerx + 1;
  //   y = py + pointery + 1;

  d->floating_tag_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  /* stackoverflow.com/questions/1925568/how-to-give-keyboard-focus-to-a-pop-up-gtk-window */
  gtk_widget_set_can_focus(d->floating_tag_window, TRUE);
  gtk_window_set_decorated(GTK_WINDOW(d->floating_tag_window), FALSE);
  gtk_window_set_type_hint(GTK_WINDOW(d->floating_tag_window), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
  gtk_window_set_transient_for(GTK_WINDOW(d->floating_tag_window), GTK_WINDOW(window));
  gtk_widget_set_opacity(d->floating_tag_window, 0.8);
  gtk_window_move(GTK_WINDOW(d->floating_tag_window), x, y);


  GtkWidget *entry = gtk_entry_new();
  gtk_widget_set_size_request(entry, FLOATING_ENTRY_WIDTH, -1);
  gtk_widget_add_events(entry, GDK_FOCUS_CHANGE_MASK);

  GtkEntryCompletion *completion = gtk_entry_completion_new();
  gtk_entry_completion_set_model(completion, gtk_tree_view_get_model(GTK_TREE_VIEW(d->related)));
  gtk_entry_completion_set_text_column(completion, 0);
  gtk_entry_completion_set_inline_completion(completion, TRUE);
  gtk_entry_completion_set_popup_set_width(completion, FALSE);
  gtk_entry_set_completion(GTK_ENTRY(entry), completion);

  gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
  gtk_container_add(GTK_CONTAINER(d->floating_tag_window), entry);
  g_signal_connect(entry, "focus-out-event", G_CALLBACK(_lib_tagging_tag_destroy), d->floating_tag_window);
  g_signal_connect(entry, "key-press-event", G_CALLBACK(_lib_tagging_tag_key_press), self);

  gtk_widget_show_all(d->floating_tag_window);
  gtk_widget_grab_focus(entry);
  gtk_window_present(GTK_WINDOW(d->floating_tag_window));

  return TRUE;
}
Example #17
0
/* update all values to reflect mouse over image id or no data at all */
static void _metadata_view_update_values(dt_lib_module_t *self)
{
  dt_lib_metadata_view_t *d = (dt_lib_metadata_view_t *)self->data;
  int32_t mouse_over_id = dt_control_get_mouse_over_id();

  if(mouse_over_id == -1)
  {
    const dt_view_t *cv = dt_view_manager_get_current_view(darktable.view_manager);
    if(cv->view((dt_view_t *)cv) == DT_VIEW_DARKROOM)
    {
      mouse_over_id = darktable.develop->image_storage.id;
    }
    else
    {
      sqlite3_stmt *stmt;
      DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images limit 1",
                                  -1, &stmt, NULL);
      if(sqlite3_step(stmt) == SQLITE_ROW) mouse_over_id = sqlite3_column_int(stmt, 0);
      sqlite3_finalize(stmt);
    }
  }

  if(mouse_over_id >= 0)
  {
    char value[512];
    char pathname[PATH_MAX] = { 0 };
    const dt_image_t *img = dt_image_cache_get(darktable.image_cache, mouse_over_id, 'r');
    if(!img) goto fill_minuses;
    if(img->film_id == -1)
    {
      dt_image_cache_read_release(darktable.image_cache, img);
      goto fill_minuses;
    }

    /* update all metadata */

    dt_image_film_roll(img, value, sizeof(value));
    _metadata_update_value(d->metadata[md_internal_filmroll], value);
    const int tp = 512;
    char tooltip[tp];
    snprintf(tooltip, tp, _("double click to jump to film roll\n%s"), value);
    gtk_widget_set_tooltip_text(GTK_WIDGET(d->metadata[md_internal_filmroll]), tooltip);

    snprintf(value, sizeof(value), "%d", img->id);
    _metadata_update_value(d->metadata[md_internal_imgid], value);

    snprintf(value, sizeof(value), "%d", img->group_id);
    _metadata_update_value(d->metadata[md_internal_groupid], value);

    _metadata_update_value(d->metadata[md_internal_filename], img->filename);

    snprintf(value, sizeof(value), "%d", img->version);
    _metadata_update_value(d->metadata[md_internal_version], value);

    gboolean from_cache = FALSE;
    dt_image_full_path(img->id, pathname, sizeof(pathname), &from_cache);
    _metadata_update_value(d->metadata[md_internal_fullpath], pathname);

    snprintf(value, sizeof(value), "%s", (img->flags & DT_IMAGE_LOCAL_COPY) ? _("yes") : _("no"));
    _metadata_update_value(d->metadata[md_internal_local_copy], value);

    // TODO: decide if this should be removed for a release. maybe #ifdef'ing to only add it to git compiles?

    // the bits of the flags
#if SHOW_FLAGS
    {
      #define EMPTY_FIELD '.'
      #define FALSE_FIELD '.'
      #define TRUE_FIELD '!'

      char *tooltip = NULL;
      char *flag_descriptions[] = { N_("unused"),
                                    N_("unused/deprecated"),
                                    N_("ldr"),
                                    N_("raw"),
                                    N_("hdr"),
                                    N_("marked for deletion"),
                                    N_("auto-applying presets applied"),
                                    N_("legacy flag. set for all new images"),
                                    N_("local copy"),
                                    N_("has .txt"),
                                    N_("has .wav")
      };
      char *tooltip_parts[14] = { 0 };
      int next_tooltip_part = 0;

      memset(value, EMPTY_FIELD, sizeof(value));

      int stars = img->flags & 0x7;
      char *star_string = NULL;
      if(stars == 6)
      {
        value[0] = 'x';
        tooltip_parts[next_tooltip_part++] = _("image rejected");
      }
      else
      {
        value[0] = '0' + stars;
        tooltip_parts[next_tooltip_part++] = star_string = g_strdup_printf(ngettext("image has %d star", "image has %d stars", stars), stars);
      }


      if(img->flags & 8)
      {
        value[1] = TRUE_FIELD;
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[0]);
      }
      else
        value[1] = FALSE_FIELD;

      if(img->flags & DT_IMAGE_THUMBNAIL_DEPRECATED)
      {
        value[2] = TRUE_FIELD;
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[1]);
      }
      else
        value[2] = FALSE_FIELD;

      if(img->flags & DT_IMAGE_LDR)
      {
        value[3] = 'l';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[2]);
      }

      if(img->flags & DT_IMAGE_RAW)
      {
        value[4] = 'r';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[3]);
      }

      if(img->flags & DT_IMAGE_HDR)
      {
        value[5] = 'h';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[4]);
      }

      if(img->flags & DT_IMAGE_REMOVE)
      {
        value[6] = 'd';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[5]);
      }

      if(img->flags & DT_IMAGE_AUTO_PRESETS_APPLIED)
      {
        value[7] = 'a';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[6]);
      }

      if(img->flags & DT_IMAGE_NO_LEGACY_PRESETS)
      {
        value[8] = 'p';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[7]);
      }

      if(img->flags & DT_IMAGE_LOCAL_COPY)
      {
        value[9] = 'c';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[8]);
      }

      if(img->flags & DT_IMAGE_HAS_TXT)
      {
        value[10] = 't';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[9]);
      }

      if(img->flags & DT_IMAGE_HAS_WAV)
      {
        value[11] = 'w';
        tooltip_parts[next_tooltip_part++] = _(flag_descriptions[10]);
      }

      static const struct
      {
        char *tooltip;
        char flag;
      } loaders[] =
      {
        { N_("unknown"), EMPTY_FIELD},
        { N_("tiff"), 't'},
        { N_("png"), 'p'},
        { N_("j2k"), 'J'},
        { N_("jpeg"), 'j'},
        { N_("exr"), 'e'},
        { N_("rgbe"), 'R'},
        { N_("pfm"), 'P'},
        { N_("GraphicsMagick"), 'g'},
        { N_("rawspeed"), 'r'}
      };

      int loader = (unsigned int)img->loader < sizeof(loaders) / sizeof(*loaders) ? img->loader : 0;
      value[12] = loaders[loader].flag;
      char *loader_tooltip = g_strdup_printf(_("loader: %s"), _(loaders[loader].tooltip));
      tooltip_parts[next_tooltip_part++] = loader_tooltip;

      value[13] = '\0';

      tooltip = g_strjoinv("\n", tooltip_parts);
      g_free(loader_tooltip);

      _metadata_update_value(d->metadata[md_internal_flags], value);
      gtk_widget_set_tooltip_text(GTK_WIDGET(d->metadata[md_internal_flags]), tooltip);

      g_free(star_string);
      g_free(tooltip);

      #undef EMPTY_FIELD
      #undef FALSE_FIELD
      #undef TRUE_FIELD
    }
#endif // SHOW_FLAGS

    /* EXIF */
    _metadata_update_value_end(d->metadata[md_exif_model], img->camera_alias);
    _metadata_update_value_end(d->metadata[md_exif_lens], img->exif_lens);
    _metadata_update_value_end(d->metadata[md_exif_maker], img->camera_maker);

    snprintf(value, sizeof(value), "F/%.1f", img->exif_aperture);
    _metadata_update_value(d->metadata[md_exif_aperture], value);

    if(img->exif_exposure <= 0.5)
      snprintf(value, sizeof(value), "1/%.0f", 1.0 / img->exif_exposure);
    else
      snprintf(value, sizeof(value), "%.1f''", img->exif_exposure);
    _metadata_update_value(d->metadata[md_exif_exposure], value);

    snprintf(value, sizeof(value), "%.0f mm", img->exif_focal_length);
    _metadata_update_value(d->metadata[md_exif_focal_length], value);

    if(isnan(img->exif_focus_distance) || fpclassify(img->exif_focus_distance) == FP_ZERO)
    {
      _metadata_update_value(d->metadata[md_exif_focus_distance], NODATA_STRING);
    }
    else
    {
      snprintf(value, sizeof(value), "%.2f m", img->exif_focus_distance);
      _metadata_update_value(d->metadata[md_exif_focus_distance], value);
    }

    snprintf(value, sizeof(value), "%.0f", img->exif_iso);
    _metadata_update_value(d->metadata[md_exif_iso], value);

    struct tm tt_exif = { 0 };
    if(sscanf(img->exif_datetime_taken, "%d:%d:%d %d:%d:%d", &tt_exif.tm_year, &tt_exif.tm_mon,
      &tt_exif.tm_mday, &tt_exif.tm_hour, &tt_exif.tm_min, &tt_exif.tm_sec) == 6)
    {
      char datetime[200];
      tt_exif.tm_year -= 1900;
      tt_exif.tm_mon--;
      tt_exif.tm_isdst = -1;
      mktime(&tt_exif);
      // just %c is too long and includes a time zone that we don't know from exif
      strftime(datetime, sizeof(datetime), "%a %x %X", &tt_exif);
      _metadata_update_value(d->metadata[md_exif_datetime], datetime);
    }
    else
      _metadata_update_value(d->metadata[md_exif_datetime], img->exif_datetime_taken);

    snprintf(value, sizeof(value), "%d", img->height);
    _metadata_update_value(d->metadata[md_exif_height], value);
    snprintf(value, sizeof(value), "%d", img->width);
    _metadata_update_value(d->metadata[md_exif_width], value);

    /* XMP */
    GList *res;
    if((res = dt_metadata_get(img->id, "Xmp.dc.title", NULL)) != NULL)
    {
      snprintf(value, sizeof(value), "%s", (char *)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_title], value);

    if((res = dt_metadata_get(img->id, "Xmp.dc.creator", NULL)) != NULL)
    {
      snprintf(value, sizeof(value), "%s", (char *)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_creator], value);

    if((res = dt_metadata_get(img->id, "Xmp.dc.rights", NULL)) != NULL)
    {
      snprintf(value, sizeof(value), "%s", (char *)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_rights], value);

    /* geotagging */
    /* latitude */
    if(isnan(img->latitude))
    {
      _metadata_update_value(d->metadata[md_geotagging_lat], NODATA_STRING);
    }
    else
    {
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *latitude = dt_util_latitude_str(img->latitude);
        _metadata_update_value(d->metadata[md_geotagging_lat], latitude);
        g_free(latitude);
      }
      else
      {
        gchar NS = img->latitude < 0 ? 'S' : 'N';
        snprintf(value, sizeof(value), "%c %09.6f", NS, fabs(img->latitude));
        _metadata_update_value(d->metadata[md_geotagging_lat], value);
      }
    }
    /* longitude */
    if(isnan(img->longitude))
    {
      _metadata_update_value(d->metadata[md_geotagging_lon], NODATA_STRING);
    }
    else
    {
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *longitude = dt_util_longitude_str(img->longitude);
        _metadata_update_value(d->metadata[md_geotagging_lon], longitude);
        g_free(longitude);
      }
      else
      {
        gchar EW = img->longitude < 0 ? 'W' : 'E';
        snprintf(value, sizeof(value), "%c %010.6f", EW, fabs(img->longitude));
        _metadata_update_value(d->metadata[md_geotagging_lon], value);
      }
    }
    /* elevation */
    if(isnan(img->elevation))
    {
      _metadata_update_value(d->metadata[md_geotagging_ele], NODATA_STRING);
    }
    else
    {
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *elevation = dt_util_elevation_str(img->elevation);
        _metadata_update_value(d->metadata[md_geotagging_ele], elevation);
        g_free(elevation);
      }
      else
      {
        snprintf(value, sizeof(value), "%.2f %s", img->elevation, _("m"));
        _metadata_update_value(d->metadata[md_geotagging_ele], value);
      }
    }

    /* release img */
    dt_image_cache_read_release(darktable.image_cache, img);

#ifdef USE_LUA
    dt_lua_async_call_alien(lua_update_metadata,
        0,NULL,NULL,
        LUA_ASYNC_TYPENAME,"void*",self,
        LUA_ASYNC_TYPENAME,"int32_t",mouse_over_id,LUA_ASYNC_DONE);
#endif
  }

  return;

/* reset */
fill_minuses:
  for(int k = 0; k < md_size; k++) _metadata_update_value(d->metadata[k], NODATA_STRING);
#ifdef USE_LUA
  dt_lua_async_call_alien(lua_update_metadata,
      0,NULL,NULL,
        LUA_ASYNC_TYPENAME,"void*",self,
        LUA_ASYNC_TYPENAME,"int32_t",-1,LUA_ASYNC_DONE);
#endif
}
Example #18
0
static void update(dt_lib_module_t *user_data, gboolean early_bark_out)
{
  //   early_bark_out = FALSE; // FIXME: when barking out early we don't update on ctrl-a/ctrl-shift-a. but
  //   otherwise it's impossible to edit text
  const dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_metadata_t *d = (dt_lib_metadata_t *)self->data;
  const int imgsel = dt_control_get_mouse_over_id();
  if(early_bark_out && imgsel == d->imgsel) return;

  d->imgsel = imgsel;

  sqlite3_stmt *stmt;

  GList *title = NULL;
  uint32_t title_count = 0;
  GList *description = NULL;
  uint32_t description_count = 0;
  GList *creator = NULL;
  uint32_t creator_count = 0;
  GList *publisher = NULL;
  uint32_t publisher_count = 0;
  GList *rights = NULL;
  uint32_t rights_count = 0;

  // using dt_metadata_get() is not possible here. we want to do all this in a single pass, everything else
  // takes ages.
  if(imgsel < 0) // selected images
  {
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT key, value FROM main.meta_data WHERE id IN "
                                                               "(SELECT imgid FROM main.selected_images) GROUP BY "
                                                               "key, value ORDER BY value",
                                -1, &stmt, NULL);
  }
  else // single image under mouse cursor
  {
    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT key, value FROM main.meta_data "
                                                               "WHERE id = ?1 GROUP BY key, value ORDER BY value",
                                -1, &stmt, NULL);
    DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgsel);
  }
  while(sqlite3_step(stmt) == SQLITE_ROW)
  {
    if(sqlite3_column_bytes(stmt, 1))
    {
      char *value = g_strdup((char *)sqlite3_column_text(stmt, 1));
      switch(sqlite3_column_int(stmt, 0))
      {
        case DT_METADATA_XMP_DC_CREATOR:
          creator_count++;
          creator = g_list_append(creator, value);
          break;
        case DT_METADATA_XMP_DC_PUBLISHER:
          publisher_count++;
          publisher = g_list_append(publisher, value);
          break;
        case DT_METADATA_XMP_DC_TITLE:
          title_count++;
          title = g_list_append(title, value);
          break;
        case DT_METADATA_XMP_DC_DESCRIPTION:
          description_count++;
          description = g_list_append(description, value);
          break;
        case DT_METADATA_XMP_DC_RIGHTS:
          rights_count++;
          rights = g_list_append(rights, value);
          break;
      }
    }
  }
  sqlite3_finalize(stmt);

  fill_combo_box_entry(d->title, title_count, title, &(d->multi_title));
  fill_combo_box_entry(d->description, description_count, description, &(d->multi_description));
  fill_combo_box_entry(d->rights, rights_count, rights, &(d->multi_rights));
  fill_combo_box_entry(d->creator, creator_count, creator, &(d->multi_creator));
  fill_combo_box_entry(d->publisher, publisher_count, publisher, &(d->multi_publisher));

  g_list_free_full(title, g_free);
  g_list_free_full(description, g_free);
  g_list_free_full(creator, g_free);
  g_list_free_full(publisher, g_free);
  g_list_free_full(rights, g_free);
}
Example #19
0
/* update all values to reflect mouse over image id or no data at all */
static void _metadata_view_update_values(dt_lib_module_t *self)
{
  dt_lib_metadata_view_t *d = (dt_lib_metadata_view_t *)self->data;
  int32_t mouse_over_id = dt_control_get_mouse_over_id();

  if (mouse_over_id == -1)
  {
    const dt_view_t *cv = dt_view_manager_get_current_view(darktable.view_manager);
    if(cv->view((dt_view_t*)cv) == DT_VIEW_DARKROOM)
    {
      mouse_over_id = darktable.develop->image_storage.id;
    }
    else
    {
      sqlite3_stmt *stmt;
      DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images limit 1", -1, &stmt, NULL);
      if(sqlite3_step(stmt) == SQLITE_ROW)
        mouse_over_id = sqlite3_column_int(stmt, 0);
      sqlite3_finalize(stmt);
    }
  }

  if(mouse_over_id >= 0)
  {
    char value[512];
    char pathname[PATH_MAX];
    const dt_image_t *img = dt_image_cache_read_get(darktable.image_cache, mouse_over_id);
    if(!img) goto fill_minuses;
    if(img->film_id == -1)
    {
      dt_image_cache_read_release(darktable.image_cache, img);
      goto fill_minuses;
    }

    /* update all metadata */

    dt_image_film_roll(img, value, sizeof(value));
    _metadata_update_value(d->metadata[md_internal_filmroll], value);
    const int tp = 512;
    char tooltip[tp];
    snprintf(tooltip, tp, _("double click to jump to film roll\n%s"), value);
    g_object_set(G_OBJECT(d->metadata[md_internal_filmroll]), "tooltip-text", tooltip, (char *)NULL);

    snprintf(value,sizeof(value),"%d", img->id);
    _metadata_update_value(d->metadata[md_internal_imgid], value);

    _metadata_update_value(d->metadata[md_internal_filename], img->filename);

    snprintf(value,sizeof(value),"%d", img->version);
    _metadata_update_value(d->metadata[md_internal_version], value);

    gboolean from_cache = FALSE;
    dt_image_full_path(img->id, pathname, sizeof(pathname), &from_cache);
    _metadata_update_value(d->metadata[md_internal_fullpath], pathname);

    snprintf(value, sizeof(value), "%s", (img->flags & DT_IMAGE_LOCAL_COPY)?_("yes"):_("no"));
    _metadata_update_value(d->metadata[md_internal_local_copy], value);

    /* EXIF */
    _metadata_update_value_end(d->metadata[md_exif_model], img->exif_model);
    _metadata_update_value_end(d->metadata[md_exif_lens], img->exif_lens);
    _metadata_update_value_end(d->metadata[md_exif_maker], img->exif_maker);

    snprintf(value, sizeof(value), "F/%.1f", img->exif_aperture);
    _metadata_update_value(d->metadata[md_exif_aperture], value);

    if(img->exif_exposure <= 0.5) snprintf(value, sizeof(value), "1/%.0f", 1.0/img->exif_exposure);
    else                          snprintf(value, sizeof(value), "%.1f''", img->exif_exposure);
    _metadata_update_value(d->metadata[md_exif_exposure], value);

    snprintf(value, sizeof(value), "%.0f mm", img->exif_focal_length);
    _metadata_update_value(d->metadata[md_exif_focal_length], value);

    if (isnan(img->exif_focus_distance) || fpclassify(img->exif_focus_distance) == FP_ZERO)
    {
      _metadata_update_value(d->metadata[md_exif_focus_distance], NODATA_STRING);
    }
    else
    {
      snprintf(value, sizeof(value), "%.2f m", img->exif_focus_distance);
      _metadata_update_value(d->metadata[md_exif_focus_distance], value);
    }

    snprintf(value, sizeof(value), "%.0f", img->exif_iso);
    _metadata_update_value(d->metadata[md_exif_iso], value);

    _metadata_update_value(d->metadata[md_exif_datetime], img->exif_datetime_taken);

    snprintf(value, sizeof(value), "%d", img->height);
    _metadata_update_value(d->metadata[md_exif_height], value);
    snprintf(value, sizeof(value), "%d", img->width);
    _metadata_update_value(d->metadata[md_exif_width], value);

    /* XMP */
    GList *res;
    if((res = dt_metadata_get(img->id, "Xmp.dc.title", NULL))!=NULL)
    {
      snprintf(value, sizeof(value), "%s", (char*)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_title], value);

    if((res = dt_metadata_get(img->id, "Xmp.dc.creator", NULL))!=NULL)
    {
      snprintf(value, sizeof(value), "%s", (char*)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_creator], value);

    if((res = dt_metadata_get(img->id, "Xmp.dc.rights", NULL))!=NULL)
    {
      snprintf(value, sizeof(value), "%s", (char*)res->data);
      _filter_non_printable(value, sizeof(value));
      g_list_free_full(res, &g_free);
    }
    else
      snprintf(value, sizeof(value), NODATA_STRING);
    _metadata_update_value(d->metadata[md_xmp_rights], value);

    /* geotagging */
    /* latitude */
    if(isnan(img->latitude))
    {
      _metadata_update_value(d->metadata[md_geotagging_lat], NODATA_STRING);
    }
    else
    {
#ifdef HAVE_MAP
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *latitude = osd_latitude_str(img->latitude);
        _metadata_update_value(d->metadata[md_geotagging_lat], latitude);
        g_free(latitude);
      }
      else
      {
#endif
        gchar NS = img->latitude<0?'S':'N';
        snprintf(value, sizeof(value), "%c %09.6f", NS, fabs(img->latitude));
        _metadata_update_value(d->metadata[md_geotagging_lat], value);
#ifdef HAVE_MAP
      }
#endif
    }
    /* longitude */
    if(isnan(img->longitude))
    {
      _metadata_update_value(d->metadata[md_geotagging_lon], NODATA_STRING);
    }
    else
    {
#ifdef HAVE_MAP
      if(dt_conf_get_bool("plugins/lighttable/metadata_view/pretty_location"))
      {
        gchar *longitude = osd_longitude_str(img->longitude);
        _metadata_update_value(d->metadata[md_geotagging_lon], longitude);
        g_free(longitude);
      }
      else
      {
#endif
        gchar EW = img->longitude<0?'W':'E';
        snprintf(value, sizeof(value), "%c %010.6f", EW, fabs(img->longitude));
        _metadata_update_value(d->metadata[md_geotagging_lon], value);
#ifdef HAVE_MAP
      }
#endif
    }

    /* release img */
    dt_image_cache_read_release(darktable.image_cache, img);

  }

  return;

  /* reset */
fill_minuses:
  for(int k=0; k<md_size; k++)
    _metadata_update_value(d->metadata[k],NODATA_STRING);

}