// $Header: /MESHARE/SRC/SESSMGR.S 86    4/17/96 10:42a Todd $

macro_file SessMgr;

/********************************************************************************
															 MULTI-EDIT MACRO FILE

Name: SESSMGR

Description:  The ME Session Manager

	// Session Manager settings
	set_global_int('!@SESSVIEW@!',1);				// default to view names (1=true)
	set_global_int('!@SESSMODMSG@!',0);     // change existing name on exit (1=true)
	set_global_int('!@SESSRSTRMSG@!',1);    // show restore message (1=true)

								(C) Copyright 1994 by American Cybernetics, Inc.
****************************************************************************** */

#ifdef Windows

	#include windows.sh
	#include mew.sh
	#include fprompt.sh
	#include dialog.sh
	#include mewlist2.sh
	#include metools.sh
	#include mewlogo.sh
	#include mewlib.sh
	#include TEMPLATE.SH
	#include MEWHELP.SH
  #include STDDLGS.SH

  #ifdef _Debug_
    #include MSGLOG.SH
  #endif

  #define SESSMGR_HELPLINK      "SESSION MANAGER"
  #define SESMGRSETUP_HELPLINK  "SESSION MANAGER SETUP"

//  #include mew.sh  There is a redundant global declaration in here so we do this instead
prototype mew
{
	void ProcessMEWInit ();
}
#else
	#include selctdir.sh
#endif

// we need the prototypes for calls to macros within exit.s
#include EXIT.SH

global {
  int Session_Names_Number;
  int Sm_Active_Win_Id;
  int Sm_Ignore_En_Change;
}

#IFDEF windows
#DEFINE _SESSION_EXTENSION  ".MEW"
#define ME_VERSION_LENGTH   34            // actual - 1 (major + .)
#DEFINE ME_VERSION_TEXT     "@MULTI-EDIT FOR WINDOWS VERSION "
#ELSE
#DEFINE _SESSION_EXTENSION  ".ME"
#define ME_VERSION_LENGTH   22            // actual - 1 (major + .)
#DEFINE ME_VERSION_TEXT     "@MULTI-EDIT VERSION "
#ENDIF

// to remember what  restore=3  is
#defIne ENCODED_FILES_MODE  3
#define IN_ENCODED_MODE     (global_int('@RESTORE')==ENCODED_FILES_MODE)

#define SM_NAME_TITLE       "Session Manager"
#define SM_NAME_VIEW_BTN    "&View Dir Sessions"
#define SM_DIR_TITLE        "Session Manager -(Directory Sessions)"
#define SM_DIR_VIEW_BTN     "&View Named Sessions"

#define Sm_Name_Title_Ctrl  701
#define Sm_Name_Ctrl        702
#define Sm_Dir_Title_Ctrl   703
#define Sm_Dir_Ctrl         704
#define Sm_List_Ctrl        600
#define Sm_Accept_Ctrl      800
#define Sm_Browse_Ctrl      801
#define Sm_Create_Ctrl      802
#define Sm_Delete_Ctrl      803
#define Sm_Update_Ctrl      804
#define Sm_Setup_Ctrl       805
#define Sm_Sort_Ctrl        806
#define SM_Oem_Ctrl         807
#define Sm_Ok               1001
#define Sm_Cancel           1002
#define Sm_Help             1003
#define Sm_Box1             650
#define Sm_Box2             651
#define Sm_Box3             652
#define Sm_Str1             653
#define Sm_Str2             654
#define Sm_Bitmap           655
#define id_sm_ProtectBtn    1100

/******************** Multi-Edit VOID Macro Function ************************

 NAME:         cantdelete()

 DESCRIPTION:  notify the user that they cant delete the session that
							 they are currently working in from the session list

 PARAMETERS:	 None.

 RETURNS:			 None.

*****************************04-05-93 04:20pm*******************************/

void cantdelete()
{
	int  menu = menu_create ;
	menu_set_item( menu, 1, 'From the SESSION MANAGER: ','','/L=3/C=3',10,0, 0);
	menu_set_item( menu, 2, 'You may not delete the current','','/L=5/C=3',10,0, 0);
	menu_set_item( menu, 3, 'session that you are working on.','','/L=6/C=3',10,0,0);
	menu_set_item( menu, 4, 'Select another session.','','/L=8/C=3',10,0,0);

	return_int = menu;
#ifdef WINDOWS
	RM('UserIn^Data_In /HN=1/A=1/#=4/T=Warning/H=' + SESSMGR_HELPLINK);
#else
	RM('UserIn^Data_In /HN=1/H=*/A=1/#=4/T= Warning ');
#endif

	menu_delete( menu );
}

int check_dir(str dir_spec) {
/*
Checks to see if dir_spec exists, and allows the user to create it
*/
	int ret_value = true,
			root_flag = false;

// special check for root directory
	if (xpos("\\",fix_dir_spec(dir_spec),1) ==
			length(fix_dir_spec(dir_spec))) {

    struct WIN32_FIND_DATA new_fd;
    struct DOS_FIND_DATA old_fd;

    int find_handle = FindFirstFile( fix_dir_spec(dir_spec) + "*.*",
                                &new_fd, &old_fd);
    root_flag = (find_handle != 0);
    if(find_handle)
      FindClose(find_handle);
	}

	if ((((file_exists(dir_spec)) && (file_attr(dir_spec) & 0x10)) ||
			(dir_spec == "")) || (root_flag)) {
		ret_value = true;
	} else {

		RM("USERIN^VERIFY /BL=" + dir_spec + "/T=Directory does not exist. Create?");
		if (return_int) {
			int DOS_Error = MKDIR(dir_spec);
			if (DOS_Error == 0) {
				ret_value = True;
			} else {
				RM("MEERROR^MESSAGEBOX /B=1/M=Error #" + str(DOS_Error) +
						" while attempting to create the directory: " + dir_spec);
				ret_value = False;
			}
		}
	}
	return(ret_value);
}

void SM_CONFIGURE() {
/*
The configuration dialog box for the session manager.  Called from
the MEW customize dialog.
*/
	int dlg;
	int restore_mode = global_int("@RESTORE");

	DlgCreate( dlg );

	DlgAddCtrl( dlg, DLG_BitmapStatic, "BT_GN_121",1,1,0,0,150,0,"");

  DlgAddCtrl( dlg, DLG_GroupBox, 'Restore status method',10, 1, 41, 5, 2002, 0, "" );

	DlgAddCtrl( dlg, DLG_RadioButton, '&No status saved',DLG_PosOffset + 1,DLG_PosOffset + 1,0,0,1100,0,"");
	DlgSetInt( dlg, 1100, restore_mode == 0);

	DlgAddCtrl( dlg, DLG_RadioButton, '&Status file in each dir',DLG_PosOffset,DLG_PosOffset + 1,0,0,1101,0,"");
	DlgSetInt( dlg, 1101, restore_mode == 1);

	DlgAddCtrl( dlg, DLG_RadioButton, 'One &global status file',DLG_PosOffset,DLG_PosOffset + 1,0,0,1102,0,"");
	DlgSetInt( dlg, 1102, restore_mode == 2);

	DlgAddCtrl( dlg, DLG_RadioButton, '&Encoded status files for each dir',DLG_PosOffset,DLG_PosOffset + 1,0,0,1103,0,"");
	DlgSetInt( dlg, 1103, restore_mode == 3);


	DlgAddCtrl( dlg, DLG_Static, 'Stat&us file path:',1,DLG_PosOffset + 2,0,0,2003,0,"");
	DlgAddCtrl( dlg, DLG_Text, global_str("@RESTORE_PATH"),DLG_PosOffset + 18,DLG_PosOffset,32,0,1104,0,"/ML=128");

  DlgAddCtrl( Dlg, Dlg_GroupBox, "Options",
      1, Dlg_PosOffset + 1,
      50, 4,
      1300, 0, "" );

  DlgAddCtrl( Dlg, dlg_Checkbox, "&Restore screen position on startup",
      DLG_PosOffset + 1, DLG_PosOffset + 1,
      0, 0,
      1105, 0, "" );
	DlgSetInt( dlg, 1105, Restore_Flags & _REST_SCREEN_POS );

/*
	DlgAddCtrl( dlg, DLG_Checkbox, 'Restore &tool bars from session to session',DLG_PosOffset,DLG_PosOffset + 1,0,0,1106,0,"");
	DlgSetInt( dlg, 1106, Restore_Flags & _REST_TOOL_BARS );
*/
  DlgAddCtrl( Dlg, dlg_Checkbox, "Use &current session when creating",
      DLG_PosOffset, DLG_PosOffset + 1,
      0, 0,
      1107, 0, "" );
  DlgSetInt( Dlg, 1107, !Global_Int( "~SESSION_NEW_EMPTY" ) );

  DlgAddCtrl( Dlg, dlg_Checkbox, "Save named sessions &only",
      dlg_PosOffset + 0, dlg_PosOffset + 1,
      0, 0,
      1108, 0, "" );
  DlgSetInt( Dlg, 1108, ( Restore_Flags & _rest_SavNamedOnly ) != 0 );

	DlgAddCtrl( dlg, DLG_PushButton, "OK",1,DLG_PosOffset + 2,Dlg_StanBtnWidth,0,100,DLGF_DefButton,"/R=1");
	DlgAddCtrl( dlg, DLG_PushButton, "Cancel",DLG_PosOffset  + Dlg_StanBtnWidth + 2,DLG_PosOffset,Dlg_StanBtnWidth,0,101,0,"/R=0");
	DlgAddCtrl( dlg, DLG_PushButton, "&Help",42,DLG_PosOffset,Dlg_StanBtnWidth,0,102,0,"/R=2");

  if(DlgExecute( dlg, 100, "Restore, Session Manager Setup", SESMGRSETUP_HELPLINK, "", 0 ))
	{
		Set_Global_Int('SETUP_CHANGED',Global_Int('SETUP_CHANGED') | $01);

		// Setup restore options
		restore_mode = 0;
		if( DlgGetInt(dlg,1101))
		{
			restore_mode = 1;
		}
		else if ( DlgGetInt(dlg,1102) )
		{
			restore_mode = 2;
		}
		else if ( DlgGetInt(dlg,1103) )
		{
			restore_mode = 3;
		}
		set_global_int( "@RESTORE", restore_mode );
		set_global_str("@RESTORE_PATH", DlgGetStr(dlg,1104) );
    Restore_Flags &= -1 ^ _rest_Mask;
    Restore_Flags |= DlgGetInt( Dlg, 1105 ) |
        ( DlgGetInt( Dlg, 1108 ) * _rest_SavNamedOnly );

 //		restore_flags = (restore_flags & 0xFD) | (DlgGetInt(dlg, 1106) << 1);

		Set_Global_Int('~SESSION_NEW_EMPTY',!DlgGetInt(dlg,1107));
	}
	DlgKill( dlg );
	return_int = 0;
}

