Index: src/dlg-change-date.c
===================================================================
--- src/dlg-change-date.c	(revision 1421)
+++ src/dlg-change-date.c	(working copy)
@@ -50,6 +50,7 @@
 
 	GtkWidget    *cd_last_modified_checkbutton;
 	GtkWidget    *cd_comment_checkbutton;
+	GtkWidget    *cd_exif_checkbutton;
 
 	GtkWidget    *cd_following_date_radiobutton;
 	GtkWidget    *cd_created_radiobutton;
@@ -156,6 +157,23 @@
 			comment_data_free (cdata);
 		}
 
+		if (is_active (data->cd_exif_checkbutton)) {
+			char buf[32];
+			struct tm tm;
+
+			localtime_r(&mtime, &tm);
+			snprintf(buf, 32, "%04d:%02d:%02d %02d:%02d:%02d ", 
+			       tm.tm_year + 1900,
+			       tm.tm_mon + 1,
+			       tm.tm_mday,
+			       tm.tm_hour,
+			       tm.tm_min,
+			       tm.tm_sec );
+//			set_exif_tag(fdata->path, EXIF_TAG_DATE_TIME, buf, 32);
+			patch_exif_tag(fdata->path, EXIF_TAG_DATE_TIME, buf, strlen(buf));
+			mtime++; // Step the time to enable sorting of pictures according to EXIF time
+		}
+
 		file_list = g_list_prepend (file_list, fdata->path);
 	}
 
@@ -173,7 +191,8 @@
 {
 	gtk_widget_set_sensitive (data->ok_button,
 				  gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->cd_last_modified_checkbutton))
-				  || gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->cd_comment_checkbutton)));
+				  || gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->cd_comment_checkbutton))
+				  || gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->cd_exif_checkbutton)));
 		
 	gtk_widget_set_sensitive (data->cd_dateedit, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->cd_following_date_radiobutton)));
 	gtk_widget_set_sensitive (data->cd_timezone_box, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->cd_adjust_timezone_radiobutton)));
@@ -234,6 +253,7 @@
 
 	data->cd_last_modified_checkbutton = glade_xml_get_widget (data->gui, "cd_last_modified_checkbutton");
 	data->cd_comment_checkbutton = glade_xml_get_widget (data->gui, "cd_comment_checkbutton");
+	data->cd_exif_checkbutton = glade_xml_get_widget (data->gui, "cd_exif_checkbutton");
 
 	data->cd_following_date_radiobutton = glade_xml_get_widget (data->gui, "cd_following_date_radiobutton");
 	data->cd_created_radiobutton = glade_xml_get_widget (data->gui, "cd_created_radiobutton");
@@ -285,6 +305,10 @@
 			  "clicked",
 			  G_CALLBACK (radio_button_clicked),
 			  data);
+	g_signal_connect (G_OBJECT (data->cd_exif_checkbutton), 
+			  "clicked",
+			  G_CALLBACK (radio_button_clicked),
+			  data); 
 	
 	g_signal_connect (G_OBJECT (data->cd_following_date_radiobutton), 
 			  "clicked",
Index: data/glade/gthumb_tools.glade
===================================================================
--- data/glade/gthumb_tools.glade	(revision 1421)
+++ data/glade/gthumb_tools.glade	(working copy)
@@ -2133,6 +2133,25 @@
 			  <property name="fill">False</property>
 			</packing>
 		      </child>
+
+		      <child>
+			<widget class="GtkCheckButton" id="cd_exif_checkbutton">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="label" translatable="yes">EXIF date</property>
+			  <property name="use_underline">True</property>
+			  <property name="relief">GTK_RELIEF_NORMAL</property>
+			  <property name="focus_on_click">True</property>
+			  <property name="active">False</property>
+			  <property name="inconsistent">False</property>
+			  <property name="draw_indicator">True</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
 		    </widget>
 		    <packing>
 		      <property name="padding">0</property>
Index: libgthumb/gth-exif-utils.c
===================================================================
--- libgthumb/gth-exif-utils.c	(revision 1421)
+++ libgthumb/gth-exif-utils.c	(working copy)
@@ -24,6 +24,7 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <time.h>
 #include <glib.h>
 
@@ -372,3 +373,154 @@
 	}
 }
 
