summaryrefslogtreecommitdiff
path: root/app/bin/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/fileio.c')
-rw-r--r--app/bin/fileio.c1565
1 files changed, 1565 insertions, 0 deletions
diff --git a/app/bin/fileio.c b/app/bin/fileio.c
new file mode 100644
index 0000000..dcd8b5c
--- /dev/null
+++ b/app/bin/fileio.c
@@ -0,0 +1,1565 @@
+/** \file fileio.c
+ * Loading and saving files. Handles trackplans as well as DXF export.
+ *
+ * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/fileio.c,v 1.18 2009-05-08 15:28:54 m_fischer Exp $
+ */
+
+/* XTrkCad - Model Railroad CAD
+ * Copyright (C) 2005 Dave Bullis
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef WINDOWS
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#endif
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#ifdef WINDOWS
+#include <io.h>
+#include <windows.h>
+ #if _MSC_VER >=1400
+ #define strdup _strdup
+ #endif
+#else
+#endif
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <locale.h>
+
+#include <stdint.h>
+
+#include "track.h"
+#include "version.h"
+#include "common.h"
+#include "utility.h"
+#include "draw.h"
+#include "misc.h"
+#include "compound.h"
+#include "i18n.h"
+
+/*#define TIME_READTRACKFILE*/
+
+EXPORT const char * workingDir;
+EXPORT const char * libDir;
+
+static char * customPath = NULL;
+static char * customPathBak = NULL;
+
+EXPORT char curPathName[STR_LONG_SIZE];
+EXPORT char * curFileName;
+EXPORT char curDirName[STR_LONG_SIZE];
+
+EXPORT char * clipBoardN;
+
+EXPORT wBool_t executableOk = FALSE;
+
+static int log_paramFile;
+
+EXPORT void SetCurDir(
+ const char * pathName,
+ const char * fileName )
+{
+ memcpy( curDirName, pathName, fileName-pathName );
+ curDirName[fileName-pathName-1] = '\0';
+ wPrefSetString( "file", "directory", curDirName );
+}
+
+#ifdef WINDOWS
+#define rename( F1, F2 ) Copyfile( F1, F2 )
+
+static int Copyfile( char * fn1, char * fn2 )
+{
+ FILE *f1, *f2;
+ size_t size;
+ f1 = fopen( fn1, "r" );
+ if ( f1 == NULL )
+ return 0;
+ f2 = fopen( fn2, "w" );
+ if ( f2 == NULL ) {
+ fclose( f1 );
+ return -1;
+ }
+ while ( (size=fread( message, 1, sizeof message, f1 )) > 0 )
+ fwrite( message, size, 1, f2 );
+ fclose( f1 );
+ fclose( f2 );
+ return 0;
+}
+#endif
+
+/**
+ * Save the old locale and set to new.
+ *
+ * \param newlocale IN the new locale to set
+ * \return pointer to the old locale
+ */
+
+char *
+SaveLocale( char *newLocale )
+{
+ char *oldLocale;
+ char *saveLocale = NULL;
+
+ /* get old locale setting */
+ oldLocale = setlocale(LC_ALL, NULL);
+
+ /* allocate memory to save */
+ if (oldLocale)
+ saveLocale = strdup( oldLocale );
+
+ setlocale(LC_ALL, newLocale );
+
+ return( saveLocale );
+}
+
+/**
+ * Restore a previously saved locale.
+ *
+ * \param locale IN return value from earlier call to SaveLocale
+ */
+
+void
+RestoreLocale( char * locale )
+{
+ if( locale ) {
+ setlocale( LC_ALL, locale );
+ free( locale );
+ }
+}
+
+
+/****************************************************************************
+ *
+ * PARAM FILE INPUT
+ *
+ */
+
+EXPORT FILE * paramFile = NULL;
+EXPORT char paramFileName[STR_LONG_SIZE];
+EXPORT wIndex_t paramLineNum = 0;
+EXPORT char paramLine[STR_LONG_SIZE];
+EXPORT char * curContents;
+EXPORT char * curSubContents;
+static long paramCheckSum;
+
+#define PARAM_DEMO (-1)
+
+typedef struct {
+ char * name;
+ readParam_t proc;
+ } paramProc_t;
+static dynArr_t paramProc_da;
+#define paramProc(N) DYNARR_N( paramProc_t, paramProc_da, N )
+
+
+EXPORT void Stripcr( char * line )
+{
+ char * cp;
+ cp = line + strlen(line);
+ if (cp == line)
+ return;
+ cp--;
+ if (*cp == '\n')
+ *cp-- = '\0';
+ if (cp >= line && *cp == '\r')
+ *cp = '\0';
+}
+
+EXPORT void ParamCheckSumLine( char * line )
+{
+ long mult=1;
+ while ( *line )
+ paramCheckSum += (((long)(*line++))&0xFF)*(mult++);
+}
+
+EXPORT char * GetNextLine( void )
+{
+ if (!paramFile) {
+ paramLine[0] = '\0';
+ return NULL;
+ }
+ if (fgets( paramLine, sizeof paramLine, paramFile ) == NULL) {
+ AbortProg( "Permature EOF on %s", paramFileName );
+ }
+ Stripcr( paramLine );
+ ParamCheckSumLine( paramLine );
+ paramLineNum++;
+ return paramLine;
+}
+
+
+/**
+ * Show an error message if problems occur during loading of a param or layout file.
+ * The user has the choice to cancel the operation or to continue. If operation is
+ * canceled the open file is closed.
+ *
+ * \param IN msg error message
+ * \param IN showLine set to true if current line should be included in error message
+ * \param IN ... variable number additional error information
+ * \return TRUE to continue, FALSE to abort operation
+ *
+ */
+
+EXPORT int InputError(
+ char * msg,
+ BOOL_T showLine,
+ ... )
+{
+ va_list ap;
+ char * mp = message;
+ int ret;
+
+ mp += sprintf( message, "INPUT ERROR: %s:%d\n",
+ paramFileName, paramLineNum );
+ va_start( ap, showLine );
+ mp += vsprintf( mp, msg, ap );
+ va_end( ap );
+ if (showLine) {
+ *mp++ = '\n';
+ strcpy( mp, paramLine );
+ }
+ strcat( mp, _("\nDo you want to continue?") );
+ if (!(ret = wNoticeEx( NT_ERROR, message, _("Continue"), _("Stop") ))) {
+ if ( paramFile )
+ fclose(paramFile);
+ paramFile = NULL;
+ }
+ return ret;
+}
+
+
+EXPORT void SyntaxError(
+ char * event,
+ wIndex_t actual,
+ wIndex_t expected )
+{
+ InputError( "%s scan returned %d (expected %d)",
+ TRUE, event, actual, expected );
+}
+
+/**
+ * Parse a line in XTrackCAD's file format
+ *
+ * \param line IN line to parse
+ * \param format IN ???
+ *
+ * \return FALSE in case of parsing error, TRUE on success
+ */
+
+EXPORT BOOL_T GetArgs(
+ char * line,
+ char * format,
+ ... )
+{
+ unsigned char * cp, * cq;
+ int argNo;
+ long * pl;
+ int * pi;
+ FLOAT_T *pf;
+ coOrd p, *pp;
+ char * ps;
+ char ** qp;
+ va_list ap;
+ char *oldLocale = NULL;
+
+ oldLocale = SaveLocale("C");
+
+ cp = line;
+ va_start( ap, format );
+ for (argNo=1;*format;argNo++,format++) {
+ while (isspace(*cp)) cp++;
+ if (!*cp && strchr( "XZYzc", *format ) == NULL ) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: EOL unexpected", TRUE, argNo );
+ return FALSE;
+ }
+ switch (*format) {
+ case '0':
+ (void)strtol( cp, &cq, 10 );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected integer", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ break;
+ case 'X':
+ pi = va_arg( ap, int * );
+ *pi = 0;
+ break;
+ case 'Z':
+ pl = va_arg( ap, long * );
+ *pl = 0;
+ break;
+ case 'Y':
+ pf = va_arg( ap, FLOAT_T * );
+ *pf = 0;
+ break;
+ case 'L':
+ pi = va_arg( ap, int * );
+ *pi = (int)strtol( cp, &cq, 10 );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected integer", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ break;
+ case 'd':
+ pi = va_arg( ap, int * );
+ *pi = (int)strtol( cp, &cq, 10 );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected integer", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ break;
+ case 'w':
+ pf = va_arg( ap, FLOAT_T * );
+ *pf = (FLOAT_T)strtol( cp, &cq, 10 );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected integer", TRUE, argNo );
+ return FALSE;
+ }
+ if (*cq == '.')
+ *pf = strtod( cp, &cq );
+ else
+ *pf /= mainD.dpi;
+ cp = cq;
+ break;
+ case 'l':
+ pl = va_arg( ap, long * );
+ *pl = strtol( cp, &cq, 10 );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected integer", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ break;
+ case 'f':
+ pf = va_arg( ap, FLOAT_T * );
+ *pf = strtod( cp, &cq );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected float", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ break;
+ case 'z':
+ pf = va_arg( ap, FLOAT_T * );
+#ifdef LATER
+ if ( paramVersion >= 9 ) {
+ *pf = strtod( cp, &cq );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected float", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ } else {
+ *pf = 0.0;
+ }
+#endif
+ *pf = 0.0;
+ break;
+ case 'p':
+ pp = va_arg( ap, coOrd * );
+ p.x = strtod( cp, &cq );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected float", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ p.y = strtod( cp, &cq );
+ if (cp == cq) {
+ RestoreLocale(oldLocale);
+ InputError( "Arg %d: expected float", TRUE, argNo );
+ return FALSE;
+ }
+ cp = cq;
+ *pp = p;
+ break;
+ case 's':
+ ps = va_arg( ap, char * );
+ while (isspace(*cp)) cp++;
+ while (*cp && !isspace(*cp)) *ps++ = *cp++;
+ *ps++ = '\0';
+ break;
+ case 'q':
+ qp = va_arg( ap, char * * );
+ if (*cp != '\"')
+ /* Stupid windows */
+ cq = strchr( cp, '\"' );
+ else
+ cq = cp;
+ if (cq!=NULL) {
+ cp = cq;
+ ps = &message[0];
+ cp++;
+ while (*cp) {
+ if ( (ps-message)>=sizeof message)
+ AbortProg( "Quoted title argument too long" );
+ if (*cp == '\"') {
+ if (*++cp == '\"') {
+ *ps++ = '\"';
+ } else {
+ *ps = '\0';
+ cp++;
+ break;
+ }
+ } else {
+ *ps++ = *cp;
+ }
+ cp++;
+ }
+ *ps = '\0';
+ } else {
+ message[0] = '\0';
+ }
+ *qp = (char*)MyStrdup(message);
+ break;
+ case 'c':
+ qp = va_arg( ap, char * * );
+ while (isspace(*cp)) cp++;
+ if (*cp)
+ *qp = cp;
+ else
+ *qp = NULL;
+ break;
+ default:
+ AbortProg( "getArgs: bad format char" );
+ }
+ }
+ va_end( ap );
+ RestoreLocale(oldLocale);
+ return TRUE;
+}
+
+EXPORT wBool_t ParseRoomSize(
+ char * s,
+ coOrd * roomSizeRet )
+{
+ coOrd size;
+ char *cp;
+
+ size.x = strtod( s, &cp );
+ if (cp != s) {
+ s = cp;
+ while (isspace(*s)) s++;
+ if (*s == 'x' || *s == 'X') {
+ size.y = strtod( ++s, &cp );
+ if (cp != s) {
+#ifdef LATER
+ if (units == UNITS_METRIC) {
+ size.x /= 2.54;
+ size.y /= 2.54;
+ }
+#endif
+ *roomSizeRet = size;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+EXPORT void AddParam(
+ char * name,
+ readParam_t proc )
+{
+ DYNARR_APPEND( paramProc_t, paramProc_da, 10 );
+ paramProc(paramProc_da.cnt-1).name = name;
+ paramProc(paramProc_da.cnt-1).proc = proc;
+}
+
+
+EXPORT BOOL_T ReadParams(
+ long key,
+ const char * dirName,
+ const char * fileName )
+{
+ FILE * oldFile;
+ char *cp;
+ wIndex_t oldLineNum;
+ wIndex_t pc;
+ long oldCheckSum;
+ long checkSum=0;
+ BOOL_T checkSummed;
+ long paramVersion = -1;
+ char *oldLocale = NULL;
+
+ if (dirName) {
+ strcpy( paramFileName, dirName );
+ strcat( paramFileName, FILE_SEP_CHAR );
+ strcat( paramFileName, fileName );
+ } else {
+ strcpy( paramFileName, fileName );
+ }
+ paramLineNum = 0;
+ curBarScale = -1;
+ curContents = strdup( fileName );
+ curSubContents = curContents;
+
+LOG1( log_paramFile, ("ReadParam( %s )\n", fileName ) )
+
+ oldLocale = SaveLocale("C");
+
+ paramFile = fopen( paramFileName, "r" );
+ if (paramFile == NULL) {
+ /* Reset the locale settings */
+ RestoreLocale( oldLocale );
+
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Parameter"), paramFileName, strerror(errno) );
+
+ return FALSE;
+ }
+ paramCheckSum = key;
+ paramLineNum = 0;
+ checkSummed = FALSE;
+ while ( paramFile && ( fgets(paramLine, 256, paramFile) ) != NULL ) {
+ paramLineNum++;
+ Stripcr( paramLine );
+ if (strncmp( paramLine, "CHECKSUM ", 9 ) == 0) {
+ checkSum = atol( paramLine+9 );
+ checkSummed = TRUE;
+ goto nextLine;
+ }
+ ParamCheckSumLine( paramLine );
+ if (paramLine[0] == '#') {
+ /* comment */
+ } else if (paramLine[0] == 0) {
+ /* empty paramLine */
+ } else if (strncmp( paramLine, "INCLUDE ", 8 ) == 0) {
+ cp = &paramLine[8];
+ while (*cp && isspace(*cp)) cp++;
+ if (!*cp) {
+ InputError( "INCLUDE - no file name", TRUE );
+
+ /* Close file and reset the locale settings */
+ if (paramFile) fclose(paramFile);
+ RestoreLocale( oldLocale );
+
+ return FALSE;
+ }
+ oldFile = paramFile;
+ oldLineNum = paramLineNum;
+ oldCheckSum = paramCheckSum;
+ ReadParams( key, dirName, cp );
+ paramFile = oldFile;
+ paramLineNum = oldLineNum;
+ paramCheckSum = oldCheckSum;
+ if (dirName) {
+ strcpy( paramFileName, dirName );
+ strcat( paramFileName, FILE_SEP_CHAR );
+ strcat( paramFileName, fileName );
+ } else {
+ strcpy( paramFileName, fileName );
+ }
+ } else if (strncmp( paramLine, "CONTENTS ", 9) == 0 ) {
+ curContents = MyStrdup( paramLine+9 );
+ curSubContents = curContents;
+ } else if (strncmp( paramLine, "SUBCONTENTS ", 12) == 0 ) {
+ curSubContents = MyStrdup( paramLine+12 );
+ } else if (strncmp( paramLine, "PARAM ", 6) == 0 ) {
+ paramVersion = atol( paramLine+6 );
+ } else {
+ for (pc = 0; pc < paramProc_da.cnt; pc++ ) {
+ if (strncmp( paramLine, paramProc(pc).name,
+ strlen(paramProc(pc).name)) == 0 ) {
+ paramProc(pc).proc( paramLine );
+ goto nextLine;
+ }
+ }
+ InputError( "Unknown param line", TRUE );
+ }
+ nextLine:;
+ }
+ if ( key ) {
+ if ( !checkSummed || checkSum != paramCheckSum ) {
+ /* Close file and reset the locale settings */
+ if (paramFile) fclose(paramFile);
+ RestoreLocale( oldLocale );
+
+ NoticeMessage( MSG_PROG_CORRUPTED, _("Ok"), NULL, paramFileName );
+
+ return FALSE;
+ }
+ }
+ if (paramFile)fclose( paramFile );
+
+ RestoreLocale( oldLocale );
+
+ return TRUE;
+}
+
+
+static void ReadCustom( void )
+{
+ FILE * f;
+ customPath =
+ (char*)MyMalloc( strlen(workingDir) + 1 + strlen(sCustomF) + 1 );
+ sprintf( customPath, "%s%s%s", workingDir, FILE_SEP_CHAR, sCustomF );
+ customPathBak = MyStrdup( customPath );
+ customPathBak[ strlen(customPathBak)-1 ] = '1';
+ f = fopen( customPath, "r" );
+ if ( f != NULL ) {
+ fclose( f );
+ curParamFileIndex = PARAM_CUSTOM;
+ ReadParams( 0, workingDir, sCustomF );
+ }
+}
+
+
+/*
+ * Open the file and then set the locale to "C". Old locale will be copied to
+ * oldLocale. After the required file I/O is done, the caller must call
+ * CloseCustom() with the same locale value that was returned in oldLocale by
+ * this function.
+ */
+EXPORT FILE * OpenCustom( char *mode )
+{
+ FILE * ret = NULL;
+
+ if (inPlayback)
+ return NULL;
+ if ( *mode == 'w' )
+ rename( customPath, customPathBak );
+ if (customPath) {
+ ret = fopen( customPath, mode );
+ if (ret == NULL) {
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Custom"), customPath, strerror(errno) );
+ }
+ }
+
+ return ret;
+}
+
+
+EXPORT char * PutTitle( char * cp )
+{
+ static char title[STR_SIZE];
+ char * tp = title;
+ while (*cp && (tp-title)<=(sizeof title)-3) {
+ if (*cp == '\"') {
+ *tp++ = '\"';
+ *tp++ = '\"';
+ } else {
+ *tp++ = *cp;
+ }
+ cp++;
+ }
+ if ( *cp )
+ NoticeMessage( _("putTitle: title too long: %s"), _("Ok"), NULL, title );
+ *tp = '\0';
+ return title;
+}
+
+/**
+ * Set the title of the main window. After loading a file or changing a design
+ * this function is called to set the filename and the changed mark in the title
+ * bar.
+ */
+
+void SetWindowTitle( void )
+{
+ if ( changed > 2 || inPlayback )
+ return;
+ sprintf( message, "%s%s - %s(%s)",
+ (curFileName==NULL||curFileName[0]=='\0')?_("Unnamed Trackplan"):curFileName,
+ changed>0?"*":"", sProdName, sVersion );
+ wWinSetTitle( mainW, message );
+}
+
+/*****************************************************************************
+ *
+ * LOAD / SAVE TRACKS
+ *
+ */
+
+static struct wFilSel_t * loadFile_fs;
+static struct wFilSel_t * saveFile_fs;
+
+static wWin_p checkPointingW;
+static paramData_t checkPointingPLs[] = {
+ { PD_MESSAGE, N_("Check Pointing") } };
+static paramGroup_t checkPointingPG = { "checkpoint", 0, checkPointingPLs, sizeof checkPointingPLs/sizeof checkPointingPLs[0] };
+
+static char * checkPtFileName1;
+static char * checkPtFileName2;
+
+/** Read the layout design.
+ *
+ * \param IN pathName filename including directory
+ * \param IN fileName pointer to filename part in pathName
+ * \param IN full
+ * \param IN noSetCurDir if FALSE current diurectory is changed to file location
+ * \param IN complain if FALSE error messages are supressed
+ *
+ * \return FALSE in case of load error
+ */
+
+static BOOL_T ReadTrackFile(
+ const char * pathName,
+ const char * fileName,
+ BOOL_T full,
+ BOOL_T noSetCurDir,
+ BOOL_T complain )
+{
+ int count;
+ coOrd roomSize;
+ long scale;
+ char * cp;
+ char *oldLocale = NULL;
+ int ret = TRUE;
+
+ oldLocale = SaveLocale( "C" );
+
+ paramFile = fopen( pathName, "r" );
+ if (paramFile == NULL) {
+ /* Reset the locale settings */
+ RestoreLocale( oldLocale );
+
+ if ( complain )
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, sProdName, pathName, strerror(errno) );
+
+ return FALSE;
+ }
+
+ paramLineNum = 0;
+ strcpy( paramFileName, fileName );
+
+ InfoMessage("0");
+ count = 0;
+ while ( paramFile && ( fgets(paramLine, sizeof paramLine, paramFile) ) != NULL ) {
+ count++;
+ if (count%10 == 0) {
+ InfoMessage( "%d", count );
+ wFlush();
+ }
+ paramLineNum++;
+ if (strlen(paramLine) == (sizeof paramLine) -1 &&
+ paramLine[(sizeof paramLine)-1] != '\n') {
+ if( !(ret = InputError( "Line too long", TRUE )))
+ break;
+ }
+ Stripcr( paramLine );
+ if (paramLine[0] == '#' ||
+ paramLine[0] == '\n' ||
+ paramLine[0] == '\0' ) {
+ /* comment */
+ continue;
+ }
+
+ if (ReadTrack( paramLine )) {
+
+ } else if (strncmp( paramLine, "END", 3 ) == 0) {
+ break;
+ } else if (strncmp( paramLine, "VERSION ", 8 ) == 0) {
+ paramVersion = strtol( paramLine+8, &cp, 10 );
+ if (cp)
+ while (*cp && isspace(*cp)) cp++;
+ if ( paramVersion > iParamVersion ) {
+ if (cp && *cp) {
+ NoticeMessage( MSG_UPGRADE_VERSION1, _("Ok"), NULL, paramVersion, iParamVersion, sProdName, cp );
+ } else {
+ NoticeMessage( MSG_UPGRADE_VERSION2, _("Ok"), NULL, paramVersion, iParamVersion, sProdName );
+ }
+ break;
+ }
+ if ( paramVersion < iMinParamVersion ) {
+ NoticeMessage( MSG_BAD_FILE_VERSION, _("Ok"), NULL, paramVersion, iMinParamVersion, sProdName );
+ break;
+ }
+ } else if (!full) {
+ if( !(ret = InputError( "unknown command", TRUE )))
+ break;
+ } else if (strncmp( paramLine, "TITLE1 ", 7 ) == 0) {
+ strncpy( Title1, &paramLine[7], TITLEMAXLEN );
+ Title1[ TITLEMAXLEN - 1 ] = '\0';
+ /*wStringSetValue( title1PD.control, Title1 );*/
+ } else if (strncmp( paramLine, "TITLE2 ", 7 ) == 0) {
+ strncpy( Title2, &paramLine[7], TITLEMAXLEN );
+ Title2[ TITLEMAXLEN - 1 ] = '\0';
+ /*wStringSetValue( title2PD.control, Title2 );*/
+ } else if (strncmp( paramLine, "ROOMSIZE", 8 ) == 0) {
+ if ( ParseRoomSize( paramLine+8, &roomSize ) ) {
+ SetRoomSize( roomSize );
+ /*wFloatSetValue( roomSizeXPD.control, PutDim(roomSize.x) );*/
+ /*wFloatSetValue( roomSizeYPD.control, PutDim(roomSize.y) );*/
+ } else {
+ if( !(ret = InputError( "ROOMSIZE: bad value", TRUE )))
+ break;
+ }
+ } else if (strncmp( paramLine, "SCALE ", 6 ) == 0) {
+ if ( !DoSetScale( paramLine+5 ) ) {
+ if( !(ret = InputError( "SCALE: bad value", TRUE )))
+ break;
+ }
+ } else if (strncmp( paramLine, "MAPSCALE ", 9 ) == 0) {
+ scale = atol( paramLine+9 );
+ if (scale > 1) {
+ mapD.scale = mapScale = scale;
+ }
+ } else if (strncmp( paramLine, "LAYERS ", 7 ) == 0) {
+ ReadLayers( paramLine+7 );
+ } else {
+ if( !(ret = InputError( "unknown command", TRUE )))
+ break;
+ }
+ }
+
+ if (paramFile)
+ fclose(paramFile);
+
+ if( ret ) {
+ if (!noSetCurDir)
+ SetCurDir( pathName, fileName );
+
+ if (full) {
+ strcpy( curPathName, pathName );
+ curFileName = &curPathName[fileName-pathName];
+ SetWindowTitle();
+ }
+ }
+
+ RestoreLocale( oldLocale );
+
+ paramFile = NULL;
+ InfoMessage( "%d", count );
+ return ret;
+}
+
+
+EXPORT int LoadTracks(
+ const char * pathName,
+ const char * fileName,
+ void * data)
+{
+#ifdef TIME_READTRACKFILE
+ long time0, time1;
+#endif
+ if (pathName == NULL)
+ return TRUE;
+ paramVersion = -1;
+ wSetCursor( wCursorWait );
+ Reset();
+ ClearTracks();
+/* DefaultLayerProperties(); */
+ ResetLayers();
+ checkPtMark = changed = 0;
+ UndoSuspend();
+ useCurrentLayer = FALSE;
+#ifdef TIME_READTRACKFILE
+ time0 = wGetTimer();
+#endif
+ if (ReadTrackFile( pathName, fileName, TRUE, FALSE, TRUE )) {
+ wMenuListAdd( fileList_ml, 0, fileName, MyStrdup(pathName) );
+ ResolveIndex();
+#ifdef TIME_READTRACKFILE
+ time1 = wGetTimer();
+ printf( "time= %ld ms \n", time1-time0 );
+#endif
+ RecomputeElevations();
+ AttachTrains();
+ DoChangeNotification( CHANGE_ALL );
+ DoUpdateTitles();
+ LoadLayerLists();
+ }
+ UndoResume();
+ /*DoRedraw();*/
+ Reset();
+ wSetCursor( wCursorNormal );
+ return TRUE;
+}
+
+/**
+ * Load the layout specified by data. Filename may contain a full
+ * path.
+ * \param index IN ignored
+ * \param label IN ignored
+ * \param data IN filename
+ */
+
+EXPORT void DoFileList(
+ int index,
+ char * label,
+ void * data )
+{
+ char * fileName, * pathName = (char*)data;
+ fileName = strrchr( pathName, FILE_SEP_CHAR[0] );
+ if (fileName == NULL)
+ fileName = pathName;
+ else
+ fileName++;
+ LoadTracks( pathName, fileName, NULL );
+}
+
+
+static BOOL_T DoSaveTracks(
+ const char * fileName )
+{
+ FILE * f;
+ time_t clock;
+ BOOL_T rc = TRUE;
+ char *oldLocale = NULL;
+
+ oldLocale = SaveLocale( "C" );
+
+ f = fopen( fileName, "w" );
+ if (f==NULL) {
+ RestoreLocale( oldLocale );
+
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Track"), fileName, strerror(errno) );
+
+ return FALSE;
+ }
+ wSetCursor( wCursorWait );
+ time(&clock);
+ rc &= fprintf(f,"#%s Version: %s, Date: %s\n", sProdName, sVersion, ctime(&clock) )>0;
+ rc &= fprintf(f, "VERSION %d %s\n", iParamVersion, PARAMVERSIONVERSION )>0;
+ Stripcr( Title1 );
+ Stripcr( Title2 );
+ rc &= fprintf(f, "TITLE1 %s\n", Title1 )>0;
+ rc &= fprintf(f, "TITLE2 %s\n", Title2 )>0;
+ rc &= fprintf(f, "MAPSCALE %ld\n", (long)mapD.scale )>0;
+ rc &= fprintf(f, "ROOMSIZE %0.6f x %0.6f\n", mapD.size.x, mapD.size.y )>0;
+ rc &= fprintf(f, "SCALE %s\n", curScaleName )>0;
+ rc &= WriteLayers( f );
+ rc &= WriteMainNote( f );
+ rc &= WriteTracks( f );
+ rc &= fprintf(f, "END\n")>0;
+ if ( !rc )
+ NoticeMessage( MSG_WRITE_FAILURE, _("Ok"), NULL, strerror(errno), fileName );
+ fclose(f);
+
+ RestoreLocale( oldLocale );
+
+ checkPtMark = changed;
+ wSetCursor( wCursorNormal );
+ return rc;
+}
+
+
+static doSaveCallBack_p doAfterSave;
+
+static int SaveTracks(
+ const char * pathName,
+ const char * fileName,
+ void * data )
+{
+ if (pathName == NULL)
+ return TRUE;
+ SetCurDir( pathName, fileName );
+ DoSaveTracks( pathName );
+ wMenuListAdd( fileList_ml, 0, fileName, MyStrdup(pathName) );
+ checkPtMark = changed = 0;
+ if (curPathName != pathName)
+ strcpy( curPathName, pathName );
+ curFileName = &curPathName[fileName-pathName];
+ if (doAfterSave)
+ doAfterSave();
+ doAfterSave = NULL;
+ return TRUE;
+}
+
+
+EXPORT void DoSave( doSaveCallBack_p after )
+{
+ doAfterSave = after;
+ if (curPathName[0] == 0) {
+ if (saveFile_fs == NULL)
+ saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks"),
+ sSourceFilePattern, SaveTracks, NULL );
+ wFilSelect( saveFile_fs, curDirName );
+ } else {
+ SaveTracks( curPathName, curFileName, NULL );
+ }
+ SetWindowTitle();
+}
+
+EXPORT void DoSaveAs( doSaveCallBack_p after )
+{
+ doAfterSave = after;
+ if (saveFile_fs == NULL)
+ saveFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Save Tracks"),
+ sSourceFilePattern, SaveTracks, NULL );
+ wFilSelect( saveFile_fs, curDirName );
+ SetWindowTitle();
+}
+
+EXPORT void DoLoad( void )
+{
+ loadFile_fs = wFilSelCreate( mainW, FS_LOAD, 0, _("Open Tracks"),
+ sSourceFilePattern, LoadTracks, NULL );
+ wFilSelect( loadFile_fs, curDirName );
+}
+
+
+EXPORT void DoCheckPoint( void )
+{
+ int rc;
+
+ if (checkPointingW == NULL) {
+ ParamRegister( &checkPointingPG );
+ checkPointingW = ParamCreateDialog( &checkPointingPG, MakeWindowTitle(_("Check Pointing")), NULL, NULL, NULL, FALSE, NULL, F_TOP|F_CENTER, NULL );
+ }
+ rename( checkPtFileName1, checkPtFileName2 );
+ wShow( checkPointingW );
+ rc = DoSaveTracks( checkPtFileName1 );
+
+ /* could the check point file be written ok? */
+ if( rc ) {
+ /* yes, delete the backup copy of the checkpoint file */
+ remove( checkPtFileName2 );
+ } else {
+ /* no, rename the backup copy back to the checkpoint file name */
+ rename( checkPtFileName2, checkPtFileName1 );
+ }
+ wHide( checkPointingW );
+}
+
+/**
+ * Remove all temporary files before exiting.When the program terminates
+ * normally through the exit choice, files that are created temporarily are removed:
+ * xtrkcad.ckp
+ *
+ * \param none
+ * \return none
+ *
+ */
+
+EXPORT void CleanupFiles( void )
+{
+ if( checkPtFileName1 )
+ remove( checkPtFileName1 );
+}
+
+/**
+ * Check for existance of checkpoint file. Existance of a checkpoint file means that XTrkCAD was not properly
+ * terminated.
+ *
+ * \param none
+ * \return TRUE if exists, FALSE otherwise
+ *
+ */
+
+EXPORT int ExistsCheckpoint( void )
+{
+ int len;
+ char *pattern = sCheckPointF;
+ char *search;
+
+ struct stat fileStat;
+
+ len = strlen( workingDir ) + 1 + strlen( sCheckPointF ) + 1;
+ checkPtFileName1 = (char*)MyMalloc(len);
+ sprintf( checkPtFileName1, "%s%s%s", workingDir, FILE_SEP_CHAR, sCheckPointF );
+ checkPtFileName2 = (char*)MyMalloc(len);
+ sprintf( checkPtFileName2, "%s%s%s", workingDir, FILE_SEP_CHAR, sCheckPoint1F );
+
+ len = strlen( workingDir ) + 1 + strlen( pattern ) + 1;
+ search = (char*)MyMalloc(len);
+ sprintf( search, "%s%s%s", workingDir, FILE_SEP_CHAR, pattern );
+
+ if( !stat( search, &fileStat ) ) {
+ MyFree( search );
+ return TRUE;
+ } else {
+ MyFree( search );
+ return FALSE;
+ }
+
+
+#ifdef LATER
+ DIR *dir;
+
+ dir = opendir( search );
+ MyFree( search );
+
+ if( dir ) {
+ closedir( dir );
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+#endif
+
+}
+
+/**
+ * Load checkpoint file
+ *
+ * \return TRUE if exists, FALSE otherwise
+ *
+ */
+
+EXPORT int LoadCheckpoint( void )
+{
+ int len;
+ char *search;
+
+ paramVersion = -1;
+ wSetCursor( wCursorWait );
+
+ len = strlen( workingDir ) + 1 + strlen( sCheckPointF ) + 1;
+ search = (char*)MyMalloc(len);
+ sprintf( search, "%s%s%s", workingDir, FILE_SEP_CHAR, sCheckPointF );
+
+ UndoSuspend();
+
+ if (ReadTrackFile( search, search + strlen(search) - strlen( sCheckPointF ), TRUE, TRUE, TRUE )) {
+ ResolveIndex();
+
+ RecomputeElevations();
+ AttachTrains();
+ DoChangeNotification( CHANGE_ALL );
+ DoUpdateTitles();
+ }
+
+ Reset();
+ UndoResume();
+
+ wSetCursor( wCursorNormal );
+
+ strcpy( curPathName, "" );
+ curFileName = curPathName;
+ SetWindowTitle();
+ changed = TRUE;
+ MyFree( search );
+ return TRUE;
+}
+
+/*****************************************************************************
+ *
+ * IMPORT / EXPORT
+ *
+ */
+
+static struct wFilSel_t * exportFile_fs;
+static struct wFilSel_t * importFile_fs;
+static struct wFilSel_t * exportDXFFile_fs;
+
+
+static int ImportTracks(
+ const char * pathName,
+ const char * fileName,
+ void * data )
+{
+ long paramVersionOld = paramVersion;
+
+ if (pathName == NULL)
+ return TRUE;
+ paramVersion = -1;
+ wSetCursor( wCursorWait );
+ Reset();
+ SetAllTrackSelect( FALSE );
+ ImportStart();
+ UndoStart( _("Import Tracks"), "importTracks" );
+ useCurrentLayer = TRUE;
+ ReadTrackFile( pathName, fileName, FALSE, FALSE, TRUE );
+ ImportEnd();
+ /*DoRedraw();*/
+ EnableCommands();
+ wSetCursor( wCursorNormal );
+ paramVersion = paramVersionOld;
+ importMove = TRUE;
+ DoCommandB( (void*)(intptr_t)selectCmdInx );
+ SelectRecount();
+ return TRUE;
+}
+
+
+EXPORT void DoImport( void )
+{
+ if (importFile_fs == NULL)
+ importFile_fs = wFilSelCreate( mainW, FS_LOAD, 0, _("Import Tracks"),
+ sImportFilePattern, ImportTracks, NULL );
+
+ wFilSelect( importFile_fs, curDirName );
+}
+
+
+/**
+ * Export the selected track pieces
+ *
+ * \param pathname IN full path and filename for export file
+ * \param filename IN pointer to filename part *within* pathname
+ * \param data IN unused
+ * \return FALSE on error, TRUE on success
+ */
+
+static int DoExportTracks(
+ const char * pathName,
+ const char * fileName,
+ void * data )
+{
+ FILE * f;
+ time_t clock;
+ char *oldLocale = NULL;
+
+ if (pathName == NULL)
+ return TRUE;
+ SetCurDir( pathName, fileName );
+ f = fopen( pathName, "w" );
+ if (f==NULL) {
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Export"), fileName, strerror(errno) );
+ return FALSE;
+ }
+
+ oldLocale = SaveLocale("C");
+
+ wSetCursor( wCursorWait );
+ time(&clock);
+ fprintf(f,"#%s Version: %s, Date: %s\n", sProdName, sVersion, ctime(&clock) );
+ fprintf(f, "VERSION %d %s\n", iParamVersion, PARAMVERSIONVERSION );
+ ExportTracks( f );
+ fprintf(f, "END\n");
+ fclose(f);
+
+ RestoreLocale( oldLocale );
+
+ Reset();
+ wSetCursor( wCursorNormal );
+ UpdateAllElevations();
+ return TRUE;
+}
+
+
+EXPORT void DoExport( void )
+{
+ if (selectedTrackCount <= 0) {
+ ErrorMessage( MSG_NO_SELECTED_TRK );
+ return;
+ }
+ if (exportFile_fs == NULL)
+ exportFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Export Tracks"),
+ sImportFilePattern, DoExportTracks, NULL );
+
+ wFilSelect( exportFile_fs, curDirName );
+}
+
+
+static FILE * dxfF;
+static void DxfLine(
+ drawCmd_p d,
+ coOrd p0,
+ coOrd p1,
+ wDrawWidth width,
+ wDrawColor color )
+{
+ fprintf(dxfF, " 0\nLINE\n" );
+ fprintf(dxfF, " 8\n%s%d\n", sProdNameUpper, curTrackLayer+1 );
+ fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n 11\n%0.6f\n 21\n%0.6f\n",
+ p0.x, p0.y, p1.x, p1.y );
+ fprintf(dxfF, " 6\n%s\n", (d->options&DC_DASH)?"DASHED":"CONTINUOUS" );
+}
+
+static void DxfArc(
+ drawCmd_p d,
+ coOrd p,
+ DIST_T r,
+ ANGLE_T angle0,
+ ANGLE_T angle1,
+ BOOL_T drawCenter,
+ wDrawWidth width,
+ wDrawColor color )
+{
+ angle0 = NormalizeAngle(90.0-(angle0+angle1));
+ if (angle1 >= 360.0) {
+ fprintf(dxfF, " 0\nCIRCLE\n" );
+ fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n 40\n%0.6f\n",
+ p.x, p.y, r );
+ } else {
+ fprintf(dxfF, " 0\nARC\n" );
+ fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n 40\n%0.6f\n 50\n%0.6f\n 51\n%0.6f\n",
+ p.x, p.y, r, angle0, angle0+angle1 );
+ }
+ fprintf(dxfF, " 8\n%s%d\n", sProdNameUpper, curTrackLayer+1 );
+ fprintf(dxfF, " 6\n%s\n", (d->options&DC_DASH)?"DASHED":"CONTINUOUS" );
+}
+
+static void DxfString(
+ drawCmd_p d,
+ coOrd p,
+ ANGLE_T a,
+ char * s,
+ wFont_p fp,
+ FONTSIZE_T fontSize,
+ wDrawColor color )
+{
+ fprintf(dxfF, " 0\nTEXT\n" );
+ fprintf(dxfF, " 1\n%s\n", s );
+ fprintf(dxfF, " 8\n%s%d\n", sProdNameUpper, curTrackLayer+1 );
+ fprintf(dxfF, " 10\n%0.6f\n 20\n%0.6f\n", p.x, p.y );
+ fprintf(dxfF, " 40\n%0.6f\n", fontSize/72.0 );
+}
+
+static void DxfBitMap(
+ drawCmd_p d,
+ coOrd p,
+ wDrawBitMap_p bm,
+ wDrawColor color )
+{
+}
+
+static void DxfFillPoly(
+ drawCmd_p d,
+ int cnt,
+ coOrd * pts,
+ wDrawColor color )
+{
+ int inx;
+ for (inx=1; inx<cnt; inx++) {
+ DxfLine( d, pts[inx-1], pts[inx], 0, color );
+ }
+ DxfLine( d, pts[cnt-1], pts[0], 0, color );
+}
+
+static void DxfFillCircle( drawCmd_p d, coOrd center, DIST_T radius, wDrawColor color )
+{
+ DxfArc( d, center, radius, 0.0, 360, FALSE, 0, color );
+}
+
+
+static drawFuncs_t dxfDrawFuncs = {
+ 0,
+ DxfLine,
+ DxfArc,
+ DxfString,
+ DxfBitMap,
+ DxfFillPoly,
+ DxfFillCircle };
+
+static drawCmd_t dxfD = {
+ NULL, &dxfDrawFuncs, 0, 1.0, 0.0, {0.0,0.0}, {0.0,0.0}, Pix2CoOrd, CoOrd2Pix, 100.0 };
+
+static int DoExportDXFTracks(
+ const char * pathName,
+ const char * fileName,
+ void * data )
+{
+ time_t clock;
+ char *oldLocale;
+
+ if (pathName == NULL)
+ return TRUE;
+ SetCurDir( pathName, fileName );
+ dxfF = fopen( pathName, "w" );
+ if (dxfF==NULL) {
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, "DXF", fileName, strerror(errno) );
+ return FALSE;
+ }
+
+ oldLocale = SaveLocale( "C" );
+ wSetCursor( wCursorWait );
+ time(&clock);
+ fprintf(dxfF,"\
+ 0\nSECTION\n\
+ 2\nHEADER\n\
+ 9\n$ACADVER\n 1\nAC1009\n\
+ 9\n$EXTMIN\n 10\n%0.6f\n 20\n%0.6f\n\
+ 9\n$EXTMAX\n 10\n%0.6f\n 20\n%0.6f\n\
+ 9\n$TEXTSTYLE\n 7\nSTANDARD\n\
+ 0\nENDSEC\n\
+ 0\nSECTION\n\
+ 2\nTABLES\n\
+ 0\nTABLE\n\
+ 2\nLTYPE\n\
+ 0\nLTYPE\n 2\nCONTINUOUS\n 70\n0\n\
+ 3\nSolid line\n\
+ 72\n65\n 73\n0\n 40\n0\n\
+ 0\nLTYPE\n 2\nDASHED\n 70\n0\n\
+ 3\n__ __ __ __ __ __ __ __ __ __ __ __ __ __ __\n\
+ 72\n65\n 73\n2\n 40\n0.15\n 49\n0.1\n 49\n-0.05\n\
+ 0\nLTYPE\n 2\nDOT\n 70\n0\n\
+ 3\n...............................................\n\
+ 72\n65\n 73\n2\n 40\n0.1\n 49\n0\n 49\n-0.05\n\
+ 0\nENDTAB\n\
+ 0\nTABLE\n\
+ 2\nLAYER\n\
+ 70\n0\n\
+ 0\nLAYER\n 2\n%s1\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s2\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s3\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s4\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s5\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s6\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s7\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s8\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s9\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nLAYER\n 2\n%s10\n 6\nCONTINUOUS\n 62\n7\n 70\n0\n\
+ 0\nENDTAB\n\
+ 0\nENDSEC\n\
+ 0\nSECTION\n\
+ 2\nENTITIES\n\
+",
+ 0.0, 0.0, mapD.size.x, mapD.size.y,
+ sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper,
+ sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper, sProdNameUpper );
+ DrawSelectedTracks( &dxfD );
+ fprintf(dxfF," 0\nENDSEC\n");
+ fprintf(dxfF," 0\nEOF\n");
+ fclose(dxfF);
+ RestoreLocale( oldLocale );
+ Reset();
+ wSetCursor( wCursorNormal );
+ return TRUE;
+}
+
+
+void DoExportDXF( void )
+{
+ if (selectedTrackCount <= 0) {
+ ErrorMessage( MSG_NO_SELECTED_TRK );
+ return;
+ }
+ if (exportDXFFile_fs == NULL)
+ exportDXFFile_fs = wFilSelCreate( mainW, FS_SAVE, 0, _("Export to DXF"),
+ sDXFFilePattern, DoExportDXFTracks, NULL );
+
+ wFilSelect( exportDXFFile_fs, curDirName );
+}
+
+EXPORT BOOL_T EditCopy( void )
+{
+ FILE * f;
+ time_t clock;
+ char *oldLocale = NULL;
+
+ if (selectedTrackCount <= 0) {
+ ErrorMessage( MSG_NO_SELECTED_TRK );
+ return FALSE;
+ }
+ f = fopen( clipBoardN, "w" );
+ if (f == NULL) {
+ NoticeMessage( MSG_OPEN_FAIL, _("Continue"), NULL, _("Clipboard"), clipBoardN, strerror(errno) );
+ return FALSE;
+ }
+
+ oldLocale = SaveLocale("C");
+
+ time(&clock);
+ fprintf(f,"#%s Version: %s, Date: %s\n", sProdName, sVersion, ctime(&clock) );
+ fprintf(f, "VERSION %d %s\n", iParamVersion, PARAMVERSIONVERSION );
+ ExportTracks(f);
+ fprintf(f, "END\n");
+ RestoreLocale(oldLocale);
+ fclose(f);
+ return TRUE;
+}
+
+
+EXPORT BOOL_T EditCut( void )
+{
+ if (!EditCopy())
+ return FALSE;
+ SelectDelete();
+ return TRUE;
+}
+
+/**
+ * Paste clipboard content. XTrackCAD uses a disk file as clipboard replacement. This file is read and the
+ * content is inserted.
+ *
+ * \return TRUE if success, FALSE on error (file not found)
+ */
+
+EXPORT BOOL_T EditPaste( void )
+{
+ BOOL_T rc = TRUE;
+ char *oldLocale = NULL;
+
+ oldLocale = SaveLocale("C");
+
+ wSetCursor( wCursorWait );
+ Reset();
+ SetAllTrackSelect( FALSE );
+ ImportStart();
+ UndoStart( _("Paste"), "paste" );
+ useCurrentLayer = TRUE;
+ if ( !ReadTrackFile( clipBoardN, sClipboardF, FALSE, TRUE, FALSE ) ) {
+ NoticeMessage( MSG_CANT_PASTE, _("Continue"), NULL );
+ rc = FALSE;
+ }
+ ImportEnd();
+ /*DoRedraw();*/
+ EnableCommands();
+ wSetCursor( wCursorNormal );
+ importMove = TRUE;
+ DoCommandB( (void*)(intptr_t)selectCmdInx );
+ SelectRecount();
+ UpdateAllElevations();
+ RestoreLocale(oldLocale);
+ return rc;
+}
+
+/*****************************************************************************
+ *
+ * INITIALIZATION
+ *
+ */
+
+EXPORT void FileInit( void )
+{
+ const char * pref;
+
+ if ( (libDir = wGetAppLibDir()) == NULL ) {
+ abort();
+ }
+ if ( (workingDir = wGetAppWorkDir()) == NULL )
+ AbortProg( "wGetAppWorkDir()" );
+
+ pref = wPrefGetString( "file", "directory" );
+ if (pref != NULL) {
+ strcpy( curDirName, pref );
+ } else {
+ sprintf( curDirName, "%s%sexamples", libDir, FILE_SEP_CHAR );
+ }
+}
+
+EXPORT BOOL_T ParamFileInit( void )
+{
+ curParamFileIndex = PARAM_DEMO;
+ log_paramFile = LogFindIndex( "paramFile" );
+ if ( ReadParams( lParamKey, libDir, sParamQF ) == FALSE )
+ return FALSE;
+
+ curParamFileIndex = PARAM_CUSTOM;
+ if (lParamKey == 0) {
+ ReadParamFiles();
+ ReadCustom();
+ }
+
+ curPathName[0] = '\0';
+
+ clipBoardN = (char*)MyMalloc( strlen(workingDir) + 1 + strlen(sClipboardF) + 1 );
+ sprintf( clipBoardN, "%s%s%s", workingDir, FILE_SEP_CHAR, sClipboardF );
+ return TRUE;
+
+}