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