~ubuntu-branches/ubuntu/saucy/darktable/saucy

« back to all changes in this revision

Viewing changes to src/imageio/storage/disk.c

  • Committer: Bazaar Package Importer
  • Author(s): David Bremner
  • Date: 2011-04-14 23:42:12 UTC
  • Revision ID: james.westby@ubuntu.com-20110414234212-kuffcz5wiu18v6ra
Tags: upstream-0.8
ImportĀ upstreamĀ versionĀ 0.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of darktable,
 
3
    copyright (c) 2009--2010 johannes hanika.
 
4
 
 
5
    darktable is free software: you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License as published by
 
7
    the Free Software Foundation, either version 3 of the License, or
 
8
    (at your option) any later version.
 
9
 
 
10
    darktable is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with darktable.  If not, see <http://www.gnu.org/licenses/>.
 
17
*/
 
18
 
 
19
#include "common/darktable.h"
 
20
#include "common/image.h"
 
21
#include "common/image_cache.h"
 
22
#include "common/imageio_module.h"
 
23
#include "common/imageio.h"
 
24
#include "common/variables.h"
 
25
#include "control/control.h"
 
26
#include "control/conf.h"
 
27
#include "gui/gtk.h"
 
28
#include "dtgtk/button.h"
 
29
#include "dtgtk/paint.h"
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
#include <glade/glade.h>
 
33
 
 
34
DT_MODULE(1)
 
35
 
 
36
// gui data
 
37
typedef struct disk_t
 
38
{
 
39
  GtkEntry *entry;
 
40
}
 
41
disk_t;
 
42
 
 
43
// saved params
 
44
typedef struct dt_imageio_disk_t
 
45
{
 
46
  char filename[1024];
 
47
  dt_variables_params_t *vp;
 
48
}
 
49
dt_imageio_disk_t;
 
50
 
 
51
 
 
52
const char*
 
53
name ()
 
54
{
 
55
  return _("file on disk");
 
56
}
 
57
 
 
58
static void
 
59
button_clicked (GtkWidget *widget, dt_imageio_module_storage_t *self)
 
60
{
 
61
  disk_t *d = (disk_t *)self->gui_data;
 
62
  GtkWidget *win = glade_xml_get_widget (darktable.gui->main_window, "main_window");
 
63
  GtkWidget *filechooser = gtk_file_chooser_dialog_new (_("select directory"),
 
64
                           GTK_WINDOW (win),
 
65
                           GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
 
66
                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
67
                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 
68
                           (char *)NULL);
 
69
 
 
70
  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), FALSE);
 
71
  gchar *old = g_strdup(gtk_entry_get_text(d->entry));
 
72
  char *c = g_strstr_len(old, -1, "$");
 
73
  if(c) *c = '\0';
 
74
  gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), old);
 
75
  g_free(old);
 
76
  if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT)
 
77
  {
 
78
    gchar *dir = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
 
79
    char composed[1024];
 
80
    snprintf(composed, 1024, "%s/$(FILE_NAME)", dir);
 
81
    gtk_entry_set_text(GTK_ENTRY(d->entry), composed);
 
82
    dt_conf_set_string("plugins/imageio/storage/disk/file_directory", composed);
 
83
    g_free(dir);
 
84
  }
 
85
  gtk_widget_destroy (filechooser);
 
86
}
 
87
 
 
88
void
 
89
gui_init (dt_imageio_module_storage_t *self)
 
