|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id$" 00003 // 00004 // FLUID undo support for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 #include <FL/Fl.H> 00029 #include "Fl_Type.h" 00030 #include "undo.h" 00031 #include <FL/Fl_Preferences.H> 00032 #include <FL/filename.H> 00033 #include "../src/flstring.h" 00034 #if defined(WIN32) && !defined(__CYGWIN__) 00035 # include <io.h> 00036 # include <windows.h> 00037 # define getpid (int)GetCurrentProcessId 00038 # ifndef __WATCOMC__ 00039 // Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs 00040 // on Windows, which is supposed to be POSIX compliant... 00041 # define unlink _unlink 00042 # endif // !__WATCOMC__ 00043 #else 00044 # include <unistd.h> 00045 #endif // WIN32 && !__CYGWIN__ 00046 00047 00048 extern Fl_Preferences fluid_prefs; // FLUID preferences 00049 extern Fl_Menu_Item Main_Menu[]; // Main menu 00050 00051 #define UNDO_ITEM 25 // Undo menu item index 00052 #define REDO_ITEM 26 // Redo menu item index 00053 00054 00055 // 00056 // This file implements an undo system using temporary files; ideally 00057 // we'd like to do this in memory, however the current data structures 00058 // and design aren't well-suited... Instead, we save and restore 00059 // checkpoint files. 00060 // 00061 00062 00063 int undo_current = 0; // Current undo level in buffer 00064 int undo_last = 0; // Last undo level in buffer 00065 int undo_max = 0; // Maximum undo level used 00066 int undo_save = -1; // Last undo level that was saved 00067 static int undo_paused = 0; // Undo checkpointing paused? 00068 00069 00070 // Return the undo filename 00071 static char *undo_filename(int level, char *buf, int bufsize) { 00072 static char undo_path[FL_PATH_MAX] = ""; // Undo path 00073 00074 00075 if (!undo_path[0]) fluid_prefs.getUserdataPath(undo_path, sizeof(undo_path)); 00076 00077 snprintf(buf, bufsize, "%sundo_%d_%d.fl", undo_path, getpid(), level); 00078 return buf; 00079 } 00080 00081 00082 // Redo menu callback 00083 void redo_cb(Fl_Widget *, void *) { 00084 char filename[FL_PATH_MAX]; // Undo checkpoint file 00085 00086 if (undo_current >= undo_last) return; 00087 00088 undo_suspend(); 00089 if (!read_file(undo_filename(undo_current + 1, filename, sizeof(filename)), 0)) { 00090 // Unable to read checkpoint file, don't redo... 00091 undo_resume(); 00092 return; 00093 } 00094 00095 undo_current ++; 00096 00097 // Update modified flag... 00098 set_modflag(undo_current != undo_save); 00099 00100 // Update undo/redo menu items... 00101 if (undo_current >= undo_last) Main_Menu[REDO_ITEM].deactivate(); 00102 Main_Menu[UNDO_ITEM].activate(); 00103 } 00104 00105 // Undo menu callback 00106 void undo_cb(Fl_Widget *, void *) { 00107 char filename[FL_PATH_MAX]; // Undo checkpoint file 00108 00109 if (undo_current <= 0) return; 00110 00111 if (undo_current == undo_last) { 00112 write_file(undo_filename(undo_current, filename, sizeof(filename))); 00113 } 00114 00115 undo_suspend(); 00116 if (!read_file(undo_filename(undo_current - 1, filename, sizeof(filename)), 0)) { 00117 // Unable to read checkpoint file, don't undo... 00118 undo_resume(); 00119 return; 00120 } 00121 00122 undo_current --; 00123 00124 // Update modified flag... 00125 set_modflag(undo_current != undo_save); 00126 00127 // Update undo/redo menu items... 00128 if (undo_current <= 0) Main_Menu[UNDO_ITEM].deactivate(); 00129 Main_Menu[REDO_ITEM].activate(); 00130 undo_resume(); 00131 } 00132 00133 // Save current file to undo buffer 00134 void undo_checkpoint() { 00135 char filename[FL_PATH_MAX]; // Undo checkpoint filename 00136 00137 // printf("undo_checkpoint(): undo_current=%d, undo_paused=%d, modflag=%d\n", 00138 // undo_current, undo_paused, modflag); 00139 00140 // Don't checkpoint if undo_suspend() has been called... 00141 if (undo_paused) return; 00142 00143 // Save the current UI to a checkpoint file... 00144 if (!write_file(undo_filename(undo_current, filename, sizeof(filename)))) { 00145 // Don't attempt to do undo stuff if we can't write a checkpoint file... 00146 perror(filename); 00147 return; 00148 } 00149 00150 // Update the saved level... 00151 if (modflag && undo_current <= undo_save) undo_save = -1; 00152 else if (!modflag) undo_save = undo_current; 00153 00154 // Update the current undo level... 00155 undo_current ++; 00156 undo_last = undo_current; 00157 if (undo_current > undo_max) undo_max = undo_current; 00158 00159 // Enable the Undo and disable the Redo menu items... 00160 Main_Menu[UNDO_ITEM].activate(); 00161 Main_Menu[REDO_ITEM].deactivate(); 00162 } 00163 00164 // Clear undo buffer 00165 void undo_clear() { 00166 char filename[FL_PATH_MAX]; // Undo checkpoint filename 00167 00168 00169 // Remove old checkpoint files... 00170 for (int i = 0; i <= undo_max; i ++) { 00171 unlink(undo_filename(i, filename, sizeof(filename))); 00172 } 00173 00174 // Reset current, last, and save indices... 00175 undo_current = undo_last = undo_max = 0; 00176 if (modflag) undo_save = -1; 00177 else undo_save = 0; 00178 } 00179 00180 // Resume undo checkpoints 00181 void undo_resume() { 00182 undo_paused = 0; 00183 } 00184 00185 // Suspend undo checkpoints 00186 void undo_suspend() { 00187 undo_paused = 1; 00188 } 00189 00190 00191 // 00192 // End of "$Id$". 00193 //