Browse Source

Allow Undo to go beyond the last block in the journal.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
4235e0ee05
3 changed files with 77 additions and 79 deletions
  1. +62
    -77
      Timeline/Loggable.C
  2. +7
    -2
      Timeline/Loggable.H
  3. +8
    -0
      Timeline/Sequence_Widget.H

+ 62
- 77
Timeline/Loggable.C View File

@@ -38,7 +38,8 @@ using std::max;
FILE *Loggable::_fp;
int Loggable::_log_id = 0;
int Loggable::_level = 0;
int Loggable::_undo_index = 1;

off_t Loggable::_undo_offset = 0;

size_t Loggable::_loggables_size = 0;
Loggable ** Loggable::_loggables;
@@ -82,6 +83,7 @@ Loggable::open ( const char *filename )
}

fseek( fp, 0, SEEK_END );
_undo_offset = ftell( fp );

Loggable::_fp = fp;

@@ -236,6 +238,8 @@ Loggable::do_this ( const char *s, bool reverse )
sscanf( s, "%s %*X %s%*[^\n<]<< %a[^\n]", classname, command, &arguments );
create = "destroy";
destroy = "create";

DMESSAGE( "undoing \"%s\"", s );
}
else
{
@@ -286,104 +290,85 @@ Loggable::do_this ( const char *s, bool reverse )
return true;
}

/** Reverse the last journal transaction */
void
Loggable::undo ( void )
{
char *buf = new char[ BUFSIZ ];

// fflush( _fp );

/* FIXME: handle more than the first block!!! */

fseek( _fp, 0, SEEK_END );
size_t len = ftell( _fp );

fseek( _fp, 0 - (BUFSIZ > len ? len : BUFSIZ), SEEK_END );

len = fread( buf, 1, BUFSIZ, _fp );
static int
backwards_fgetc ( FILE *fp )
{
int c;

char *s = buf + len - 1;
if ( fseek( fp, -1, SEEK_CUR ) != 0 )
return -1;

int i = 1;
c = fgetc( fp );

/* move back _undo_index items from the end */
for ( int j = _undo_index; j-- ; )
for ( --s; *s && s >= buf; --s, ++i )
{
if ( *s == '\n' )
{
if ( *(s + 1) == '\t' )
continue;
fseek( fp, -1, SEEK_CUR );

if ( *(s + 1) == '}' )
{
*(s + 1) = NULL;
continue;
}
return c;
}

break;
}
}
s++;
static char *
backwards_fgets ( char *s, int size, FILE *fp )
{
if ( fseek( fp, -1, SEEK_CUR ) != 0 )
return NULL;

buf[ len ] = NULL;
int c;
while ( ( c = backwards_fgetc( fp ) ) >= 0 )
if ( '\n' == c )
break;

if ( ! strlen( s ) )
{
WARNING( "corrupt undo file or no undo entries." );
return;
}
long here = ftell( fp );

char *b = s;
fseek( fp, 1, SEEK_CUR );

s += strlen( s ) - 1;
char *r = fgets( s, size, fp );

if ( strtok( b, "\n" ) == NULL )
FATAL( "empty undo transaction!\n" );
fseek( fp, here, SEEK_SET );

int n = 1;
while ( strtok( NULL, "\n" ) )
++n;
return r;
}

int ui = _undo_index;
/** Reverse the last journal transaction */
void
Loggable::undo ( void )
{
const int bufsiz = 1024;
char buf[bufsiz];

block_start();

if ( strcmp( b, "{" ) )
{
/* It's a single undo, get rid of trailing messages in this block */
long here = ftell( _fp );

n = 1;
fseek( _fp, _undo_offset, SEEK_SET );

s = b + 2;
s += strlen( s ) - 1;
}
backwards_fgets( buf, bufsiz, _fp );

while ( n-- )
if ( ! strcmp( buf, "}\n" ) )
{
while ( s >= b && *(--s) );

s++;

if ( ! strcmp( s, "{" ) )
break;
DMESSAGE( "undoing block" );
for ( ;; )
{
backwards_fgets( buf, bufsiz, _fp );

if ( *s == '\t' )
s++;
char *s = buf;
if ( *s != '\t' )
break;
else
++s;

DMESSAGE( "undoing \"%s\"", s );
do_this( s, true );
}
}
else
do_this( buf, true );

do_this( s, true );
off_t uo = ftell( _fp );

s -= 2;
}
ASSERT( _undo_offset <= here, "WTF?" );

block_end();

_undo_index = ui + 2;

delete[] buf;
_undo_offset = uo;
}

void
@@ -463,7 +448,8 @@ Loggable::compact ( void )
if ( ! snapshot( _fp ) )
FATAL( "Could not write snapshot!" );

_undo_index = 1;
fseek( _fp, 0, SEEK_END );
// _undo_index = 1;
}

/** Buffered sprintf wrapper */
@@ -512,10 +498,6 @@ Loggable::flush ( void )

int n = _transaction.size();

if ( n )
/* something done, reset undo index */
_undo_index = 1;

if ( n > 1 )
fprintf( _fp, "{\n" );

@@ -536,6 +518,9 @@ Loggable::flush ( void )
if ( n > 1 )
fprintf( _fp, "}\n" );

if ( n )
/* something done, reset undo index */
_undo_offset = ftell( _fp );

fflush( _fp );
}


+ 7
- 2
Timeline/Loggable.H View File

@@ -68,7 +68,10 @@ class Loggable
static FILE *_fp;
static int _log_id;
static int _level;
static int _undo_index;

/* static int _undo_index; */

static off_t _undo_offset;

static size_t _loggables_size;
static Loggable ** _loggables;
@@ -148,7 +151,9 @@ public:
static bool open ( const char *filename );
static bool close ( void );
static void undo ( void );
static int undo_index ( void ) { return _undo_index; }

/* static int undo_index ( void ) { return _undo_index; } */

static void compact ( void );

static


+ 8
- 0
Timeline/Sequence_Widget.H View File

@@ -220,18 +220,26 @@ public:
static void
delete_selected ( void )
{
Loggable::block_start();

while ( _selection.size() )
delete _selection.front();

Loggable::block_end();
}

static void
select_none ( void )
{
Loggable::block_start();

while ( _selection.size() )
{
_selection.front()->redraw();
_selection.pop_front();
}

Loggable::block_end();
}

static Sequence_Widget *current ( void ) { return Sequence_Widget::_current; }


Loading…
Cancel
Save