void Sm_Put_List_Data( str S_Name, str S_Dir, int ReadOnly )
/* This macro assumes the session manager list window is active
   and your cursor is already on the desired line in the list window
*/
{
  str Line = "\x7F" + "NAME=" + S_Name + "\x7F" + "DIR=" + S_Dir;

  if ( ReadOnly ) {
    Line += "\x7F" + "I=WINDOW_READONLY";
  }
  Put_Line( Line );
  return ( );

}  // Sm_Put_List_Data

void Sm_Get_List_Data( str &SName, str &SDir, int &ReadOnly ) {
/*
  This macro assumes the session manager list window is active
  and your cursor is already on the desired line
*/

  SName = Parse_Str( "\x7F" + "NAME=", Get_Line( ) );
  SDir = Parse_Str( "\x7F" + "DIR=", Get_Line( ) );
  ReadOnly = Parse_Str( "\x7F" + "I=", Get_Line( ) ) != "";

}  // Sm_Get_List_Data

void Sm_Do_Sort( int List_hWnd )
/*
  Sorts the session manager session list.  It is assumed that the
  current MEW window is the list.
*/
{
  int t_window_id = window_id,
      list_win_id,
      list_win_num,
      sort_win_id = 0,
      sort_win_num,
      numlines,
      current_selection,
      selection_set = 0,
      ascend = !Global_int("!SESS_SORT_DESCEND"),
      by_dir = Global_int("!SESS_SORT_BY_DIR") * 80,
      t_int;

  List_Win_Id = Window_Id;
  List_Win_Num = Cur_Window;

  Switch_Window( Window_Count );
  Create_Window;
  Sort_Win_Id = Window_Id;
  Sort_Win_Num = Cur_Window;
  File_Name = "SESSSORT.TMP";

  Switch_Win_Id( List_Win_Id );
  Current_Selection = C_Line;
  Tof;
  while ( !At_Eof ) {
    Put_Line_To_Win(
      copy(parse_str("NAME=",get_line) +
"                                                                              ",
      1, 80) +
      copy(parse_str("DIR=",get_line) +
"                                                                              ",
      1, 80) +
      "LINE#=" + Str( C_Line ) + "\x7F\xFE" + "DAT=" + Get_Line( ),
      C_Line,
      Sort_Win_Num,
      0
    );
    down;
  }

  // clear out existing stuff in list window
  Numlines = C_Line - 1;
  Block_Begin;
  Tof;
  Delete_Block;

  // sort temporary list
  Switch_Win_Id( Sort_Win_Id );
  Qsort_Lines( 1, Numlines, Ascend, By_Dir + 1, 80, 1 );

  // rebuild list using sort results
  for ( T_Int = 0; T_Int < NumLines; ++t_Int ) {
    if ( List_Hwnd ) {
      SendMessage( list_hwnd, LB_DELETESTRING, 0, 0 ); // delete selections
    }
    if ( !Selection_Set ) {
      if ( Parse_Int( "LINE#=", Get_Line( ) ) == Current_Selection ) {
        Selection_Set = True;
        Current_Selection = C_Line;
      }
    }
    Put_Line_To_Win( Parse_Str( "\xFE" + "DAT=", Get_Line( ) ),
//      "NAME=" + shorten_str(copy(get_line, 1, 80)) +
//      "DIR=" + shorten_str(copy(get_line, 81, 80)),
      c_line,
      list_win_num,
      0
    );
    down;
  }

  // tell windows how many new selections there are
  if (list_hwnd) {
    for (t_int = 0; t_int < numlines; ++t_int) {
      SendMessage( list_hwnd, LB_ADDSTRING, 0, 0 );
    }
  }


  if (switch_win_id(sort_win_id)) {
    delete_window;
  }

  switch_win_id(list_win_id);
  goto_line(current_selection);
  if (list_hwnd) {
    sendmessage( list_hwnd, LB_SETCURSEL, c_line - 1, 0);
  }
  switch_win_id(t_window_id);
}

void Sm_Sort_List( ) {
/*
  The dialog box for sorting the session list
*/
  int result,
      dlg;

  DlgCreate(dlg);

  DlgAddCtrl( Dlg, dlg_GroupBox, "Sort Order",
      1, 1,
      17, 3,
      2001, 0, "" );

	DlgAddCtrl( dlg, DLG_RadioButton,
              "&Ascending",
              DLG_PosOffset | 1,
              DLG_PosOffset | 1,
							0,
							0,
              2002,
							0,
							"");
  DlgSetInt(dlg, 2002, !Global_Int("!SESS_SORT_DESCEND"));

	DlgAddCtrl( dlg, DLG_RadioButton,
              "&Descending",
              Dlg_PosOffset,
              Dlg_PosOffset | 1,
							0,
							0,
              2003,
							0,
							"");
  DlgSetInt(dlg, 2003, Global_Int("!SESS_SORT_DESCEND"));

  DlgAddCtrl(dlg, DLG_GroupBox,
              "Sort By",
              21,
              1,
              14,
              3,
              2005,
              0,
              "");

	DlgAddCtrl( dlg, DLG_RadioButton,
              "&Name",
              DLG_PosOffset | 1,
              DLG_PosOffset | 1,
							0,
							0,
              2006,
							0,
							"");
  DlgSetInt(dlg, 2006, !Global_Int("!SESS_SORT_BY_DIR"));

	DlgAddCtrl( dlg, DLG_RadioButton,
              "&Directory",
              Dlg_PosOffset,
              Dlg_PosOffset | 1,
							0,
							0,
              2007,
							0,
							"");
  DlgSetInt(dlg, 2007, Global_Int("!SESS_SORT_BY_DIR"));

  DlgAddCtrl( dlg, DLG_PushButton, "OK",
    1, 5,
    DLG_StanBtnWidth, 0, SM_OK, 0, "/R=1");

  DlgAddCtrl( dlg, DLG_PushButton, "Cancel",
    DLG_PosOffset+DLG_StanBtnWidth+2, DLG_PosOffset,
    DLG_StanBtnWidth, 0, SM_Cancel, 0, "/R=0");

  DlgAddCtrl( dlg, DLG_PushButton, "&Help",
    26, DLG_PosOffset,
    DLG_StanBtnWidth, 0, SM_HELP, 0, "/R=2");

  result = DlgExecute( dlg, SM_OK, "Sort Sessions", SESSMGR_HELPLINK, "", 0);

  if (result) {

    Set_Global_Int("!SESS_SORT_DESCEND", DlgGetInt(dlg, 2003));
    Set_Global_Int("!SESS_SORT_BY_DIR" , DlgGetInt(dlg, 2007));

    RM("SETUP^SETSAVE");

    Sm_Do_Sort( GetDlgItem(parse_int("/DLGHANDLE=",mparm_str), SM_list_ctrl));
  }
  DlgKill( Dlg );
  SetFocus( GetDlgItem( Parse_Int( "/DLGHANDLE=", MParm_Str ), sm_List_Ctrl ) );

}  // Sm_Sort_List

