X-Git-Url: https://git.distorted.org.uk/~mdw/mup/blobdiff_plain/cdb3c0882392596f814cf939cbfbd38adc6f2bfe..ddf6330b56bcfb657e0186b24b9b1422c51d3424:/mup/mupmate/Preferences.C diff --git a/mup/mupmate/Preferences.C b/mup/mupmate/Preferences.C new file mode 100644 index 0000000..23aba11 --- /dev/null +++ b/mup/mupmate/Preferences.C @@ -0,0 +1,317 @@ +/* Copyright (c) 2006 by Arkkra Enterprises */ +/* All rights reserved */ + +// This file contains code for defining and using things +// related to user configuration settings and preferences. + +#include +#include +#include +#include "globals.H" +#include "utils.H" +#include "Preferences.H" +#include + +// Access to the user preferences file +Fl_Preferences * Preferences_p; + +// Preference names and default values +const char * const Editor_font_preference = "editor_font"; +const char * const Default_editor_font = "Courier"; + +const char * const Editor_size_preference = "editor_size"; +const char * const Default_editor_size = "12"; + +const char * const Auto_display_preference = "auto_display"; +const int Default_auto_display = 0; + +const char * const Auto_save_preference = "auto_save"; +const int Default_auto_save = 1; + +const char * const Tooltips_delay_preference = "tooltips_delay"; +const double Default_tooltips_delay = 1.0; + +const char * const Mup_program_location = "Mup_program"; +const char * const Default_Mup_program_location = "mup"; + +const char * const Mup_documentation_location = "Mup_documentation"; +#if defined(__WIN32) +const char * const Default_Mup_documentation_location = "c:\\Program Files\\mupmate"; +#else +const char * const Default_Mup_documentation_location = "/usr/share/doc/packages/mup"; +#endif + +const char * const Music_files_location = "Music_folder"; +const char * const Default_music_files_location = "."; + +const char * const MUPPATH_location = "MUPPATH"; +const char * const Default_MUPPATH_location = "."; + +const char * const Viewer_location = "Viewer"; +#if defined(__WIN32) +const char * const Default_viewer_location = "c:\\Program Files\\Ghostgum\\gsview\\gsview32.exe"; +#else +const char * const Default_viewer_location = "gv"; +#endif + +const char * const MIDI_player_location = "MIDI_player"; +#if defined(__WIN32) +const char * const Default_MIDI_player_location = "c:\\Program Files\\Windows Media Player\\wmplayer.exe"; +#else +const char * const Default_MIDI_player_location = "xplaymidi"; +#endif + +const char * const Showed_startup_hints = "showed_startup_hints"; +const int Default_startup_hints_flag = 0; + +// Name of User's Guide directory and index file +// relative to Mup documentation directory. +const char * uguide_directory = "uguide"; +#ifdef OS_LIKE_WIN32 +const char * uguide_filename = "index.htm"; +#else +const char * uguide_filename = "index.html"; +#endif + +// Don't use un-readable tiny font, but especially avoid size of zero, +// which could happen if preferences file contains a bad number, so that +// atoi() returns zero. Keep max small enough to fit reasonable number +// of characters in a window. +const unsigned char Min_size = 5; +const unsigned char Max_size = 30; + +// Minimum and default sizes for Main and Help browser windows. +const int Min_width = 600; +const int Default_width = 720; +const int Min_height = 400; +const int Default_height = 480; + + +// If user hasn't specified any program yet to use for PostScript viewer +// and/or MIDI file player, we try to deduce what they have available +// that could be used, and set one of those as the default. + +// List of likely programs to use as PostScript viewers +static const char * const viewer_candidates[] = { +#if defined(__WIN32) + "GSview32", + "GSview", +#else +#ifdef OS_LIKE_UNIX + "gv", + "ghostview", +#endif +#endif + 0 +}; + +// List of likely programs to use as MIDI file players +static const char * const player_candidates[] = { +#if defined(__WIN32) + "wmplayer", + "mplayer", +#else +#ifdef OS_LIKE_UNIX + "xplaymidi", + "timidity", + "pmidi", + "playmidi", +#endif +#endif + 0 +}; + + +// If the default preference value for a program location is no good, +// try to find where it is. +// pgm_location = the preference name of the program of interest +// default_location = the default path to the program +// file_suffix = .ps or .mod or .mup +// Returns true if the preference value was updated. + +static bool +deduce_location(const char * pgm_location, const char * default_location, + const char * file_suffix, const char * const * candidates) +{ + char * place; // a path to try for finding the pgm + char location[FL_PATH_MAX]; // full path to pgm when it is found + + if (Preferences_p->get(pgm_location, place, default_location) != 0) { + // There was a value already set. Make sure it is good. + if (find_executable(place, location)) { + if (strcmp(place, location) != 0) { + // Must have started as relative path + // and now we know the full path. + (void) Preferences_p->set(pgm_location, location); + return(true); + } + else { + // Existing setting was okay as is. + return(false); + } + } + } + +#ifdef OS_LIKE_WIN32 + // Try looking in the registry for what to use for + // files of this type. + if ((place = lookup_pgm_for_file_suffix(file_suffix)) != 0) { + (void) Preferences_p->set(place, default_location); + return(true); + } +#endif + + // If there had been nothing set, see if the default location is good. + if (find_executable(default_location, location)) { + (void) Preferences_p->set(pgm_location, location); + return(true); + } + + // Try looking in the various educated guess locations. + if (candidates != 0) { + int i; + for (i = 0; candidates[i] != 0; i++) { + if (find_executable(candidates[i], location)) { + (void) Preferences_p->set(pgm_location, location); + return(true); + } + } + } + + return(false); +} + + +// Returns true is the Mup User's Guide can be found at the given location. + +static bool +doc_found(const char * location) +{ + return(access(users_guide_index_file(location), F_OK) == 0); +} + + +// Try to deduce where the Mup documentation is. +// Returns true if updated the Preferences to point to new location. + +static bool +deduce_documentation_location(const char * doc_location, const char * default_doc_location) +{ + char * place; + // First try the stored location, if any + if (Preferences_p->get(doc_location, place, default_doc_location) != 0) { + if (doc_found(place)) { + // Existing preference is good. No update needed. + return(false); + } + } + + // Try default location + if (doc_found(default_doc_location)) { + Preferences_p->set(doc_location, default_doc_location); + return(true); + } + + // Try relative to where Mup executable is. + char *muploc; + (void) Preferences_p->get(Mup_program_location, muploc, + Default_Mup_program_location); + char * basename_p; + if ((basename_p = strrchr(muploc, dir_separator())) != 0) { + int len = basename_p - muploc; + char mupdir[len + 1]; + (void) strncpy(mupdir, muploc, len); + mupdir[len] = '\0'; + if (doc_found(mupdir)) { + Preferences_p->set(doc_location, mupdir); + return(true); + } + + // Try at ../docs from where mup executable was, + // since it could be there from unpacking tar file. + char * parentdir_p; + if ((parentdir_p = strrchr(mupdir, dir_separator())) != 0) { + len = parentdir_p - mupdir + 1; + // Add room for doc and terminator + char mupdocdir[len + 5]; + (void) strncpy(mupdocdir, muploc, len); + (void) strcpy(mupdocdir + len, "docs"); + if (doc_found(mupdocdir)) { + Preferences_p->set(doc_location, mupdocdir); + return(true); + } + } + } + return(false); +} + + +// This function attempts to find the locations of what we need, +// like a PostScript viewer and MIDI player. + +void +deduce_helper_locations(void) +{ + bool updated = false; + + // First try to find a PostScript viewer + if (deduce_location(Viewer_location, Default_viewer_location, ".ps", + viewer_candidates)) { + updated = true; + } + + // Next do MIDI player + if (deduce_location(MIDI_player_location, Default_MIDI_player_location, + ".mid", player_candidates)) { + updated = true; + } + + // Find the Mup command itself + if (deduce_location(Mup_program_location, Default_Mup_program_location, ".mup", 0)) { + updated = true; + } + + if (deduce_documentation_location(Mup_documentation_location, + Default_Mup_documentation_location)) { + updated = true; + } + +#ifdef OS_LIKE_WIN32 + // Try to guess a good default place for Mup input files. + char * place; + if (Preferences_p->get(Music_files_location, place, + Default_music_files_location) == 0) { + if ((place = find_music_folder()) != 0) { + Preferences_p->set(Music_files_location, place); + updated = true; + } + } + // The same place is probably a good guess for Mup include files. + if (Preferences_p->get(MUPPATH_location, place, + Default_MUPPATH_location) == 0) { + if ((place = find_music_folder()) != 0) { + Preferences_p->set(MUPPATH_location, place); + updated = true; + } + } +#endif + + // If at least one better choice was found, update the persistent data. + if (updated) { + Preferences_p->flush(); + } +} + + +// Given a path to Mup's documentation directory, +// add on the name of the User's Guide index file. +// Return that in a static area. + +const char * +users_guide_index_file(const char * const doc_dir) +{ + static char file_path[FL_PATH_MAX]; + (void) sprintf(file_path, "%s%c%s%c%s", doc_dir, dir_separator(), + uguide_directory, dir_separator(), uguide_filename); + return((const char *) file_path); +}