90
{
 
91
  disk_t *d = (disk_t *)malloc(sizeof(disk_t));
 
92
  self->gui_data = (void *)d;
 
93
  self->widget = gtk_hbox_new(FALSE, 5);
 
94
  GtkWidget *widget;
 
95
 
 
96
  widget = gtk_entry_new();
 
97
  gtk_box_pack_start(GTK_BOX(self->widget), widget, TRUE, TRUE, 0);
 
98
  gchar *dir = dt_conf_get_string("plugins/imageio/storage/disk/file_directory");
 
99
  if(dir)
 
100
  {
 
101
    gtk_entry_set_text(GTK_ENTRY(widget), dir);
 
102
    g_free(dir);
 
103
  }
 
104
  d->entry = GTK_ENTRY(widget);
 
105
  dt_gui_key_accel_block_on_focus (GTK_WIDGET (d->entry));
 
106
  gtk_object_set(GTK_OBJECT(widget), "tooltip-text", _("enter the path where to put exported images:\n"
 
107
                 "$(ROLL_NAME) - roll of the input image\n"
 
108
                 "$(FILE_DIRECTORY) - directory of the input image\n"
 
109
                 "$(FILE_NAME) - basename of the input image\n"
 
110
                 "$(FILE_EXTENSION) - extension of the input image\n"
 
111
                 "$(SEQUENCE) - sequence number\n"
 
112
                 "$(YEAR) - year\n"
 
113
                 "$(MONTH) - month\n"
 
114
                 "$(DAY) - day\n"
 
115
                 "$(HOUR) - hour\n"
 
116
                 "$(MINUTE) - minute\n"
 
117
                 "$(SECOND) - second\n"
 
118
                 "$(EXIF_YEAR) - exif year\n"
 
119
                 "$(EXIF_MONTH) - exif month\n"
 
120
                 "$(EXIF_DAY) - exif day\n"
 
121
                 "$(EXIF_HOUR) - exif hour\n"
 
122
                 "$(EXIF_MINUTE) - exif minute\n"
 
123
                 "$(EXIF_SECOND) - exif second\n"
 
124
                 "$(PICTURES_FOLDER) - pictures folder\n"
 
125
                 "$(HOME_FOLDER) - home folder\n"
 
126
                 "$(DESKTOP_FOLDER) - desktop folder"
 
127
                                                      ), (char *)NULL);
 
128
  widget = dtgtk_button_new(dtgtk_cairo_paint_directory, 0);
 
129
  gtk_widget_set_size_request(widget, 18, 18);
 
130
  gtk_object_set(GTK_OBJECT(widget), "tooltip-text", _("select directory"), (char *)NULL);
 
131
  gtk_box_pack_start(GTK_BOX(self->widget), widget, FALSE, FALSE, 0);
 
132
  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(button_clicked), self);
 
133
}
 
134
 
 
135
void
 
136
gui_cleanup (dt_imageio_module_storage_t *self)
 
137
{
 
138
  free(self->gui_data);
 
139
}
 
140
 
 
141
void
 
142
gui_reset (dt_imageio_module_storage_t *self)
 
143
{
 
144
  disk_t *d = (disk_t *)self->gui_data;
 
145
  // global default can be annoying:
 
146
  // gtk_entry_set_text(GTK_ENTRY(d->entry), "$(FILE_DIRECTORY)/darktable_exported/$(FILE_NAME)");
 
147
  dt_conf_set_string("plugins/imageio/storage/disk/file_directory", gtk_entry_get_text(d->entry));
 
148
}
 
149
 
 
150
int
 
151
store (dt_imageio_module_data_t *sdata, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total)
 
