diff --git a/misc/org.yorba.shotwell.gschema.xml b/misc/org.yorba.shotwell.gschema.xml
index 42b9ac3..e55fce3 100644
--- a/misc/org.yorba.shotwell.gschema.xml
+++ b/misc/org.yorba.shotwell.gschema.xml
@@ -221,6 +221,12 @@
         <description>If true, Shotwell will convert all filenames to lowercase when importing photo files</description>
     </key>
 
+    <key name="enforce-directory-pattern" type="b">
+        <default>false</default>
+        <summary>always enforce the directory pattern</summary>
+        <description>If true, Shotwell will always enforce the directory pattern by moving files whenever they change.</description>
+    </key>
+
     <key name="directory-pattern" type="s">
         <default>""</default>
         <summary>directory pattern</summary>
diff --git a/src/Dialogs.vala b/src/Dialogs.vala
index e83442f..9645986 100644
--- a/src/Dialogs.vala
+++ b/src/Dialogs.vala
@@ -1820,6 +1820,7 @@ public class PreferencesDialog {
     private string? lib_dir = null;
     private Gee.ArrayList<PathFormat> path_formats = new Gee.ArrayList<PathFormat>();
     private GLib.DateTime example_date = new GLib.DateTime.local(2009, 3, 10, 18, 16, 11);
+    private Gtk.CheckButton enforce_pattern;
     private Gtk.CheckButton lowercase;
     private Gtk.Button close_button;
     private Plugins.ManifestWidgetMediator plugins_mediator = new Plugins.ManifestWidgetMediator();
@@ -1885,6 +1886,9 @@ public class PreferencesDialog {
         dir_pattern_combo.changed.connect(on_dir_pattern_combo_changed);
         dir_pattern_entry.changed.connect(on_dir_pattern_entry_changed);
         
+        enforce_pattern = builder.get_object("enforce_pattern") as Gtk.CheckButton;
+        enforce_pattern.toggled.connect(on_enforce_pattern_toggled);
+
         lowercase = builder.get_object("lowercase") as Gtk.CheckButton;
         lowercase.toggled.connect(on_lowercase_toggled);
         
@@ -1920,6 +1924,7 @@ public class PreferencesDialog {
         
         setup_dir_pattern(dir_pattern_combo, dir_pattern_entry);
         
+        enforce_pattern.set_active(Config.Facade.get_instance().get_enforce_directory_pattern());
         lowercase.set_active(Config.Facade.get_instance().get_use_lowercase_filenames());
     }
     
@@ -2207,6 +2212,10 @@ public class PreferencesDialog {
         dir_pattern_combo.append_text(name);
     }
     
+    private void on_enforce_pattern_toggled() {
+        Config.Facade.get_instance().set_enforce_directory_pattern(enforce_pattern.get_active());
+    }
+
     private void on_lowercase_toggled() {
         Config.Facade.get_instance().set_use_lowercase_filenames(lowercase.get_active());
     }
diff --git a/src/Photo.vala b/src/Photo.vala
index f54b829..fd10b10 100644
--- a/src/Photo.vala
+++ b/src/Photo.vala
@@ -4621,13 +4621,60 @@ public class LibraryPhoto : Photo, Flaggable, Monitorable {
     }
     
     protected override void notify_altered(Alteration alteration) {
-        // generate new thumbnails in the background
+        if (alteration.has_detail("metadata", "exposure-time")) {
+            move_by_directory_pattern();
+        }
         if (!block_thumbnail_generation && alteration.has_subject("image"))
+            // generate new thumbnails in the background
             thumbnail_scheduler.at_priority_idle(Priority.LOW);
         
         base.notify_altered(alteration);
     }
-    
+
+    protected void move_by_directory_pattern() {
+        File src = get_master_file();
+
+        if (!AppDirs.is_in_import_dir(src)) {
+            debug("Source file not in the import directory. Do nothing.");
+            return;
+        }
+
+        time_t timestamp = get_exposure_time();
+
+        File dest_dir = AppDirs.get_baked_import_dir(timestamp);
+        if (dest_dir.equal(src.get_parent())) {
+            debug("The file is already in the correct directory. Do nothing.");
+            return;
+        }
+
+        File? dest;
+        bool collision;
+        try {
+            // This creates a new file, which we will overwrite in our move.
+            dest = LibraryFiles.generate_unique_file(src.get_basename(), null, timestamp, out collision);
+        } catch (Error e) {
+            warning("Error from generate_unique_file: %s", e.message);
+            return;
+        }
+        if (dest == null) {
+            warning("Could not make destination path");
+            return;
+        } else if (collision) {
+            warning("Collision when creating destination path (extension added)");
+        }
+
+        LibraryMonitor.blacklist_file(dest, "Photo.move_by_directory_pattern");
+        try {
+            src.move(dest, FileCopyFlags.OVERWRITE);
+        } catch (Error e) {
+            warning("Error when moving: %s", e.message);
+            LibraryMonitor.unblacklist_file(dest);
+            return;
+        }
+        set_master_file(dest);
+        LibraryMonitor.unblacklist_file(dest);
+    }
+
     public override Gdk.Pixbuf get_preview_pixbuf(Scaling scaling) throws Error {
         Gdk.Pixbuf pixbuf = get_thumbnail(ThumbnailCache.Size.BIG);
         
diff --git a/src/config/ConfigurationInterfaces.vala b/src/config/ConfigurationInterfaces.vala
index 9bd4a31..517179c 100644
--- a/src/config/ConfigurationInterfaces.vala
+++ b/src/config/ConfigurationInterfaces.vala
@@ -35,6 +35,7 @@ public enum ConfigurableProperty {
     DISPLAY_PHOTO_RATINGS,
     DISPLAY_PHOTO_TAGS,
     DISPLAY_PHOTO_TITLES,
+    ENFORCE_DIRECTORY_PATTERN,
     EVENT_PHOTOS_SORT_ASCENDING,
     EVENT_PHOTOS_SORT_BY,
     EVENTS_SORT_ASCENDING,
@@ -124,6 +125,9 @@ public enum ConfigurableProperty {
             case DISPLAY_PHOTO_TITLES:
                 return "DISPLAY_PHOTO_TITLES";
                 
+            case ENFORCE_DIRECTORY_PATTERN:
+                return "ENFORCE_DIRECTORY_PATTERN";
+
             case EVENT_PHOTOS_SORT_ASCENDING:
                 return "EVENT_PHOTOS_SORT_ASCENDING";
                 
@@ -613,6 +617,27 @@ public abstract class ConfigurationFacade : Object {
     }
 
     //
+    // always enforce the directory pattern (move files)
+    //
+    public virtual bool get_enforce_directory_pattern() {
+        try {
+            return get_engine().get_bool_property(ConfigurableProperty.ENFORCE_DIRECTORY_PATTERN);
+        } catch (ConfigurationError err) {
+            on_configuration_error(err);
+
+            return false;
+        }
+    }
+
+    public virtual void set_enforce_directory_pattern(bool b) {
+        try {
+            get_engine().set_bool_property(ConfigurableProperty.ENFORCE_DIRECTORY_PATTERN, b);
+        } catch (ConfigurationError err) {
+            on_configuration_error(err);
+        }
+    }
+
+    //
     // event photos sort
     //
     public virtual void get_event_photos_sort(out bool sort_order, out int sort_by) {
diff --git a/ui/shotwell.glade b/ui/shotwell.glade
index 8899d1b..0ad612e 100644
--- a/ui/shotwell.glade
+++ b/ui/shotwell.glade
@@ -2,7 +2,6 @@
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-requires Shotwell 0.0 -->
-  <!-- interface-naming-policy project-wide -->
   <object class="GtkDialog" id="Search criteria">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -13,12 +12,12 @@
     <property name="type_hint">dialog</property>
     <property name="skip_taskbar_hint">True</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox6">
+      <object class="GtkBox" id="dialog-vbox6">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="search dialog buttons">
+          <object class="GtkButtonBox" id="search dialog buttons">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
@@ -64,8 +63,6 @@
                     <property name="width_chars">20</property>
                     <property name="primary_icon_activatable">False</property>
                     <property name="secondary_icon_activatable">False</property>
-                    <property name="primary_icon_sensitive">True</property>
-                    <property name="secondary_icon_sensitive">True</property>
                   </object>
                   <packing>
                     <property name="expand">True</property>
@@ -210,7 +207,7 @@
     <property name="destroy_with_parent">True</property>
     <property name="type_hint">dialog</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox5">
+      <object class="GtkBox" id="dialog-vbox5">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <child>
@@ -285,8 +282,8 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
                                 <property name="events">GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK</property>
-                                <property name="show_text">True</property>
                                 <property name="text" translatable="yes">Preparing pictures for import...</property>
+                                <property name="show_text">True</property>
                               </object>
                               <packing>
                                 <property name="expand">True</property>
@@ -360,7 +357,7 @@
           </packing>
         </child>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area5">
+          <object class="GtkButtonBox" id="dialog-action_area5">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
@@ -431,7 +428,6 @@
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="hscrollbar_policy">never</property>
-            <property name="vscrollbar_policy">automatic</property>
             <property name="shadow_type">etched-in</property>
             <child>
               <placeholder/>
@@ -482,11 +478,11 @@
     <property name="type_hint">dialog</property>
     <property name="skip_taskbar_hint">True</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox3">
+      <object class="GtkBox" id="dialog-vbox3">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area3">
+          <object class="GtkButtonBox" id="dialog-action_area3">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
@@ -528,7 +524,7 @@
                   <object class="GtkTable" id="table1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="n_rows">14</property>
+                    <property name="n_rows">15</property>
                     <property name="n_columns">2</property>
                     <property name="column_spacing">8</property>
                     <property name="row_spacing">4</property>
@@ -667,8 +663,8 @@
                       </object>
                       <packing>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">10</property>
-                        <property name="bottom_attach">11</property>
+                        <property name="top_attach">11</property>
+                        <property name="bottom_attach">12</property>
                       </packing>
                     </child>
                     <child>
@@ -690,8 +686,8 @@
                       </object>
                       <packing>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">11</property>
-                        <property name="bottom_attach">12</property>
+                        <property name="top_attach">12</property>
+                        <property name="bottom_attach">13</property>
                       </packing>
                     </child>
                     <child>
@@ -876,8 +872,6 @@
                             <property name="invisible_char">•</property>
                             <property name="primary_icon_activatable">False</property>
                             <property name="secondary_icon_activatable">False</property>
-                            <property name="primary_icon_sensitive">True</property>
-                            <property name="secondary_icon_sensitive">True</property>
                           </object>
                         </child>
                       </object>
@@ -946,8 +940,8 @@
                       </object>
                       <packing>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">9</property>
-                        <property name="bottom_attach">10</property>
+                        <property name="top_attach">10</property>
+                        <property name="bottom_attach">11</property>
                         <property name="x_options">GTK_FILL</property>
                         <property name="y_options"></property>
                       </packing>
@@ -972,8 +966,8 @@
                       </object>
                       <packing>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">12</property>
-                        <property name="bottom_attach">13</property>
+                        <property name="top_attach">13</property>
+                        <property name="bottom_attach">14</property>
                       </packing>
                     </child>
                     <child>
@@ -984,8 +978,8 @@
                       <packing>
                         <property name="left_attach">1</property>
                         <property name="right_attach">2</property>
-                        <property name="top_attach">13</property>
-                        <property name="bottom_attach">14</property>
+                        <property name="top_attach">14</property>
+                        <property name="bottom_attach">15</property>
                       </packing>
                     </child>
                     <child>
@@ -1005,8 +999,34 @@
                         </child>
                       </object>
                       <packing>
-                        <property name="top_attach">13</property>
-                        <property name="bottom_attach">14</property>
+                        <property name="top_attach">14</property>
+                        <property name="bottom_attach">15</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="checkbox: enforce pattern">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="top_padding">3</property>
+                        <property name="left_padding">10</property>
+                        <child>
+                          <object class="GtkCheckButton" id="enforce_pattern">
+                            <property name="label" translatable="yes">A_lways enforce the directory pattern</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="use_action_appearance">False</property>
+                            <property name="use_underline">True</property>
+                            <property name="draw_indicator">True</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">9</property>
+                        <property name="bottom_attach">10</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
                       </packing>
                     </child>
                   </object>
@@ -1191,13 +1211,13 @@
     <property name="destroy_with_parent">True</property>
     <property name="type_hint">dialog</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox2">
+      <object class="GtkBox" id="dialog-vbox2">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="can_default">True</property>
         <property name="has_default">True</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area2">
+          <object class="GtkButtonBox" id="dialog-action_area2">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
@@ -1268,8 +1288,6 @@
                 <property name="width_chars">30</property>
                 <property name="primary_icon_activatable">False</property>
                 <property name="secondary_icon_activatable">False</property>
-                <property name="primary_icon_sensitive">True</property>
-                <property name="secondary_icon_sensitive">True</property>
                 <signal name="changed" handler="text_entry_dialog_on_entry_changed" object="text_entry_dialog1" swapped="yes"/>
               </object>
               <packing>