+
+const char leth[]  = {0x49, 0x49, 0x2a, 0x00}; // Little endian TIFF header
+const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a}; // Big endian TIFF header
+const char types[] = {0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 0x08, 0x00, 0x04, 0x08}; // size in bytes for EXIF types
+
+#define DE_ENDIAN16(val) endian == G_BIG_ENDIAN ? GUINT16_FROM_BE(val) : GUINT16_FROM_LE(val)
+#define DE_ENDIAN32(val) endian == G_BIG_ENDIAN ? GUINT32_FROM_BE(val) : GUINT32_FROM_LE(val)
+
+#define ENDIAN16_IT(val) endian == G_BIG_ENDIAN ? GUINT16_TO_BE(val) : GUINT16_TO_LE(val)
+#define ENDIAN32_IT(val) endian == G_BIG_ENDIAN ? GUINT32_TO_BE(val) : GUINT32_TO_LE(val)
+
+#define IFD_OFFSET_PUSH(val) offsets[oi++] = val;
+#define IFD_OFFSET_PULL()    offsets[--oi]
+
+#define IFD_NAME_PUSH(val) names[ni++] = val;
+#define IFD_NAME_PULL()    names[--ni]
+
+unsigned int
+patch_exif_tag( const char *filename,
+	        ExifTag     etag,
+		const char *data,
+		int         size)
+{
+	FILE *jf;
+	char buf[1024 * 64];
+	int  i, tag, offset, tags, rest, type, count; 
+        int tiff   = 0;
+        int endian = 0;
+	int gpsifd;
+	int exififd;
+
+	unsigned int offsets[32], oi, ni;
+        char          *names[32];
+
+	printf("patch_exif_tag(%s, %04x, %s, %d)\n", filename, etag, data, size);
+
+        // Init IFD stack
+	oi = 0;
+	ni = 0;
+	IFD_OFFSET_PUSH(0);
+	IFD_NAME_PUSH("START");
+
+        // get path to file
+	if ((filename = get_file_path_from_uri (filename)) == NULL )
+		return 0;
+
+	// open file rb+ (read (r) and modify (+), b indicates binary file accces on non-Unix systems
+	if ((jf = fopen(filename, "rb+")) == NULL)
+		return 0;
+
+        // Fill buffer
+        fread(buf, 1, sizeof(buf), jf);
+
+        // Check for TIFF header and catch endianess
+	i = 0;
+	while (i < sizeof(buf)){
+
+		// Little endian TIFF header
+		if (bcmp(&buf[i], leth, 4) == 0){ 
+		   endian = G_LITTLE_ENDIAN;
+                }
+
+		// Big endian TIFF header
+		else if (bcmp(&buf[i], beth, 4) == 0){ 
+                   endian = G_BIG_ENDIAN;
+                }
+
+		// Keep looking through buffer
+		else {
+                   i++;
+		   continue;
+		}
+		break;
+        }
+
+	// We have found either big or little endian TIFF header
+ 	tiff    = i;
+
+        // Endian some tag values that we will look for
+	exififd = ENDIAN16_IT(0x8769);
+	gpsifd  = ENDIAN16_IT(0x8825);
+        tag     = ENDIAN16_IT(etag);
+
+        // Read out the offset
+        offset  = DE_ENDIAN32(*((unsigned long*)(&buf[i] + 4)));
+	i       = i + offset;
+
+        // Start out with IFD0 (and add more IFDs while we go)
+	IFD_OFFSET_PUSH(i);
+	IFD_NAME_PUSH("IFD0");
+
+        // As long as we find more IFDs check out the tags in each
+	while ((i = IFD_OFFSET_PULL()) != 0){
+	  
+	  printf("%s:\n", IFD_NAME_PULL());
+	  tags    = DE_ENDIAN16(*((unsigned short*)(&buf[i])));
+	  i       = i + 2;
+
+ 	  // Check this IFD for tags of interest
+	  while (tags-- && i < sizeof(buf) - 12 ){
+	        type   = DE_ENDIAN16(*((unsigned short*)(&buf[i + 2])));
+		count  = DE_ENDIAN32(*((unsigned long*) (&buf[i + 4])));
+  	        offset = DE_ENDIAN32(*((unsigned long*) (&buf[i + 8])));
+
+		printf("TAG: %04x type:%d count:%d offset:%04lx\n", 
+			DE_ENDIAN16(*((unsigned short*)(&buf[i]))), type, count, offset);
+
+		// Our tag?
+		if (bcmp(&buf[i], (char *)&tag, 2) == 0){ 
+
+		   // Local value that can be patched directly in TAG table 
+		   if ((types[type] * count) <= 4){
+		       *((unsigned long*)(&buf[i + 8])) = ENDIAN32_IT(*data);
+                   }
+		   // Offseted value of same or larger size that we can patch
+		   else if (types[type] * count >= size){
+		       memcpy((char *)(buf + tiff + offset), data, size);
+		   }
+		   // Otherwise we are not able to patch the new value, at least not here
+		   else {
+		       fprintf(stderr, "patch_exif_tag: New TAG value does not fit, no patch applied\n");
+		       continue;
+                   }
+                }
+		// EXIF pointer tag?
+		else if (bcmp(&buf[i], (char *)&exififd, 2) == 0){ 
+	      	    IFD_OFFSET_PUSH(offset + tiff);
+		    IFD_NAME_PUSH("EXIF");
+		}
+		// GPS pointer tag?
+		else if (bcmp(&buf[i], (char *)&gpsifd, 2) == 0){ 
+	      	    IFD_OFFSET_PUSH(offset + tiff);
+		    IFD_NAME_PUSH("GPS");
+		}
+                i += 12;
+          }
+	  // Check for a valid next pointer and assume that to be IFD1
+	  if ((i = DE_ENDIAN32((*((unsigned long*) (&buf[i]))))) != 0){ 
+		int j;
+		i = i + tiff;
+		IFD_OFFSET_PUSH(i);
+		IFD_NAME_PUSH("IFD1");
+
+          }
+        }
+
+        // Save changes
+	rewind(jf);
+	fwrite(buf, 1, sizeof(buf), jf);
+	fclose(jf);
+}