152
{
 
153
  dt_image_t *img = dt_image_cache_get(imgid, 'r');
 
154
  if(!img) return 1;
 
155
  dt_imageio_disk_t *d = (dt_imageio_disk_t *)sdata;
 
156
 
 
157
  char filename[1024]= {0};
 
158
  char dirname[1024]= {0};
 
159
  dt_image_full_path(img->id, dirname, 1024);
 
160
  int fail = 0;
 
161
  // we're potentially called in parallel. have sequence number synchronized:
 
162
  dt_pthread_mutex_lock(&darktable.plugin_threadsafe);
 
163
  {
 
164
 
 
165
    // if filenamepattern is a directory just let att ${FILE_NAME} as default..
 
166
    if ( g_file_test(d->filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) || ((d->filename+strlen(d->filename))[0]=='/' || (d->filename+strlen(d->filename))[0]=='\\') )
 
167
      snprintf (d->filename+strlen(d->filename), 1024-strlen(d->filename), "$(FILE_NAME)");
 
168
 
 
169
    // avoid braindead export which is bound to overwrite at random:
 
170
    if(total > 1 && !g_strrstr(d->filename, "$"))
 
171
    {
 
172
      snprintf(d->filename+strlen(d->filename), 1024-strlen(d->filename), "_$(SEQUENCE)");
 
173
    }
 
174
 
 
175
 
 
176
    d->vp->filename = dirname;
 
177
    d->vp->jobcode = "export";
 
178
    d->vp->img = img;
 
179
    d->vp->sequence = num;
 
180
    dt_variables_expand(d->vp, d->filename, TRUE);
 
181
    strncpy(filename, dt_variables_get_result(d->vp), 1024);
 
182
    strncpy(dirname, filename, 1024);
 
183
 
 
184
    char *c = dirname + strlen(dirname);
 
185
    for(; c>dirname && *c != '/'; c--);
 
186
    if(*c == '/') *c = '\0';
 
187
    if(g_mkdir_with_parents(dirname, 0755))
 
188
    {
 
189
      fprintf(stderr, "[imageio_storage_disk] could not create directory: `%s'!\n", dirname);
 
190
      dt_control_log(_("could not create directory `%s'!"), dirname);
 
191
      dt_image_cache_release(img, 'r');
 
192
      fail = 1;
 
193
      goto failed;
 
194
    }
 
195
 
 
196
    c = filename + strlen(filename);
 
197
    for(; c>filename && *c != '.' && *c != '/' ; c--);
 
198
    if(c <= filename || *c=='/') c = filename + strlen(filename);
 
199
 
 
200
    const char *ext = format->extension(fdata);
 
201
    sprintf(c,".%s",ext);
 
202
 
 
203
    /* prevent overwrite of files */
 
204
    int seq=1;
 
205
failed:
 
206
    if (!fail && g_file_test (filename,G_FILE_TEST_EXISTS))
 
207
    {
 
208
      do
 
209
      {
 
210
        sprintf(c,"_%.2d.%s",seq,ext);
 
211
        seq++;
 
212
      }
 
213
      while (g_file_test (filename,G_FILE_TEST_EXISTS));
 
214
    }
 
215
 
 
216
  } // end of critical block
 
217
  dt_pthread_mutex_unlock(&darktable.plugin_threadsafe);
 
218
  if(fail) return 1;
 
219
 
 
220
  /* export image to file */
 
221
  dt_imageio_export(img, filename, format, fdata);
 
222
  dt_image_cache_release(img, 'r');
 
223
 
 
224
  printf("[export_job] exported to `%s'\n", filename);
 
225
  char *trunc = filename + strlen(filename) - 32;
 
226
  if(trunc < filename) trunc = filename;
 
227
  dt_control_log(_("%d/%d exported to `%s%s'"), num, total, trunc != filename ? ".." : "", trunc);
 
228
  return 0;
 
229
}
 
230
 
 
231
void*
 
232
get_params(dt_imageio_module_storage_t *self, int* size)
 
233
{
 
234
  dt_imageio_disk_t *d = (dt_imageio_disk_t *)malloc(sizeof(dt_imageio_disk_t));
 
235
  memset(d, 0, sizeof(dt_imageio_disk_t));
 
236
  // have to return the size of the struct to store (i.e. without all the variable pointers at the end)
 
237
  *size = sizeof(dt_imageio_disk_t) - sizeof(void *);
 
238
  disk_t *g = (disk_t *)self->gui_data;
 
239
  d->vp = NULL;
 
240
  dt_variables_params_init(&d->vp);
 
241
  const char *text = gtk_entry_get_text(GTK_ENTRY(g->entry));
 
242
  strncpy(d->filename, text, 1024);
 
243
  dt_conf_set_string("plugins/imageio/storage/disk/file_directory", d->filename);
 
244
  return d;
 
245
}
 
246
 
 
247
void
 
248
free_params(dt_imageio_module_storage_t *self, void *params)
 
249
{
 
250
  dt_imageio_disk_t *d = (dt_imageio_disk_t *)params;
 
251
  dt_variables_params_destroy(d->vp);
 
252
  free(params);
 
253
}
 
254
 
 
255
int
 
256
set_params(dt_imageio_module_storage_t *self, void *params, int size)
 
257
{
 
258
  if(size != sizeof(dt_imageio_disk_t) - sizeof(void *)) return 1;
 
259
  dt_imageio_disk_t *d = (dt_imageio_disk_t *)params;
 
260
  disk_t *g = (disk_t *)self->gui_data;
 
261
  gtk_entry_set_text(GTK_ENTRY(g->entry), d->filename);
 
262
  dt_conf_set_string("plugins/imageio/storage/disk/file_directory", d->filename);
 
263
  return 0;
 
264
}