| 
							- //
 - // "$Id$"
 - //
 - // FLUID undo support for the Fast Light Tool Kit (FLTK).
 - //
 - // Copyright 1998-2010 by Bill Spitzak and others.
 - //
 - // This library is free software; you can redistribute it and/or
 - // modify it under the terms of the GNU Library General Public
 - // License as published by the Free Software Foundation; either
 - // version 2 of the License, or (at your option) any later version.
 - //
 - // This library is distributed in the hope that it will be useful,
 - // but WITHOUT ANY WARRANTY; without even the implied warranty of
 - // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - // Library General Public License for more details.
 - //
 - // You should have received a copy of the GNU Library General Public
 - // License along with this library; if not, write to the Free Software
 - // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 - // USA.
 - //
 - // Please report all bugs and problems on the following page:
 - //
 - //     http://www.fltk.org/str.php
 - //
 - 
 - #include <FL/Fl.H>
 - #include "Fl_Type.h"
 - #include "undo.h"
 - #include <FL/Fl_Preferences.H>
 - #include <FL/filename.H>
 - #include "../src/flstring.h"
 - #if defined(WIN32) && !defined(__CYGWIN__)
 - #  include <io.h>
 - #  include <windows.h>
 - #  define getpid (int)GetCurrentProcessId
 - #  ifndef __WATCOMC__
 - // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
 - // on Windows, which is supposed to be POSIX compliant...
 - #    define unlink _unlink
 - #  endif // !__WATCOMC__
 - #else
 - #  include <unistd.h>
 - #endif // WIN32 && !__CYGWIN__
 - 
 - 
 - extern Fl_Preferences	fluid_prefs;	// FLUID preferences
 - extern Fl_Menu_Item	Main_Menu[];	// Main menu
 - 
 - #define UNDO_ITEM	25		// Undo menu item index
 - #define REDO_ITEM	26		// Redo menu item index
 - 
 - 
 - //
 - // This file implements an undo system using temporary files; ideally
 - // we'd like to do this in memory, however the current data structures
 - // and design aren't well-suited...  Instead, we save and restore
 - // checkpoint files.
 - //
 - 
 - 
 - int undo_current = 0;			// Current undo level in buffer
 - int undo_last = 0;			// Last undo level in buffer
 - int undo_max = 0;			// Maximum undo level used
 - int undo_save = -1;			// Last undo level that was saved
 - static int undo_paused = 0;		// Undo checkpointing paused?
 - 
 - 
 - // Return the undo filename
 - static char *undo_filename(int level, char *buf, int bufsize) {
 -   static char	undo_path[FL_PATH_MAX] = "";	// Undo path
 - 
 - 
 -   if (!undo_path[0]) fluid_prefs.getUserdataPath(undo_path, sizeof(undo_path));
 - 
 -   snprintf(buf, bufsize, "%sundo_%d_%d.fl", undo_path, getpid(), level);
 -   return buf;
 - }
 - 
 - 
 - // Redo menu callback
 - void redo_cb(Fl_Widget *, void *) {
 -   char	filename[FL_PATH_MAX];			// Undo checkpoint file
 - 
 -   if (undo_current >= undo_last) return;
 - 
 -   undo_suspend();
 -   if (!read_file(undo_filename(undo_current + 1, filename, sizeof(filename)), 0)) {
 -     // Unable to read checkpoint file, don't redo...
 -     undo_resume();
 -     return;
 -   }
 - 
 -   undo_current ++;
 - 
 -   // Update modified flag...
 -   set_modflag(undo_current != undo_save);
 - 
 -   // Update undo/redo menu items...
 -   if (undo_current >= undo_last) Main_Menu[REDO_ITEM].deactivate();
 -   Main_Menu[UNDO_ITEM].activate();
 - }
 - 
 - // Undo menu callback
 - void undo_cb(Fl_Widget *, void *) {
 -   char	filename[FL_PATH_MAX];			// Undo checkpoint file
 - 
 -   if (undo_current <= 0) return;
 - 
 -   if (undo_current == undo_last) {
 -     write_file(undo_filename(undo_current, filename, sizeof(filename)));
 -   }
 - 
 -   undo_suspend();
 -   if (!read_file(undo_filename(undo_current - 1, filename, sizeof(filename)), 0)) {
 -     // Unable to read checkpoint file, don't undo...
 -     undo_resume();
 -     return;
 -   }
 - 
 -   undo_current --;
 - 
 -   // Update modified flag...
 -   set_modflag(undo_current != undo_save);
 - 
 -   // Update undo/redo menu items...
 -   if (undo_current <= 0) Main_Menu[UNDO_ITEM].deactivate();
 -   Main_Menu[REDO_ITEM].activate();
 -   undo_resume();
 - }
 - 
 - // Save current file to undo buffer
 - void undo_checkpoint() {
 -   char	filename[FL_PATH_MAX];			// Undo checkpoint filename
 - 
 - //  printf("undo_checkpoint(): undo_current=%d, undo_paused=%d, modflag=%d\n",
 - //         undo_current, undo_paused, modflag);
 - 
 -   // Don't checkpoint if undo_suspend() has been called...
 -   if (undo_paused) return;
 - 
 -   // Save the current UI to a checkpoint file...
 -   if (!write_file(undo_filename(undo_current, filename, sizeof(filename)))) {
 -     // Don't attempt to do undo stuff if we can't write a checkpoint file...
 -     perror(filename);
 -     return;
 -   }
 - 
 -   // Update the saved level...
 -   if (modflag && undo_current <= undo_save) undo_save = -1;
 -   else if (!modflag) undo_save = undo_current;
 - 
 -   // Update the current undo level...
 -   undo_current ++;
 -   undo_last = undo_current;
 -   if (undo_current > undo_max) undo_max = undo_current;
 - 
 -   // Enable the Undo and disable the Redo menu items...
 -   Main_Menu[UNDO_ITEM].activate();
 -   Main_Menu[REDO_ITEM].deactivate();
 - }
 - 
 - // Clear undo buffer
 - void undo_clear() {
 -   char	filename[FL_PATH_MAX];			// Undo checkpoint filename
 - 
 - 
 -   // Remove old checkpoint files...
 -   for (int i = 0; i <= undo_max; i ++) {
 -     unlink(undo_filename(i, filename, sizeof(filename)));
 -   }
 - 
 -   // Reset current, last, and save indices...
 -   undo_current = undo_last = undo_max = 0;
 -   if (modflag) undo_save = -1;
 -   else undo_save = 0;
 - }
 - 
 - // Resume undo checkpoints
 - void undo_resume() {
 -   undo_paused = 0;
 - }
 - 
 - // Suspend undo checkpoints
 - void undo_suspend() {
 -   undo_paused = 1;
 - }
 - 
 - 
 - //
 - // End of "$Id$".
 - //
 
 
  |