int Sm_Make_List( int Session_Names_Id, str old_sess_name ) trans
/****************** Multi-Edit INTEGER Macro Function ***********************

 NAME:         sm_make_list(session_list_id)

 DESCRIPTION:  Creates a new window and builds of a list of the directories
							 currently covered by encoded status files.
							 Leaves the cursor on the line for the current directory.


 PARAMETERS:   session_list_id, the window on which to create the file list

 RETURNS:      the length of the longest line in the file list

 ----------------------------------------------------------------------------
 MODIFICATIONS
 ----------------------------------------------------------------------------
 040893[scm]: while creating the list of sessions, the authenticity of the
							status files is kept by checking the existence of the
							directories that the encoded status files refer to.
							If the directory does not exist, the status file is deleted.

 091093[scm]:	actually delete the status file / thx2 jeff fontanesi


 063094[tmj]: conditionally compile for DOS or Windows
							add Windows support

 081194[scm]: add support for 'named' sessions
							For EncodedStatusFiles mode only, the user can view
							the session list either by directory name or by a
							useful description of the edit session.

*****************************04-05-93 04:06pm*******************************/
{
	str fn[128] = make_restr_name( ENCODED_FILES_MODE,"");	// restore file for current dir
	str curfn[128] = fn;
	str buf;
	str bff,bff2,bfname;
	int tfile_search_attr = file_search_attr;
	int sresult,hn,jx,jy,jz1,jz2, tx, fexists;
	int SV_Refresh = refresh;
	int cline_pos;
  int FileReadOnly;

  struct WIN32_FIND_DATA new_fd;
  struct DOS_FIND_DATA old_fd;
  int find_handle;

	refresh = false;

	// 082493[scm]
	// display 'search in progress
#IFDEF WINDOWS
	make_message('Searching for all sessions...');
	working;
#ELSE
	Put_Box(13, 8, 50, 11, LIGHTGRAY, BLACK, '', TRUE);
	Write('Searching for All Sessions...',16,9,LIGHTGRAY,BLACK);
#ENDIF

	// Find first file in list
	str sext = _SESSION_EXTENSION;
  find_handle = FindFirstFile(get_path(fn) + '*'+ _SESSION_EXTENSION,
                            &new_fd, &old_fd );

  if ( find_handle ) {
		// As long as dos is returing 0, loop
    do {
      FileReadOnly = File_Attr( Get_Path( Fn ) + New_Fd.cFileName ) & 0x01;
      Error_Level = 0;
      // Open the file up
      if ( !S_Open_File( Get_Path( Fn ) + New_Fd.cFileName, 0x20, Hn ) ) {
        // read the first 250 bytes
        if ( !S_Read_Bytes( Buf, Hn, 250 )) {

          tx = xpos("\r",buf,1); // make sure we have only 1 line
          buf = copy(buf,1,tx - 1);

            // check to see if it is a valid restore file
          if(copy(buf, 1, ME_VERSION_LENGTH) == (ME_VERSION_TEXT  + Copy(version,1,2)))
          {
              bfname = parse_str("SESS_BY_NAME=",buf);
              if (svl(bfname)) {
                switch_win_id(session_names_id);
                Sm_Put_List_Data( BFName, Parse_Str( "SESS_HOME_DIR=", Buf ),
                    FileReadOnly );
                down;
              }
          }
        }
        s_close_file(hn);
      }
    } while( FindNextFile( Find_Handle, &New_Fd, &Old_Fd ) );
    FindClose(find_handle);
  }

	// 0842493[scm]
	// kill the 'searching...' box
#IFDEF WINDOWS
	make_message('');
#ELSE
	Kill_Box;
#ENDIF

	up;         // Sort the list and name list
	qsort_lines( 1, c_line,1, 1, 2048, 0 );

	switch_win_id(session_names_id);
	up;
	qsort_lines( 1, c_line,1, 150, 2048, 0);
	tof;

	file_search_attr = tfile_search_attr;

	tof;
// find current named session list
  if (!svl(old_sess_name)) {
    old_sess_name = global_str("!SESSION_NAME");
  }
  find_text("NAME=" + old_sess_name + "", 0, 0)

	goto_col(1);

	refresh = SV_Refresh;

	return (64);

}

void Sm_Set_Ctrls( hDlg ) {
/*
  This macro sets values in all the dialog box controls according to
  the current selection.  Run primarily via the hook macro
*/

  SM_ignore_en_change = True; // tell hook proc not to enable the accept button

  Switch_Window( Session_Names_Number );

  str SName;
  str SDir;

  int ReadOnly;
  int ItemCnt = SendDlgItemMessage( hDlg, sm_List_ctrl, LB_GETCOUNT, 0, 0 );

  Sm_Get_List_Data( SName, SDir, ReadOnly );
  SetDlgItemText( hDlg, sm_Name_Ctrl, SName);
  SetDlgItemText( hDlg, sm_Dir_Ctrl, SDir);

  EnableWindow( GetDlgItem( hDlg, sm_Update_Ctrl ), !ReadOnly );

  if ( ReadOnly ) {
    SetDlgItemText( hDlg, id_sm_ProtectBtn, "un&Protect" );
  }
  else {
    SetDlgItemText( hDlg, id_sm_ProtectBtn, "&Protect" );
  }
  EnableWindow( GetDlgItem( hDlg, sm_Name_Ctrl ), ItemCnt );
  EnableWindow( GetDlgItem( hDlg, sm_Name_Title_Ctrl ), ItemCnt );
  EnableWindow( GetDlgItem( hDlg, sm_Dir_Ctrl ), ItemCnt );
  EnableWindow( GetDlgItem( hDlg, sm_Dir_Title_Ctrl ), ItemCnt );
  EnableWindow( GetDlgItem( hDlg, sm_Browse_Ctrl), ItemCnt );
  EnableWindow( GetDlgItem( hDlg, sm_Ok ), ItemCnt );

  if ( ItemCnt ) {
    SetDefaultButton( hDlg, sm_Ok );
	}
  else {
    SetDefaultButton( hDlg, sm_Create_ctrl );
  }
  EnableWindow( GetDlgItem( hDlg, sm_Accept_Ctrl ), False );
  sm_Ignore_En_Change = False;


}  // Sm_Set_Ctrls

void Sm_Delete(
			int List_Win = Parse_Int( "/LW=", MParm_Str ),
			int Name_Win = Parse_Int( "/NW=", MParm_Str )
)
/******************** Multi-Edit VOID Macro Function ************************

 NAME:         sm_delete()

 DESCRIPTION:  Run by SM_DIALOG when the Del button is pressed

*****************************04-18-93 01:09pm*******************************/
{
	int CurWin = Cur_Window;
	int CLPos = C_Line;

#ifdef Windows
	int Dialog_Handle = Parse_Int( "/DLGHANDLE=", MParm_Str );
	int ListBox_Id    = Parse_Int( "/LB=", MParm_Str );
	int List_hWnd 		= GetDlgItem( Dialog_Handle, Listbox_Id );
	int Jx, Record_Count;
	int Currentlbsel;
#endif

	str S_Name, S_Dir;
	str TStr1;

	Switch_Window( Name_Win );
	Goto_Line( CLPos );

	Goto_Col( 1 );
  Sm_Get_List_Data( TStr1, S_Dir, Jx );

	if ( TStr1 == Global_Str( "!Session_Name" ) ) {
		CantDelete( );
	}
	else {

#ifdef Windows
    Return_Int = VerifyDlg( "Delete \"" + TStr1 + "\"?", "", sessmgr_HelpLink,
        id_std_Yes, 0 ) == id_std_Yes;
#else
    Rm( "USERIN^Verify /H=PROMPTS/BL=Confirm/T=Delete \""+ TStr1 + "\"?" );
#endif

    if (Return_Int) {
        // Delete the encoded file
        TStr1 = Make_Restr_Name( ENCODED_FILES_MODE, "0:" + TStr1 ) + ".MEW";
        Del_File( TStr1 );

        // Delete the line from the session list
        CurrentLBSel = C_Line - 1;
        Del_Line;

        if ( At_Eof ) {
          Up;
        }
        mark_pos;
        eof;
        record_count = c_line;
        goto_mark;

#ifdef Windows
        // Reset list
        Jx = SendMessage( list_hwnd, LB_GETCURSEL, 0, 0 );
        SendMessage( list_hwnd, LB_DELETESTRING, jx, 0 );
        --jx;
        sendmessage( list_hwnd, LB_SETCURSEL, c_line - 1, 0);
        // Redraw list
        RedrawWindow( list_hwnd, 0, 0, rdw_Invalidate );
        Sm_Set_Ctrls( Dialog_Handle );
        // Set the focus back to the list window
        SetFocus( List_hWnd );
#endif
    }
	}
  Return_Int = 0;
  Goto_Col(1);
  Redraw;
	Return_Int = 0;

}  // Sm_Delete

