| @@ -31,6 +31,8 @@ | |||
| using std::min; | |||
| using std::max; | |||
| #include <FL/Fl.H> // for Fl::check() | |||
| FILE *Loggable::_fp; | |||
| @@ -43,6 +45,9 @@ Loggable ** Loggable::_loggables; | |||
| std::map <std::string, create_func*> Loggable::_class_map; | |||
| std::queue <char *> Loggable::_transaction; | |||
| progress_func *Loggable::_progress_callback = NULL; | |||
| void *Loggable::_progress_callback_arg = NULL; | |||
| /** Open the journal /filename/ and replay it, bringing the end state back into RAM */ | |||
| @@ -83,6 +88,9 @@ Loggable::open ( const char *filename ) | |||
| return true; | |||
| } | |||
| #include <sys/stat.h> | |||
| #include <unistd.h> | |||
| /** replay journal or snapshot */ | |||
| bool | |||
| Loggable::replay ( FILE *fp ) | |||
| @@ -90,6 +98,12 @@ Loggable::replay ( FILE *fp ) | |||
| /* FIXME: bogus */ | |||
| char buf[BUFSIZ]; | |||
| struct stat st; | |||
| fstat( fileno( fp ), &st ); | |||
| off_t total = st.st_size; | |||
| off_t current = 0; | |||
| while ( fscanf( fp, "%[^\n]\n", buf ) == 1 ) | |||
| { | |||
| if ( ! ( ! strcmp( buf, "{" ) || ! strcmp( buf, "}" ) ) ) | |||
| @@ -99,7 +113,14 @@ Loggable::replay ( FILE *fp ) | |||
| else | |||
| do_this( buf, false ); | |||
| } | |||
| current = ftell( fp ); | |||
| if ( _progress_callback ) | |||
| _progress_callback( current * 100 / total, _progress_callback_arg ); | |||
| } | |||
| return true; | |||
| } | |||
| /** close journal and delete all loggable objects, returing the systemt to a blank slate */ | |||
| @@ -360,21 +381,9 @@ Loggable::undo ( void ) | |||
| delete[] buf; | |||
| } | |||
| /* FIXME: we need a version of this that is fully const, right? */ | |||
| /** write a snapshot of the state of all loggable objects, sufficient | |||
| * for later reconstruction, to /fp/ */ | |||
| bool | |||
| Loggable::snapshot ( FILE *fp ) | |||
| void | |||
| Loggable::compact_ids ( void ) | |||
| { | |||
| FILE *ofp = _fp; | |||
| if ( ! ( _fp = fp ) ) | |||
| { | |||
| _fp = ofp; | |||
| return false; | |||
| } | |||
| /* first, make all ids consecutive */ | |||
| int id = 0; | |||
| for ( int i = 0; i < _log_id; ++i ) | |||
| if ( _loggables[ i ] ) | |||
| @@ -390,6 +399,21 @@ Loggable::snapshot ( FILE *fp ) | |||
| } | |||
| _log_id = id; | |||
| } | |||
| /* FIXME: we need a version of this that is fully const, right? */ | |||
| /** write a snapshot of the state of all loggable objects, sufficient | |||
| * for later reconstruction, to /fp/ */ | |||
| bool | |||
| Loggable::snapshot ( FILE *fp ) | |||
| { | |||
| FILE *ofp = _fp; | |||
| if ( ! ( _fp = fp ) ) | |||
| { | |||
| _fp = ofp; | |||
| return false; | |||
| } | |||
| block_start(); | |||
| @@ -419,6 +443,8 @@ Loggable::snapshot ( const char *name ) | |||
| snapshot( fp ); | |||
| fclose( fp ); | |||
| return true; | |||
| } | |||
| /** Replace the journal with a snapshot of the current state */ | |||
| @@ -428,7 +454,9 @@ Loggable::compact ( void ) | |||
| fseek( _fp, 0, SEEK_SET ); | |||
| ftruncate( fileno( _fp ), 0 ); | |||
| snapshot( _fp ); | |||
| compact_ids(); | |||
| if ( ! snapshot( _fp ) ) | |||
| FATAL( "Could not write snapshot!" ); | |||
| _undo_index = 1; | |||
| } | |||
| @@ -35,6 +35,8 @@ | |||
| #include "util/debug.h" | |||
| typedef void (progress_func)( int, void * ); | |||
| class Log_Entry; | |||
| class Loggable; | |||
| typedef Loggable *(create_func)(Log_Entry &); | |||
| @@ -75,6 +77,9 @@ class Loggable | |||
| static std::queue <char *> _transaction; | |||
| static progress_func *_progress_callback; | |||
| static void *_progress_callback_arg; | |||
| private: | |||
| int _id; | |||
| @@ -131,8 +136,11 @@ private: | |||
| /* not implemented */ | |||
| const Loggable & operator= ( const Loggable &rhs ); | |||
| static void compact_ids ( void ); | |||
| public: | |||
| static void progress_callback ( progress_func *p, void *arg ) { _progress_callback = p; _progress_callback_arg = arg;} | |||
| static const char *escape ( const char *s ); | |||
| int id ( void ) const { return _id; } | |||
| @@ -152,14 +152,13 @@ asprintf( &path, "%s/options", user_config_dir ); | |||
| free( path ); | |||
| menubar->add( "&Timeline", 0, 0, const_cast< Fl_Menu_Item *>( timeline->menu->menu() ), FL_SUBMENU_POINTER );} {selected | |||
| } | |||
| menubar->add( "&Timeline", 0, 0, const_cast< Fl_Menu_Item *>( timeline->menu->menu() ), FL_SUBMENU_POINTER );} {} | |||
| } | |||
| Function {make_window()} {open | |||
| } { | |||
| Fl_Window main_window { | |||
| label Timeline open | |||
| xywh {225 89 1020 765} type Double resizable xclass Non_DAW visible | |||
| xywh {500 26 1020 765} type Double resizable xclass Non_DAW visible | |||
| } { | |||
| Fl_Menu_Bar menubar {open | |||
| xywh {0 0 1024 25} | |||
| @@ -192,6 +191,10 @@ main_window->redraw();} | |||
| if ( ! name ) | |||
| return; | |||
| progress->show(); | |||
| timeline->hide(); | |||
| Loggable::progress_callback( progress_cb, this ); | |||
| if ( ! Project::validate( name ) ) | |||
| { | |||
| fl_alert( "The path \\"%s\\"\\ndoes not refer to a valid Non-DAW project!", name ); | |||
| @@ -201,7 +204,9 @@ else if ( ! Project::open( name ) ) | |||
| fl_alert( "Could not open \\"%s\\" as a Non-DAW project!", name ); | |||
| // we are in a somewhar ambiguous state now with no project open. | |||
| }} | |||
| } | |||
| progress->hide(); | |||
| timeline->show();} | |||
| xywh {10 10 40 25} | |||
| } | |||
| MenuItem {} { | |||
| @@ -544,15 +549,15 @@ delete win;} | |||
| } | |||
| } | |||
| Fl_Group {} {open | |||
| xywh {0 23 1024 48} | |||
| xywh {-10 23 1034 51} | |||
| } { | |||
| Fl_Pack {} {open | |||
| xywh {0 23 473 46} type HORIZONTAL | |||
| xywh {-10 23 483 46} type HORIZONTAL | |||
| code0 {o->spacing( 10 );} | |||
| } { | |||
| Fl_Box {} { | |||
| label {<Transport>} | |||
| xywh {0 23 184 46} color 30 | |||
| xywh {-10 23 194 46} color 30 | |||
| code0 {transport = o;} | |||
| code1 {o->labeltype( FL_NO_LABEL );} | |||
| class Transport | |||
| @@ -611,6 +616,10 @@ delete win;} | |||
| } | |||
| } | |||
| } | |||
| Fl_Progress progress { | |||
| label {0%} | |||
| xywh {15 394 995 41} hide | |||
| } | |||
| Fl_Box {} { | |||
| label {<Timeline>} | |||
| xywh {0 72 1024 695} box FLAT_BOX color 47 labelsize 100 resizable | |||
| @@ -670,7 +679,8 @@ project_name->redraw();} {} | |||
| snprintf( s, 5, "%d%%", (int)v ); | |||
| p->label( s );} {} | |||
| p->label( s );} {selected | |||
| } | |||
| } | |||
| Function {update_status()} {open | |||
| } { | |||
| @@ -701,7 +711,7 @@ xruns_output->value( engine->xruns() );} {} | |||
| } { | |||
| Fl_Window about_dialog_window { | |||
| label About open | |||
| private xywh {658 165 495 600} type Double xclass {Non-DAW} visible | |||
| private xywh {758 335 495 600} type Double xclass {Non-DAW} visible | |||
| } { | |||
| Fl_Tabs {} {open | |||
| xywh {0 213 497 392} | |||
| @@ -795,6 +805,18 @@ save(); | |||
| exit( 0 );} {} | |||
| } | |||
| Function {progress_cb( int p, void *arg )} {open return_type {static void} | |||
| } { | |||
| code {Fl_Progress *progress = ((TLE*)arg)->progress; | |||
| static char pat[10]; | |||
| update_progress( progress, pat, p ); | |||
| progress->redraw(); | |||
| Fl::check();} {} | |||
| } | |||
| } | |||
| class New_Project_Dialog {open | |||