|
-
- /*******************************************************************************/
- /* Copyright (C) 2008 Jonathan Moore Liles */
- /* */
- /* This program is free software; you can redistribute it and/or modify it */
- /* under the terms of the GNU General Public License as published by the */
- /* Free Software Foundation; either version 2 of the License, or (at your */
- /* option) any later version. */
- /* */
- /* This program 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 General Public License for */
- /* more details. */
- /* */
- /* You should have received a copy of the GNU General Public License along */
- /* with This program; see the file COPYING. If not,write to the Free Software */
- /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
- /*******************************************************************************/
-
- #include "Fl_Menu_Settings.H"
-
- #include <string.h>
-
- /* code to dump and restore (portions of) an Fl_Menu_ */
-
- #define MAX_PATH 1024
-
- void
- Fl_Menu_Settings::remove_ampersands ( char *str, int n )
- {
- char *d = str;
- char *s = str;
-
- while ( n-- )
- {
- if ( *s == '&' )
- {
- ++s;
- continue;
- }
-
- *(d++) = *(s++);
- }
-
- *d = '\0';
- }
-
- void
- Fl_Menu_Settings::indent ( FILE *fp, int n )
- {
- while ( n-- )
- fprintf( fp, "\t" );
- }
-
- int
- Fl_Menu_Settings::item_pathname_x ( char *path, int n, const Fl_Menu_Item *item )
- {
- int r = Fl_Menu_::item_pathname( path, n, item );
-
- remove_ampersands( path, n );
-
- return r;
- }
-
- /** dump options from submenu /menu/ of menubar /bar/ to file /fp/ */
- const Fl_Menu_Item *
- Fl_Menu_Settings::dump ( Fl_Menu_ *bar, const Fl_Menu_Item *menu, FILE *fp, int depth )
- {
- static char path[256];
- const Fl_Menu_Item *m = menu;
-
- for ( ; m->text; ++m )
- {
- bool is_radio = false;
-
- if ( m->flags & FL_SUBMENU )
- // if ( m->submenu() )
- {
- strcpy( path, m->text );
- remove_ampersands( path, strlen( path ) );
-
- indent( fp, depth );
- fprintf( fp, "%s\n", path );
-
- /* recurse */
- m = dump( bar, ++m, fp, depth + 1 );
-
- // ++m;
-
- // m = dump( bar, m->flags & FL_SUBMENU_POINTER ? (Fl_Menu_Item*) m->user_data() : m, fp, depth + 1 );
-
- if ( ! depth )
- break;
- else
- continue;
- }
-
- if ( m->radio() )
- is_radio = true;
-
- // bar->item_pathname( path, sizeof( path ) - 1, m );
- item_pathname_x( path, sizeof( path ) - 1, m );
-
-
- if ( m->flags & FL_MENU_TOGGLE || m->flags & FL_MENU_RADIO )
- {
- if ( ! is_radio )
- {
- indent( fp, depth );
-
- fprintf( fp, "%s\n", rindex( path, '/' ) + 1 );
-
- indent( fp, depth + 1 );
-
- fprintf( fp, "%s\n", m->flags & FL_MENU_VALUE ? "true" : "false" );
- }
- else if ( m->flags & FL_MENU_VALUE )
- {
- *rindex( path, '/' ) = '\0';
-
- indent( fp, depth );
-
- fprintf( fp, "%s\n", path + strlen( path ) + 1 );
- }
- }
-
- }
-
- return m;
- }
-
- /** dump menu to file /name/ starting at /item. */
- int
- Fl_Menu_Settings::dump ( const Fl_Menu_Item *item, const char *name )
- {
- FILE *fp = fopen( name, "w" );
-
- if ( ! fp )
- return false;
-
- dump( this, item, fp, 0 );
-
- fclose( fp );
-
-
- return true;
- }
-
- #define strlcat strncat
-
- /* taken from Fl_Menu_.cxx and modified to ignore hotkeys and case */
- const Fl_Menu_Item *
- Fl_Menu_Settings::find_item_x ( const char *name, const Fl_Menu_Item *item )
- {
- char menupath [ MAX_PATH ] = ""; // File/Export
-
- const Fl_Menu_Item *m = item ? item : menu();
-
- int depth = 0;
-
- while ( depth >= 0 )
- for ( ;m ; ++m )
- {
- if ( m->flags & FL_SUBMENU )
- {
- // IT'S A SUBMENU
- // we do not support searches through FL_SUBMENU_POINTER links
- if ( menupath[0] )
- strlcat( menupath, "/", sizeof( menupath ) );
-
- strlcat( menupath, m->label(), sizeof( menupath ) );
-
- remove_ampersands( menupath, strlen( menupath ) );
-
- if ( ! strcasecmp( menupath, name ) )
- return m;
- else
- {
- ++depth;
- continue;
- }
- }
- else
- {
- if ( ! m->label() )
- {
- // END OF SUBMENU? Pop back one level.
- char *ss = strrchr( menupath, '/' );
- if ( ss )
- *ss = 0;
- else
- menupath[0] = '\0';
-
- --depth;
- ++m;
-
- break;
- }
-
- // IT'S A MENU ITEM
- char itempath[ MAX_PATH ]; // eg. Edit/Copy
- strcpy( itempath, menupath );
-
- if ( itempath[0] )
- strlcat( itempath, "/", sizeof( itempath ) );
-
- strlcat( itempath, m->label(), sizeof( itempath ) );
-
- remove_ampersands( itempath, strlen( itempath ) );
-
- if ( !strcasecmp( itempath, name ) )
- return m;
- }
- }
-
- return ( Fl_Menu_Item * )0;
- }
-
-
- static void
- path_push ( char *path, const char *s )
- {
- strcat( path, s );
- strcat( path, "/" );
- }
-
- static void
- path_pop ( char *path )
- {
- char *s;
-
- int l = strlen( path );
-
- if ( ! l )
- return;
-
- if ( path[ l - 1 ] == '/' )
- path[ l - 1 ] = '\0';
-
- s = rindex( path, '/' );
-
- if ( s )
- *(s + 1) = '\0';
- else
- *path = '\0';
- }
-
- void
- Fl_Menu_Settings::load ( Fl_Menu_ *bar, const Fl_Menu_Item *item, FILE *fp, int depth, char *path, int pmax )
- {
- char line[256];
-
- while ( ! feof( fp ) )
- {
- *line = '\0';
-
- fgets( line, sizeof( line ), fp );
-
- if ( *line == '#' )
- continue;
-
- line[ strlen( line ) - 1 ] = '\0';
-
- int ld = strspn( line, "\t" );
-
- if ( ld > depth )
- {
- path_push( path, line + ld );
-
- ++depth;
-
- // load( bar, item, fp, depth + 1, path, pmax );
- /* */;
- }
- else if ( ld < depth )
- {
- /* we should know the path and the value now */
-
- // path_pop( path );
- *rindex( path, '/' ) = '\0';
-
- // printf( "%s = %s\n", path, path + strlen( path ) + 1 );
-
- const Fl_Menu_Item *it = find_item_x( path, item + 1 );
-
- if ( it && it->radio() ) /* radio button */
- {
- bar->picked( it );
-
- path_pop( path );
- }
- else /* toggle */
- {
- *rindex( path, '/' ) = '\0';
-
- if ( ( it = find_item_x( path, item + 1 ) ) && it->checkbox() )
- {
- int v = 0 == strcasecmp( "true", (path + strlen( path ) + 1 ) );
-
- if ( v != ( it->value() != 0 ) /* grr, FLTK */ )
- bar->picked( it );
- }
-
- }
-
- while ( ld < depth )
- {
- path_pop( path );
- depth--;
- }
-
- path_push( path, line + ld );
- }
- else /* d == depth */
- {
- /* doesn't apply? */
- }
- }
- }
-
- /** load settings from file /name/ into menu starting at /item */
- int
- Fl_Menu_Settings::load ( const Fl_Menu_Item *item, const char *name )
- {
- FILE *fp = fopen( name, "r" );
-
- if ( ! fp )
- return false;
-
- char path[ MAX_PATH ];
- path[0] = '\0';
-
- load( this, item, fp, 0, path, sizeof( path ) );
-
- fclose( fp );
-
- return true;
- }
|