int Sm_Check_Name( str S_Name, int Line_Num )
// checks for naming conflicts.  assumes you are already in the
// list box window.  returns 0 if there is a conflict
{
	int Return_Value = 1;
	str T_Name;

	Mark_Pos;
	Tof;
	while ( !At_Eof ) {
		if ( ( C_Line != Line_Num /* this prevents looking at existing line */)
				&& ( Caps( Fix_Cmd_Param( S_Name ) ) ==
				Caps( Fix_Cmd_Param( Parse_Str( "NAME=", Get_Line( ) ) ) ) ) ) {
			Return_Value = 0;
			t_name = parse_str("NAME=",get_line);
		}
		down;
	}
	Goto_Mark;

	if (return_value == 0) {
		RM("MEERROR^MESSAGEBOX /B=1/T=Name Conflict/M=The session name '" +
				s_name +
				"' will create a status file of the same name as the existing session '" +
				t_name + "'.");
	}
	return ( Return_Value );

}  // Sm_Check_Name

void Sm_Update( )
/*
  Updates the status file for the currently selected session according
  to the current editor conditions
*/
{
  int hDlg = Parse_Int( "/DLGHANDLE=", Mparm_Str );
  int Cur_List_Window;
  int Active_Window = window_id;
  int ReadOnly;

  str SName;
  str SDir;
  str Cur_Sess_Name = Global_Str( "!SESSION_NAME" );

  Cur_List_Window = SendDlgItemMessage( hDlg, sm_List_Ctrl, WM_ML2_GETLISTBUF, 0 ,0);
  Switch_Window( Cur_List_Window );
  Sm_Get_List_Data( SName, SDir, ReadOnly );
  Set_Global_Int( "Oem_mode",
      SendDlgItemMessage( hDlg, SM_OEM_CTRL, BM_GETCHECK, 0, 0 ) );

  // run status to replace the current status file for this session
  Set_Global_Str( "!Session_Name", SName );
  Switch_Win_Id( Sm_Active_Win_Id );
  Rm( "Status" );
  Set_Global_Str( "!Session_Name", Cur_Sess_Name );

  Switch_Window( Cur_List_Window );
  Sm_Put_List_Data( SName, FExpand( "" ), ReadOnly );

  // Get list window handle
  hDlg = GetDlgItem( hDlg, sm_List_Ctrl );
  RedrawWindow( hDlg, 0, 0, RDW_INVALIDATE);
  // Set the focus back to the list window
  SetFocus( hDlg );

  Switch_Win_Id(active_window);
  Return_Int = 0;

}  // Sm_Update

void Sm_New( )
/*
  Creates a new session including a status file and a new
  selection in the list
*/
{
	int hDLG = Parse_Int( "/DLGHANDLE=", MParm_Str ),
			Cur_List_Window,
			hList,
//			item_count,
			T_Insert_Mode = Insert_Mode,
			Active_Window = Window_Id;

	str S_Dir,
			Cur_Path = FExpand( "" ),
			Cur_Sess_Name = Global_Str( "!Session_Name" );

	Cur_List_Window = SendDlgItemMessage( hDlg, sm_List_Ctrl, WM_ML2_GETLISTBUF, 0 ,0 );
	Switch_Window( Cur_List_Window );

	if ( Sm_Check_Name( "(no name)", 0 ) ) {
		// run STATUS so we have a session file to work with
		Set_Global_Str( "!Session_Name", "(no name)" );
		Switch_Win_Id( Sm_Active_Win_Id );
		Rm( "Status /NEW=" + Str( Global_Int( "~Session_New_Empty" ) ) );

		Set_Global_Str( "!Session_Name", Cur_Sess_Name );

		Switch_Window( Cur_List_Window );
		Goto_Col( 1 );
		if ( !At_Eof ) {
			Eol;
			Insert_Mode = TRUE;
			Cr;
		}

    Sm_Put_List_Data( "(no name)", FExpand( "" ), 0 );
		Insert_Mode = T_Insert_Mode;

		SendMessage( GetDlgItem(hdlg, SM_list_ctrl), WM_SETREDRAW, 0, 0);
		SendMessage( GetDlgItem(hdlg, SM_list_ctrl), LB_ADDSTRING, 0, 0);
		sendmessage( GetDlgItem(hdlg, SM_list_ctrl), LB_SETCURSEL, c_line - 1, 0);
		SendMessage( GetDlgItem(hdlg, SM_list_ctrl), WM_SETREDRAW, 1, 0);
		SendMessage( GetDlgItem(hdlg, SM_list_ctrl), WM_ML2_REDRAW, 0, 0);
	}
	sm_set_ctrls(hdlg);
	SetFocus(GetDlgItem(hdlg, SM_name_ctrl));
	// this highlights the text in the name control
  SendMessage(GetDlgItem(hdlg, SM_name_ctrl), EM_SETSEL, 0, 0xFFFF0000);

	switch_win_id(active_window);
	return_int = 0;
}

void Sm_Accept( ) {
/*
  Run by the accept button.  Updates the controls and creates or
  updates the status file to reflect the changes.
*/
	int hDLG = parse_int("/DLGHANDLE=",mparm_str),
			cur_list_window;
  int ReadOnly;

	str old_s_name,
			cur_sess_name = global_str("!SESSION_NAME"),
			cur_path = fexpand(""),
			old_s_dir,
			new_s_name,
			new_s_dir;

	cur_list_window = SendDlgItemMessage(hdlg, SM_list_ctrl, WM_ML2_GETLISTBUF, 0 ,0);
	switch_window(cur_list_window);
	GetDlgItemText(hdlg, SM_name_Ctrl, new_s_name, 128);
	GetDlgItemText(hdlg, SM_dir_ctrl, new_s_dir, 128);
  new_s_dir = fexpand(new_s_dir);  // JKP 7/27/95 5:52PM


  if (Check_Dir(fix_dir_spec(new_s_dir))) {
    if (Sm_Check_Name(new_s_name,c_line)) {
      Sm_Get_List_Data( Old_S_Name, Old_S_Dir, ReadOnly );
      // rename the staus file if they changed the session name
      int dos_error = 0;
      if (old_s_name != new_s_name) {
        dos_error = rename_file(
            make_restr_name( ENCODED_FILES_MODE,"0:" + old_s_name) + ".MEW",
            make_restr_name( ENCODED_FILES_MODE,"0:" + new_s_name) + ".MEW"
            );
      }
      if (dos_error == 0) {
        create_window;
        // load the status file and change the name and home directory
        load_file(make_restr_name( ENCODED_FILES_MODE,"0:" + new_s_name) + ".MEW");
        if (!search_fwd("",1)) {
          eol;
        }
        str t_str = copy(get_line,1,c_col - 1);
        put_line(t_str +
            "SESS_BY_NAME=" + new_s_name +
            "SESS_HOME_DIR=" + new_s_dir
            );
        save_file;
        delete_window;

      } else {
  // if we get here it is probably because we did not have an existing
  // status file to rename.  Create one from scratch by running STATUS.

        set_global_str("!SESSION_NAME",new_s_name);
        change_dir(fix_dir_spec(new_s_dir));
        RM("STATUS");
        change_dir(fix_dir_spec(cur_path));
        error_level = 0;
        set_global_str("!SESSION_NAME",cur_sess_name);
      }
  // change the stuff in the list box
      switch_window(cur_list_window);

      Sm_Put_List_Data( New_S_Name, New_S_Dir, 0 );

      SetFocus(GetDlgItem(hdlg, SM_list_ctrl));
      RedrawWindow(GetDlgItem(hdlg, SM_list_ctrl), 0, 0, RDW_INVALIDATE);
      SetDefaultButton(hdlg,SM_OK);
      EnableWindow(GetDlgItem(hdlg, SM_accept_ctrl), False);
		} else {
			SetFocus(GetDlgItem(hdlg, SM_name_ctrl));
		}
	}

	if (new_s_name == cur_sess_name) {
		if (fix_dir_spec(cur_path) != fix_dir_spec(new_s_dir)) {
			change_dir(fix_dir_spec(new_s_dir));
		}
	}
	return_int = 0;

}  // Sm_Accept

