Diff of /trunk/src/undo.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 234 by harbaum, Mon Jul 20 20:15:10 2009 UTC revision 235 by harbaum, Tue Jul 21 14:31:16 2009 UTC
# Line 37  char *undo_type_string(type_t type) { Line 37  char *undo_type_string(type_t type) {
37  }  }
38    
39  static void undo_object_free(object_t *obj) {  static void undo_object_free(object_t *obj) {
   char *msg = osm_object_string(obj);  
   printf("   object %s\n", msg);  
   g_free(msg);  
   
40    if(obj->ptr) {    if(obj->ptr) {
41        char *msg = osm_object_string(obj);
42        printf("   object %s\n", msg);
43        g_free(msg);
44      } else
45        printf("   object %s\n", osm_object_type_string(obj));
46    
47      if(obj->ptr) {
48    
49      switch(obj->type) {      switch(obj->type) {
50      case NODE:      case NODE:
51        osm_node_free(NULL, obj->node);        osm_node_free(NULL, obj->node);
# Line 71  static void undo_op_free(undo_op_t *op) Line 75  static void undo_op_free(undo_op_t *op)
75  static void undo_state_free(undo_state_t *state) {  static void undo_state_free(undo_state_t *state) {
76    printf(" state: %s\n", undo_type_string(state->type));    printf(" state: %s\n", undo_type_string(state->type));
77    
78      if(state->object)
79        undo_object_free(state->object);
80    
81    undo_op_t *op = state->op;    undo_op_t *op = state->op;
82    while(op) {    while(op) {
83      undo_op_t *next = op->next;      undo_op_t *next = op->next;
# Line 176  static object_t *undo_object_copy(object Line 183  static object_t *undo_object_copy(object
183    return NULL;    return NULL;
184  }  }
185    
186  void undo_remember_delete(appdata_t *appdata, object_t *object) {  void undo_append_object(appdata_t *appdata, undo_type_t type,
187                            object_t *object) {
188    
189    /* don't do anything if undo isn't enabled */    /* don't do anything if undo isn't enabled */
190    if(!appdata->menu_item_map_undo)    if(!appdata->menu_item_map_undo)
191      return;      return;
192    
193    printf("UNDO: remembering delete operation for %s\n",    g_assert(appdata->undo.open);
          osm_object_type_string(object));  
194    
195    /* create a new undo state */    printf("UNDO: saving %s operation for %s\n",
196    undo_state_t *state = undo_append_state(appdata);           undo_type_string(type),
197    state->type = UNDO_DELETE;           osm_object_type_string(object));
198    
199    /* a simple stand-alone node deletion is just a single */    /* a simple stand-alone node deletion is just a single */
200    /* operation on the database/map so only one undo_op is saved */    /* operation on the database/map so only one undo_op is saved */
201    undo_op_t *op = state->op = g_new0(undo_op_t, 1);  
202    op->type = UNDO_DELETE;    /* append new undo operation */
203    op->object = undo_object_copy(object);    undo_op_t **op = &(appdata->undo.open->op);
204      while(*op) op = &(*op)->next;
205    
206      *op = g_new0(undo_op_t, 1);
207      (*op)->type = type;
208      (*op)->object = undo_object_copy(object);
209    }
210    
211    void undo_append_way(appdata_t *appdata, undo_type_t type, way_t *way) {
212      object_t obj;
213      obj.type = WAY;
214      obj.way = way;
215    
216      undo_append_object(appdata, type, &obj);
217    }
218    
219    void undo_open_new_state(struct appdata_s *appdata, undo_type_t type,
220                             object_t *object) {
221      g_assert(!appdata->undo.open);
222    
223      printf("UNDO: open new state for %s\n",
224             osm_object_string(object));
225    
226      /* don't do anything if undo isn't enabled */
227      if(!appdata->menu_item_map_undo)
228        return;
229    
230      /* create a new undo state */
231      appdata->undo.open = undo_append_state(appdata);
232      appdata->undo.open->type = type;
233    
234      appdata->undo.open->object = undo_object_copy(object);
235    }
236    
237    void undo_close_state(appdata_t *appdata) {
238      g_assert(appdata->undo.open);
239    
240      printf("UNDO: closing state\n");
241    
242      appdata->undo.open = NULL;
243  }  }
244    
245    
246    /* --------------------- restoring ---------------------- */
247    
248  /* undo the deletion of an object */  /* undo the deletion of an object */
249  static void undo_operation_object_delete(appdata_t *appdata, object_t *obj) {  static void undo_operation_object_delete(appdata_t *appdata, object_t *obj) {
250    
# Line 222  static void undo_operation_object_delete Line 271  static void undo_operation_object_delete
271      obj->ptr = NULL;      obj->ptr = NULL;
272    } break;    } break;
273    
274      case WAY: {
275        way_t *orig = osm_get_way_by_id(appdata->osm, obj->way->id);
276        g_assert(orig);
277        g_assert(orig->flags & OSM_FLAG_DELETED);
278      } break;
279    
280    default:    default:
281      printf("Unsupported object type\n");      printf("Unsupported object type\n");
282        g_assert(0);
283      break;      break;
284    }    }
285  }  }
# Line 263  void undo(appdata_t *appdata) { Line 319  void undo(appdata_t *appdata) {
319    /* since the operations list was built by prepending new */    /* since the operations list was built by prepending new */
320    /* entries, just going through the list will run the operations */    /* entries, just going through the list will run the operations */
321    /* in reverse order. That's exactly what we want! */    /* in reverse order. That's exactly what we want! */
   
322    undo_op_t *op = state->op;    undo_op_t *op = state->op;
323    while(op) {    while(op) {
324      undo_operation(appdata, op);      undo_operation(appdata, op);

Legend:
Removed from v.234  
changed lines
  Added in v.235