void Sm_Browse( )
/*
  Activated by the browse button.  Invokes that directory list
  common dialog to select a home directory.
*/
{
	int hdlg = parse_int("/DLGHANDLE=",mparm_str),
      dlg = parse_int ("/DATAHANDLE=",mparm_str);
	str s_dir;

	GetDlgItemText(hdlg, SM_Dir_Ctrl, s_dir, 128);

	if (SelectDirectory( hdlg,            // int parent,
												s_dir,                      // str &fn,
												"Select a home directory", // str title,
												"SESSMGRNEWDIR",          // str help,
												0                         // int flags
											)
      )
  {
    SetFocus (GetDlgItem(hdlg, SM_dir_ctrl));
		DlgSetStr(dlg, SM_Dir_ctrl, s_dir);
		SetWindowText(GetDlgItem(hdlg, SM_dir_ctrl), s_dir);
		SendDlgItemMessage(hdlg, SM_browse_ctrl, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
		SendDlgItemMessage(hdlg, SM_accept_ctrl, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
	}
	return_int = 0;
}

void SmProtectSession( )
/******************************************************************************
                               Multi-Edit Macro
                               21-Feb-96  18:01

  Function: `description`
  Entry   : `entry`
  Exit    : `exit`

               Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
  int hDlg = Parse_Int( "/DLGHANDLE=", MParm_Str );

  if ( hDlg ) {

    int ActiveWin  = Window_Id;
    int SavRefresh = Refresh;
    int ListWin;
    int ReadOnly;

    str SName;
    str SDir;
    str FName;

    Refresh = False;
    ListWin = SendDlgItemMessage( hDlg, sm_List_Ctrl, WM_ML2_GETLISTBUF, 0 ,0 );

    Switch_Window( ListWin );
    Sm_Get_List_Data( SName, SDir, ReadOnly );

    FName = "0:" + SName;
    FName = Make_Restr_Name( Global_Int( "@Restore" ), FName ) + ".MEW";

    ReadOnly = File_Attr( FName );
    if ( !Error_Level ) {
      if ( ReadOnly & 0x01 ) {
        ReadOnly &= 0xFF ^ 0x01;
      }
      else {
        ReadOnly |= 0x01;
      }
      Set_File_Attr( FName, ReadOnly );
    }
    Error_Level = 0;
    Sm_Put_List_Data( SName, SDir, ReadOnly & 0x01 );
    Sm_Set_Ctrls( hDlg );
    // Get list window handle
    hDlg = GetDlgItem( hDlg, sm_List_Ctrl );
    RedrawWindow( hDlg, 0, 0, RDW_INVALIDATE);
    // Set the focus back to the list window
    SetFocus( hDlg );

    Switch_Win_Id( ActiveWin );
    Refresh = SavRefresh;
  }
  Return_Int = 0;

}  // SmProtectSession

str Sm_Dialog(
			int Longest_Line_Length,
			int Session_Names_Id,
			int Session_Names_Number
) trans
/****************** Multi-Edit INTEGER Macro Function ***********************

 NAME:         sm_dialog

 DESCRIPTION:  the dialog box from which the user selects sessions
							 the user can insert new sessions, delete sessions from
							 the list, select a session from the list, or escape.

 PARAMETERS:   int longest_line_length
									Used to evenly display the session list
							 int session_list_id,
									The window where the list has been built
							 int session_list_number,
									The number of the window where the list has been built
									Used by the dialog box /WIN parameter (where's the list?)


 RETURNS:      Directory name of session selected, or "" if ESC was hit.

*****************************04-05-93 04:22pm*******************************/
{

#ifdef Windows

	int Active_Window = Window_Id;
	int T_Insert_Mode = Insert_Mode;
	int T_Refresh 		= Refresh;
	int cc 						= longest_line_length;		// cc vars used for box
	int ll;
	int Dlg;

	str S_Dir;
	str S_Name = "";
	str sessname[80];
	str cursessname[80];
	str cursesspath[80];
	str cursessid[80];
	str otherstr[40],
			titlestr[40],
			result_str;

	int svwinid;
	int mh;
	int ctrl_style, Create_style, Select_style;
	int viewoffset=0;
	int cline_pos;
	int session_view_win;
	int lll;
	int dfltitem = 1,
			new_flag = 0;
	int dlgidCurrentSession;
	int dlgidToggleView;
	int Result;
  int ReadOnly;

	refresh=false;

	dfltitem=6;
	sessname = global_str("!SESSION_NAME");
	cursessname = sessname;
	ctrl_style = 0;
	Create_style = 0;
	Select_style = DLGF_Defbutton;
	otherstr = SM_NAME_VIEW_BTN;
	titlestr = SM_NAME_TITLE;
	session_view_win = session_names_number;

	// This will get the length to determine if we need a HSCROLL Bar.
  switch_window(session_view_win);

	// while we're at it, sort the list
  Sm_Do_Sort( 0 );

	int maxlength = 0;
	mark_pos;
	tof;
	while ( !at_eof ) {
		if ( length(parse_str("DIR=", get_line) ) > maxlength) {
			maxlength = length(parse_str("DIR=", get_line));
		}
		down;
	}
	goto_mark;
	// End HSCROLL

	switch_win_id(session_names_id);
	if ((c_line == 1) && (at_eof)) {
		ctrl_style = DLGF_Disable;
		Create_style = Dlgf_Defbutton;
		Select_style = 0;
	}
	set_global_int('!@SESSVIEW@!',1);
  Sm_Get_List_Data( S_Name, S_Dir, ReadOnly );
	refresh=false;

  if ( btnonright )  {
    btnonright = 1;   // make sure it's no higher then one for calculations below
  }

	DlgCreate(dlg);

	refresh = false;
	longest_line_length = 40;

  DlgAddCtrl( Dlg, dlg_BitmapStatic, "BT_GN_121",
      3 + ( BtnOnRight * 62 ), 2,
      0, 0,
      sm_BITMAP, 0, "" );

  DlgAddCtrl(dlg,DLG_Blackframe, '', 13 - (btnonright * 12), Dlg_Units + 4,
        60, 2, SM_BOX1, 0, '');
  DlgAddCtrl(dlg,DLG_Static,'Current Session:',
        Dlg_Posoffset + 1, Dlg_Posoffset + Dlg_Units + 2, 0, 0, SM_STR1, 0, '');

  if ( Svl( CurSessName ) ) {
    CurSessId = CurSessName;
  }
  else {
    CurSessId = CurSessPath;
	}
  DlgAddCtrl( Dlg, dlg_Static, CurSessId,
      dlg_Posoffset + 18, dlg_Posoffset + 0,
      0, 0,
      sm_Str2, 0, "" );

  DlgAddCtrl(dlg,DLG_Blackframe,'',13 - (btnonright * 12), Dlg_Units + 44,
          60, Dlg_Units + 29, SM_BOX2, 0, '');
  DlgAddCtrl(dlg,DLG_Static, "&Name:", Dlg_Posoffset + 1, Dlg_Posoffset,
          0, 0, Sm_Name_Title_Ctrl, Ctrl_Style, '');
  DlgAddCtrl(dlg,Dlg_Text, S_Name, Dlg_Posoffset + 12, Dlg_Posoffset,
          30, 0, Sm_Name_Ctrl, Ctrl_Style,'/ML=30');
  DlgAddCtrl(dlg,Dlg_Static, "D&irectory:", Dlg_Negoffset + 12, Dlg_Posoffset + Dlg_Units + 16,
          0, 0, Sm_Dir_Title_Ctrl, Ctrl_Style,'');
  DlgAddCtrl(dlg,Dlg_Text, S_Dir,  Dlg_Posoffset + 12, Dlg_Posoffset,30,0,SM_dir_ctrl,ctrl_style,'/ML=128');

  DlgAddCtrl( Dlg, dlg_PushButton, "&Accept",
      Dlg_Posoffset + 32, Dlg_Negoffset + Dlg_Units + 17,
      DLG_StanBtnWidth + 2, 0,
      SM_Accept_ctrl,Dlgf_disable,"/R="+str(SM_Accept_Ctrl) + "/M=SM_ACCEPT /NW=" +
      str(session_names_number) +
      "/LID=" + str(SM_List_ctrl));

	DlgAddCtrl(dlg,DLG_PushButton,"&Browse...",
      DLG_PosOffset,dlg_PosOffset + dlg_units + 17,
      DLG_StanBtnWidth + 2, 0,
      SM_Browse_ctrl,ctrl_style,"/R="+str(SM_Browse_Ctrl) + "/M=SM_BROWSE /NW=" +
      str(session_names_number));

  DlgAddCtrl( Dlg, dlg_ListBox, "\x7F" + "I=/T=3/W=15" + "\x7F" + "NAME=/W=29/IS=1" + "\x7F" + "DIR=/W=29",
      13 - ( BtnOnRight * 12 ), dlg_Units + 80,
      60, dlg_Units | ( dlg_Units_QLine * 29 ),
      sm_List_Ctrl, DLGF_LB_HSCROLL,
      "/WIN=" + Str( Session_View_Win ) + "/OR=" + Str( C_Row ) +
      '/INCO=1/DC=1/INSWCMD=' + str(sm_create_ctrl) +
      '/DELWCMD=' + str(sm_delete_ctrl) + '/HSCROLL=' + str(maxlength + 45));
      DfltItem = sm_List_Ctrl;

	DlgAddCtrl( Dlg, dlg_PushButton, "&Create",
      1 + ( BtnOnRight * 62 ), dlg_PosOffset + 0,
      dlg_StanBtnWidth + 2, 0,
			sm_Create_Ctrl, 0 | Create_Style,
      "/R=" + Str( sm_Create_Ctrl ) + "/M=Sm_New" );

  DlgAddCtrl( Dlg, Dlg_PushButton, "&Delete",
      dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_5QLines,
      dlg_StanBtnWidth + 2, 0,
      sm_delete_ctrl, 0,
      "/R=" + Str( sm_Delete_Ctrl ) + "/M=Sm_Delete /NW=" +
          str( Session_Names_Number ) + "/DH=" + Str( Dlg ) +
          "/LB=" + str( sm_List_Ctrl ) );

  DlgAddCtrl( Dlg, dlg_PushButton, "&Update",
      dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_5QLines,
      dlg_StanBtnWidth + 2, 0,
      sm_Update_Ctrl, 0,
      '/R='+str(SM_Update_Ctrl) + "/M=Sm_Update" );

  DlgAddCtrl(dlg,Dlg_PushButton,'&Sort...',
      dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_3HLines,
      Dlg_StanBtnWidth + 2, 0,
      SM_Sort_Ctrl,0,
      '/R='+str(SM_Sort_Ctrl)+
      '/M=SM_SORT_LIST');

  DlgAddCtrl( Dlg, dlg_PushButton, "&Protect",
      dlg_PosOffset + 0, dlg_PosOffset | dlg_Units_3HLines,
      dlg_StanBtnWidth + 2, 0,
      id_sm_ProtectBtn, 0, "/M=SmProtectSession" );

	DlgAddCtrl( dlg, DLG_PushButton, "Se&lect",
    1, dlg_Units + 176,
		DLG_StanBtnWidth, 0, SM_OK, ctrl_style | Select_style, "/R=1");

	DlgAddCtrl( dlg, DLG_PushButton, "Cancel",
		DLG_PosOffset+DLG_StanBtnWidth+2, DLG_PosOffset,
		DLG_StanBtnWidth, 0, SM_Cancel, 0, "/R=0");

	DlgAddCtrl( dlg, DLG_PushButton, "&Help",
		63, DLG_PosOffset,
    DLG_StanBtnWidth + 2, 0, SM_HELP, 0, "/R=2");

	Result = DlgExecute( Dlg, sm_list_Ctrl, TitleStr, SESSMGR_HELPLINK,
			"/HOOK=SessMessageProc", 0 );

	// Delete the encoded (no name) file
	Del_File( Make_Restr_Name( ENCODED_FILES_MODE, "0:(no name)" ) + ".MEW" );
	Error_Level = 0;

  S_Dir  = "";
	S_Name = "";
	if ( Result == 1 ) {
		SvWinId = Window_Id;
    Switch_Win_Id( Session_Names_Id );
    Sm_Get_List_Data( S_Name, S_Dir, ReadOnly );
		Switch_Win_Id( SvWinId );
		Return_Int = 1;
	}
	else {                                // User aborted
		Return_Int = 0;
		S_Dir = "";
	}
	DlgKill( Dlg );

	Insert_Mode = T_Insert_Mode;
	Refresh = T_Refresh;
	Switch_Win_Id( Active_Window );
  return ( "\x7F" + "DIR=" + S_Dir + "\x7F" + "NAME=" + S_Name );


#else       // ------------------- Dos version -----------------------

	int Active_Window = 	Window_Id;
	int T_Insert_Mode = 	Insert_Mode;
	int T_Refresh = 			Refresh;
	int cc = 							longest_line_length;		// cc vars used for box
	int ll;
	int menu;
	str s_dir, s_name = "";
  int ReadOnly;

	str sessname[80];
	str cursessname[80];
	str cursesspath[80];
	str cursessid[80];
	str otherstr[20];
	int svwinid;
	int mh, mi = 0;
	int viewoffset=0;
	int cline_pos;
	int session_view_win;
	int lll;
	int dfltitem = 1;

	dfltitem=6;
	switch ( global_int('!@SESSVIEW@!') )
	{
		case 1 :		// view session name
			cline_pos = c_line;
			switch_win_id(session_names_id);
			goto_line(cline_pos);
			sessname = remove_space(copy(get_line,1,70));
			cursessname = sessname;
			otherstr= ' Path';
			session_view_win = session_names_number;
			switch_win_id(session_list_id);
			goto_line(cline_pos);
			cursesspath = remove_space(copy(get_line,1,xpos(' ',get_line,1)));
			switch_win_id(session_names_id);
				break;

		case 0 :		// view session path
		default:
			cline_pos = c_line;
			switch_win_id(session_list_id);
			goto_line(cline_pos);
			sessname = remove_space(copy(get_line,1,xpos(' ',get_line,1)));
			cursesspath = sessname;

			switch_win_id(session_names_id);
			goto_line(cline_pos);
			cursessname = remove_space(copy(get_line,1,70));
			switch_win_id(session_list_id);
			otherstr = ' Name';
			session_view_win = session_list_number;
			break;
	}

	menu = menu_create;

MENU_LOOP:


	menu_delete(menu);
	menu = menu_create;
	mi = 0;
	refresh = false;
	longest_line_length = 40;

/*1*/	menu_set_item(menu,++mi,'Current Session:','','/W=20/C=2/L=2',10,0,0);
	switch(global_int('!@SESSVIEW@!'))
	{
		case 1 :
			cursessid = cursessname;
			break;
		case 0 :
		default:
			cursessid = cursesspath;
			break;
	}

/*2*/ menu_set_item(menu,++mi, cursessid,'','/W=30/ML=50/C=2/L=3',10,0,0);

/*3*/ menu_set_item(menu,++mi,'New directory', '',
					'/KC=<Ins>/W=18/K1=0/K2=82/R=3/L=6/C=50' /*+ str(cc)*/, 11, 0, 0);

/*4*/ menu_set_item(menu,++mi,'Remove session',
						'SM_DELETE /NW='+
						str(session_names_number)+
						'/LW='+str(session_list_number), '/M=1'+
						'/KC=<Del>/W=19/K1=0/K2=83/R=4/L=8/C=50'/* + str(cc + 20)*/, 11, 0, 0);

/*5*/ menu_set_item(menu,++mi,'View '+otherstr,'','/KC=<F6>/W=13/ML=28/K1=0/K2=64/R=5/L=10/C=50',11,0,0);

/*6*/ menu_set_item(menu,++mi,'Select directory to work in:', '', '/ML=35/W=' + str(longest_line_length + 1) + '/L=5/C=2/DC=1/WIN='+STR(session_view_win)+'/OR='+STR(C_ROW), 15, 0, 0);
			dfltitem = mi;


	Return_Int = menu;

	//RM("USERIN^DATA_IN  /NK=1/Y=4/H=SESSMGR/HN=1/PRE=SS/#="+
	//        str(mi)+"/T=Session Manager/S="+
	//        STR(DFLTITEM)+"/NC=1/OR=" + Str(C_Row));
	RM("USERIN^DATA_IN  /H=SESSMGR/HN=1/A=0/PRE=SS"+
				"/NK=1/Y=4"+
				'/#='+str(mi)+'/T=Session Manager/S='+
				str(dfltitem)+"/NC=1/OR=" + Str(C_Row));

forced:
	if (Return_Int == 1) {
		switch ( global_int('!@SESSVIEW@!') )
		{
			case  1:
				svwinid = window_id;
				switch_win_id(session_names_id);

        Sm_Get_List_Data( S_Name, S_Dir, Readonly );

				switch_win_id(svwinid);
				break;
			case  0:
			default:
				svwinid=window_id;
				switch_win_id(session_list_id);
				s_dir = shorten_str(copy(get_line,1,149));
				switch_win_id(svwinid);
				break;
		}
	}
	else if ( Return_Int == 0 )
	{
		Return_Int = 0;						// user aborted
		s_dir = "";
	}
	else if ( Return_Int == 3 )		// *** NEW SESSION ***
	{
		switch ( global_int('!@SESSVIEW@!') )
		{
			case  1:
				RM("MEERROR^MESSAGEBOX /B=2/M=Need a dialog box for this!!!");
				break;
			case  0:
			default:
				Return_Str = "";
				Return_Int = 0;
				s_dir = select_dir_dlg();
/*
				if ( copy(s_dir,svl(s_dir),1) == '\' )
				{
					s_dir = copy(s_dir,1,svl(s_dir)-1);
				}
*/
				s_dir = fix_dir_spec(s_dir);
				if (s_dir == '') // *** ESCAPE ***
				{
					goto MENU_LOOP;
				}
				else if ((file_attr(s_dir) & 0x10) == 0)
				{
					rm("MEERROR^MessageBox /B=1/M=Directory does not exist");
					goto menu_loop;
				}
				break;
		}
	}
	else
		Goto MENU_LOOP;

	Insert_Mode = T_Insert_Mode;
	Refresh = T_Refresh;
	menu_delete(menu);
	switch_win_id(active_window);
	return ("DIR=" + s_dir + "NAME=" + s_name);

#endif

}  // Sm_Dialog

void Clr_Tmp_Globals( )
/******************** Multi-Edit VOID Macro Function ************************

 NAME:         clr_tmp_globals()

 DESCRIPTION:  Clears out global variables whose prefix is one of !@.~

 PARAMETERS:   None

 RETURNS:      None

*****************************09-15-93 03:45pm*******************************/
  // clear out globals that don't begin with ~
	//
{
	int jx;
	str tstr;

	TStr =  First_Global( jx );
	while ( Tstr != '' )
	{
    if (XPOS(str_char(tstr,1),'~',1) == 0) {
			if(  jx == 1  ) {
				set_global_int(tstr,0);
			} else {
				set_global_str(tstr,'');
			}
			TStr = First_Global(jx);
		}
		else
		{
			TStr = Next_Global(jx);
		}
	}
}

int Sm_Restart( str Parms )
/****************** Multi-Edit INTEGER Macro Function ***********************

 NAME:         sm_restart(

 DESCRIPTION:  restarts Multi-Edit

 PARAMETERS:   None.

 RETURNS:      False if failure, true if success

*****************************04-05-93 04:32pm*******************************/
{
	if ( !global_int('!@RUNSESSMGR@!') )
	{

		int count, winid;
		int T_Refresh = refresh;

		// for use in clear_temp_globals subroutine:
		int jx;
		str tstr;


		rm("EXIT /NE=1/SN=" + parse_str("NAME=",parms)); // save current system status and shut down
		if ( return_int )
			{
			// this was prompted by noticing that the same files were always
			// checked out of my VCS library, yet vcs support was configured
			// for encoded status files.  found out some global variables were
			// not being cleared.
			clr_tmp_globals(); // added 091593[scm] - clear !@. prefixed vars.

			// kill all editable windows
			refresh=false;
			for ( count=WINDOW_COUNT; count > 0; count-- )
			{
				winid = count;
				switch_window(winid);
				if ( (WINDOW_ATTR & $80) == 0 ) /* editable window? */
				{
					Redraw;
					Delete_Window;
				}
			}
			make_message('');
			refresh=T_Refresh;
			return(1);                   // success
		}
		else
		{
			refresh=T_Refresh;
			return(0);                   // failed
		}
	}
	return(1);
}


void Sm_Not_Active( )
/******************** Multi-Edit VOID Macro Function ************************

 NAME:         SM_Not_Active()

 DESCRIPTION:  Inform the user that the Session Manager can not be used
							 unless the Restore feature is configured for 'Encoded Files'

 PARAMETERS:   None.

 RETURNS:      None.

*****************************04-05-93 04:34pm*******************************/
{
	int  menu = menu_create ;

	return_int = menu;
	//RM('UserIn^Data_In /HN=1/H=INRE/A=1/#=11/T=Session Manager');
#ifdef WINDOWS
	menu_set_item( menu, 1, 'The Multi-Edit SESSION MANAGER','','/L=1/C=3',10,0, 0);
	menu_set_item( menu, 2, 'is not active at this time.','','/L=2/C=3',10,0, 0);
	menu_set_item( menu, 3, 'To activate the SESSION MANAGER, you must','','/L=4/C=3',10,0,0);
	menu_set_item( menu, 4, 'select "Encoded status files for each dir" ','','/L=5/C=3',10,0,0);
	menu_set_item( menu, 5, 'from the Session Status Method option','','/L=6/C=3',10,0,0);
	menu_set_item( menu, 6, 'from the Session Manager Setup dialog box','','/L=7/C=3',10,0,0);
	menu_set_item( menu, 7, '','','/L=8/C=3',10,0,0);
	RM('UserIn^Data_In /HN=1/A=1/#=7/T=Session Manager/H=' +
			SESSMGR_HELPLINK);
#else
	menu_set_item( menu, 1, 'The Multi-Edit SESSION MANAGER','','/L=3/C=3',10,0, 0);
	menu_set_item( menu, 2, 'is not active at this time.','','/L=4/C=3',10,0, 0);
	menu_set_item( menu, 3, 'To activate the SESSION MANAGER, you must','','/L=6/C=3',10,0,0);
	menu_set_item( menu, 4, 'select "Encoded status files for each dir" ','','/L=7/C=3',10,0,0);
	menu_set_item( menu, 5, 'from the Restore Previous Status option','','/L=8/C=3',10,0,0);
	menu_set_item( menu, 6, 'from the User Interface Settings dialog box','','/L=9/C=3',10,0,0);
	menu_set_item( menu, 7, '                                             ','','/L=10/C=3',10,0,0);
	menu_set_item( menu, 8, 'Main Menu --','','/L=12/C=3',10,0,0);
	menu_set_item( menu, 9, 'Other --','','/L=13/C=6',10,0,0);
	menu_set_item( menu,10, 'Install --','','/L=14/C=9',10,0,0);
	menu_set_item( menu,11, 'User Interface --','','/L=15/C=12',10,0,0);
	menu_set_item( menu,12, 'Restore Previous Status','','/L=16/C=15',10,0,0);
	RM('UserIn^Data_In /HN=1/H=INRE/A=1/#=12/T=Session Manager');
#endif

	menu_delete( menu );

}

void SessMgr	(str s_name 			= Parse_Str( "/SESSION=", mparm_str ),
							 str s_dir				= Parse_Str( "/DIR=", mparm_str ),
							 str select_name 	= Parse_Str( "/SN=", mparm_str ),
							 int no_switch 		= Parse_Int( "/NOSWITCH=", mparm_str ) != 0
							)
/******************** Multi-Edit VOID Macro Function ************************

 NAME:         SessMgr()

 DESCRIPTION:  The driver routine of the Session Manager

 PARAMETERS:   /SESSION=name    Switch directly to specified session.

 RETURNS:      None.

*****************************04-05-93 04:36pm*******************************/
{
  int i;                        // loop counter
  int session_names_id = 0;         // window id of session name list
  int longest_line_length;      // longest length in filespec list
  int using_name;
  int svcurscrn = global_int('CUR_SCRN');
  int last_window_active 	= window_id; // save the handle of the starting window for use if user presses escape
  int window_to_switch_to = window_id;
  int T_Refresh = refresh;
  int Session_Hidden = 0;
  str Buffer;
  str OrgSession = Global_Str( "!Session_Name" );

  if (( caps(S_Name) == caps(OrgSession) ) && (S_Name != ""))
  {
    return();
  }


  Sm_Active_Win_Id = Window_Id;
  Refresh = False;

	// FORCED SETTINGS
	set_global_int('!@SESSVIEW@!',1);				// default to view names (1=true)
	set_global_int('!@SESSMODMSG@!',0);     // change existing name on exit (1=true)
	set_global_int('!@SESSRSTRMSG@!',1);    // show restore message (1=true)

  Working;
  if ( !IN_ENCODED_MODE ) { // must be in Encoded Files mode!!!
    Sm_Not_Active( );
  }
  else {

    // ask user for session to switch to
    int user_is_picking = 1;

    while ( User_Is_Picking ) {
      if ( S_Name == "" ) {
        Create_Window;                      // create window for session names
        Session_Names_Id = Window_Id;
        file_name = 'SESSNAMES';

        // create the list and fetch the longest line length
        longest_line_length = sm_make_list(session_names_id, select_name);
        if ( !No_Switch ) { // don't do this if they used the /SM switch
          if ( ( Global_Str( "!Session_Name" ) == "" ) &&
              !( Restore_Flags & _rest_SavNamedOnly ) ) {
            // assume this to be a new session named the current directory
            // unless we find a more appropriate name
            Set_Global_Str( "!Session_Name", FExpand( "" ) );
            if ( LocateDBPage( "MECONFIG", "SESSMGR.CFG", FALSE ) ) {
              Down;

              str T_Name = Get_Line( );

              if ( Svl( T_Name ) ) {
                Switch_Win_Id( Session_Names_Id );
                Mark_Pos;
                if ( Find_Text( "\x7F" + "NAME=" + t_name + "\x7F", 0, 0 ) ) {
                  if ( Parse_Str( "\x7F" + "DIR=", Get_Line( ) ) ==
                      Global_Str( "!Session_Name" ) ) {
                    // Set only if the last session had the same directory
                    Set_Global_Str( "!Session_Name", T_Name );
                  }
                }
                Goto_Mark;
              }
            }
          }
        }
        switch_win_id(session_names_id);
        session_names_number = cur_window;
        Buffer = Sm_Dialog( Longest_Line_Length, Session_Names_Id,
            Session_Names_Number );
        ProcessMsgQueue( 10 );
        S_Dir = Fix_Dir_Spec( Parse_Str( "\x7F" + "DIR=", Buffer ) );
        S_Name = Parse_Str( "\x7F" + "NAME=", Buffer );
      }
      if ( ( S_Dir != "" ) || ( S_Name != "" ) ) {
        Working;
        if ( Switch_Win_Id( Session_Names_Id ) ) {
          Delete_Window;
        }
        Switch_Win_Id( Last_Window_Active );
        if ( S_Name != OrgSession ) {
          if ( Svl( S_Name ) ) { // if this is a named session
            Using_Name = True;
          }
          else {
            Using_Name = False;
          }
          Working;
          if ( No_Switch ) {

            int Count;

            for ( Count = Window_Count; Count > 0; --Count ) {
              Switch_Window( Count );
              if ( ( Window_Attr & 0x80 ) == 0 ) {
                Delete_Window;
              }
            }
            goto Skip_Switch;
          }
          // try to restart the system
          if ( Sm_Restart( Buffer ) ) {
            if ( !No_Switch ) {
              Session_Hidden = TRUE;
              ShowWindow( Frame_Handle, SW_Hide );
              MewLogo( 0 );
            }

  Skip_Switch:
            Error_Level = 0;
            // change to directory of new session
            if ( !Using_Name && ( S_Dir != "" ) ) {
              Change_Dir( Fix_Dir_Spec( S_Dir ) );
            }
            if ( Error_Level ) {
              Beep;

  #ifdef Windows
              if ( Using_Name ) {
                MessageBox( Frame_Handle,
                    "Unable to change directory to " + S_Dir,
                    "Warning: Session Manager",
                    mb_Ok | mb_IconExclamation );
              }
              else {
                MessageBox( Frame_Handle,
                    "Unable to change directory to " + S_Dir,
                    "Error: Session Manager",
                    mb_Ok | mb_IconExclamation );
              }
  #else
              Make_Message( "Unable to change directory to " + S_Dir );
              Read_Key;
  #endif
              Error_Level = 0;
              if ( Using_Name ) {
                goto Do_Switch;
              }
            }
            else {

  Do_Switch:
    // ***** Clear up the display while switching *****
              refresh = true;
              redraw;             // 090993[scm]
              new_screen;
    // ************************************************

              working;
              ProcessMEWInit();

              working;

// is this necessary? hmmm.... ----------------------------------------------
              // kill the file history we used ????
              // make next file->open use clean history list?
              str fhnum[4] = parse_str('/#=',global_str('FILE_HISTORY'));
              set_global_str('FILE_HISTORY'+fhnum,'');

// --------------------------------------------------------------------------

//                  sm_parms1();

#ifdef Windows
              if ( !No_Switch ) {
                  Rm("SETCONFIG /DB=MECONFIG");
                  rm('Load_Wcmds');
                  ProcessPkgInit( False );
              }
#endif
              if ( !No_Switch ) {
                  RM('.STARTUP^STARTUP');
                  rm('KEYMAC_LOAD /NE=1');
              }
              ERROR_LEVEL = 0;

#ifdef Windows
              if ( Using_Name ) {
                // restore status according to name
                Rm( "Restore /M=0/SS=" + str( !No_Switch ) + "/SN=" + S_Name +
                    "/SD=" + S_Dir );
              }
              else {
                // restore status according to that directory
                Rm( "Restore /M=0/SS=" + str( !No_Switch ) );
              }
#else
              Rm( "Restore /M=0/CC="+str(svcurscrn)); // restore status according to that directory
#endif
              if ( Parse_Int( "\x7F" + "NEW=", Buffer ) ) {
                /* This creates a status file for the new session so that the new
                session will appear in the list the next time the session manager
                is invoked */
                Rm( "Status" );
              }

#ifdef Windows
              SendMessage(frame_handle,WM_USER+101,0,0); // WM_PARENTSIZE
              if(!restoreresult)
              {
                  RM('tbmgr^build_toolboxes');  // forced build accordingly to db file
                  if ( !Global_Int ("@MAXIMIZE_WINDOWS")  )
                  {
                    RM('WOrganize /M=0');
                  }
              }

              fprompt_work_dir = fexpand("");
              if(length(fprompt_work_dir) > 3)
              {
                if(copy(fprompt_work_dir,length(fprompt_work_dir),1) == "\\")
                {
                  fprompt_work_dir = copy(fprompt_work_dir, 1, length(fprompt_work_dir) - 1 );
                }
              }
              if(fprompt_mode & _FPM_CLEARMASKSTART)
              {
                fprompt_last_path = fprompt_work_dir + "\\*.*";
              }
#endif

              Window_To_Switch_To = Return_Int;
              User_Is_Picking = False;
              if ( !No_Switch ) {
                  Rm( "VCSCHK^VcsStartup" );    // Initialize the vcs support
                  Rm( "METAGS^Tag_Init" );
                  HlpSetGlobals( );  // Initialize the help files system
                  // 090293[scm] - call macro named by @startup_mac_2
                  // variables set by startup.mac be may overridden by
                  // those contained in the status file just restored
                  // (see mesys^parmload for the sequence of startup events)
                  if(  (Length(Global_Str('@STARTUP_MAC_2')))  ) {
                    RM(Global_Str('@STARTUP_MAC_2'));
                    Error_Level = 0;
                  }
                  // load global templates
                  if ( g_Tmp_Global &&
                      File_Exists( User_Path + "GLOBAL" + Tmp_File_Ext ) ) {
                    Tmp_Init_All( "GLOBAL", 0 );
                  }
                }
                make_message("Session \"" + s_name + "\" restored.");
            }
          }
          else {
            Make_Message('Session Manager: Save Files aborted. Returned to current session.');
          }
        }
        else {
          User_Is_Picking = False;
        }
      }
      else {
        Make_Message( "" );
        Switch_Win_Id( Session_Names_Id );
        Delete_Window;
        Switch_Win_Id( Last_Window_Active ); // back to where we started
        User_Is_Picking = 0;
        Switch_Win_Id( Window_To_Switch_To ); // 082493[scm]
      }
    } // end while user_is_picking
  }
  Refresh = T_Refresh;

  if ( Session_Hidden ) {
    ShowWindow( Frame_Handle, SW_Show );
    SendMessage( Frame_Handle, WM_PARENTSIZE, 0, 0 );
    MewLogo( 1 );
  }
  Session_Names_Number = 0;
  Sm_Active_Win_Id = 0;

}  // SessMgr

int SessMessageProc(int &retval, int window, message, wparam, lparam, str parms ) {
/*
  Message proc for the session manager dialog box
*/
  if ( Message == WM_COMMAND ) {
    switch( WParam ) {
			case dlg_WCmd_Init :
        Sm_Set_Ctrls( Window );
        break;

      case sm_Name_Ctrl :
      case sm_Dir_Ctrl :
        if ( ( ( LParam >> 16 )  == en_Change ) && ( !sm_Ignore_en_Change ) ) {
          EnableWindow( GetDlgItem( Window, sm_Accept_Ctrl ), TRUE );
          SetDefaultButton( Window, sm_Accept_Ctrl );
				}
				break;

      case sm_List_Ctrl :
        switch ( LParam >> 16 ) {
					case LBN_SELCHANGE :
            Sm_Set_Ctrls( Window );
						break;
				}
				break;
		}
	}
	return(DlgMessageProc(retval, window,message,wparam,lparam, parms ));

}