/****************************** Module Header ******************************* * * Module Name: main.e * * Copyright (c) Netlabs EPM Distribution Project 2002 * * $Id$ * * =========================================================================== * * This file is part of the Netlabs EPM Distribution package and 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, in version 2 as it comes in the "COPYING" file of the * Netlabs EPM Distribution. This library 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. * ****************************************************************************/ ; --------------------------------------------------------------------------- ; - DEFINIT and DEFMAIN are processed whenever the .ex file is linked. ; For the main .ex file this is equivalent to 'for every newly opened EPM ; window'. For other linked packages DEFMAIN is only executed, if ; the package is called by the command/DEFMAIN trick: If a command ; is executed, also .ex files are searched. If an .ex file with the ; same basename as the command exists, then DEFMAIN of this package ; will be executed. ; - DEFMAIN is processed after all DEFINITs are completed. That makes it ; possible to process something in DEFMAIN being ensured that all ; DEFINIT actions (e.g. set default values) are finished. ; - DEFMAIN is not processed, if EPM.EXE is started with option /r. ; /r opens first a new EPM thread, but if an EPM window is already ; present, all args will be passed to that EPM window (or the topmost ; EPM window). Exception: An EPM window, started with option /m (multiple ; instances), is ignored therefore. ; - Only 1 DEFMAIN is allowed per .ex file. ; - Every .ex file defines its own DEFINIT, DEFMAIN and DEFEXIT. ; - DEFEXIT is not processed for the main .ex file. For other linked ; .ex files it is processed on unlink (may be used to switch a keyset ; back or to remove a submenu). ; - DEFMAIN should be used to parse the command line arguments of the ; current .EX file. For EPM.EX this is handled by MAIN.E. defmain universal rexx_profile universal unnamedfilename -- use NLS-dependent string from EPMMRI.DLL or -- ETKE603.DLL, not the one from ENGLISH.E universal DisplayDisabled -- suppress screen refresh during file loading ; Get args ----------------------------------------------------------------- -- arg(1) contains all args, that where submitted to EPM.EXE, after -- stripping the known EPM command line options off. These args will be -- submitted later to the Edit command. EpmArgs = arg(1) -- dprintf doesn't work before the end of defmain. It probably works just -- after InitConfig. Note that internal (and outdated internal) defs were -- already processed when DEFMAIN is executed. --dprintf( 'MAIN: arg(1) = ['arg(1)']') -- Note: Double quote chars were removed by the EPM executable. -- Fortunately several NEPMD commands can handle filenames with -- spaces (e.g. Shell). As a result, that won't matter. ; Process settings from MODECFG.E -------------------------------------------- 'InitModeConfig' ; Process settings from NEPMD.INI and load menu ---------------------------- 'InitConfig' ; Get the .Untitled filename, defined in the DLLs, NLS-dependent. ---------- -- EPM always starts with an .Untitled file. -- For the language-specific versions of the EPM binaries (W4+) all -- resources moved to epmmri.dll. The .Untitled name is stringtable item -- 54. -- For the Larry Margolis version epmmri.dll doesn't exist. The .Untitled -- name is located in etke603.dll as resource, stringtable item 54. -- This filename is NLS-dependent and hard-coded in the E Toolkit DLLs, -- while the filename coming from the 'edit' command queries the constant. -- To keep both names in synch, we take the name from the DLL and replace -- all occurences of the UNNAMED_FILE_NAME const with a query of the -- universal var or of the proc GetUnnamedFilename(). unnamedfilename = .filename getfileid unnamedfid ; Host support ------------------------------------------------------------- compile if (HOST_SUPPORT='EMUL' | HOST_SUPPORT='E3EMUL') and not defined(my_SAVEPATH) call check_savepath() compile endif ; Automatically link .ex files from \autolink --------------------- call Autolink() ; Process 'init' hook ------------------------------------------------------ -- The 'init' hook is a comfortable way to override or add some -- general settings as an extension to NepmdInitConfig or initconfig. -- It can be used for configurations by other linked .ex files without -- the use of PROFILE.ERX. -- Example: 'HookAdd init default_save_options /ns /ne /nt' -- Example: 'HookAdd init default_search_options +faet' -- Note : Hooks are only able to process commands, not procedures. 'HookExecute init' ; Process PROFILE.ERX ------------------------------------------------------ -- Changed: profile.erx is now processed before any file is loaded. In -- order to change file settings, the 'load' or 'loadonce' hook -- must be used now. -- Note: E.g. switching highlighting on for the original EPM with -- 'toggle_parse 1 epmkwds.' from profile.erx didn't work for -- every loaded file. Any file stuff didn't work properly there. -- Using the new 'load' hook or the 'AtLoad' command, one can -- execute something for every loaded file -- easily and properly. if rexx_profile then ProfileName = 'profile.erx' -- REXX profile is not searched anymore. It must be placed in -- %NEPMD_USERDIR%\bin with the name PROFILE.ERX now. Profile = Get_Env('NEPMD_USERDIR')'\bin\'ProfileName if NepmdFileExists( Profile) then if NepmdQueryPathInfo( Profile, 'SIZE') > 0 then 'rx' Profile EpmArgs endif endif endif ; Show menu and window ----------------------------------------------------- .titletext = 'Executing: 'EpmArgs refresh call showmenu_activemenu() -- show the EPM menu -- see also: INIT.E for menu call showwindow('ON') mouse_setpointer WAIT_POINTER --refresh -- force to show the window, with the empty file loaded -- Not possible: ProcessSelect is not called if starting command takes -- longer display -1 -- disable screen refresh, re-enabled in defselect DisplayDisabled = 1 dprintf( 'MAIN', 'executing postme main2' unnamedfid','EpmArgs) 'postme main2' unnamedfid','EpmArgs ; --------------------------------------------------------------------------- ; When PROFILE.ERX is processed, it often takes a longer time. In order to ; keep the order of the further steps (e.g. afterload) right, moving the rest ; of defmain to a posted defc should delay it until PROFILE.ERX processing ; is fully completed. Fortunally the single postme doesn't cause much ; overhead here. defc main2 universal nepmd_hini -- following universals are initialized to the -- fileid of the file after execution of the -- 'xcom e /n' command: universal firstloadedfid -- first loaded file universal firstinringfid -- first file in the ring parse arg unnamedfid ',' EpmArgs ; Maybe change to previous work dir ---------------------------------------- KeyPath = '\NEPMD\User\ChangeWorkDir' ChangeWorkDir = NepmdQueryConfigValue( nepmd_hini, KeyPath) if ChangeWorkDir = 1 then KeyPath = '\NEPMD\User\ChangeWorkDir\Last' LastWorkDir = NepmdQueryConfigValue( nepmd_hini, KeyPath) if NepmdDirExists( LastWorkDir) then call directory( '\') call directory( LastWorkDir) endif endif ; Execute the EpmArgs (Edit command) --------------------------------------- dprintf( 'MAIN', 'main2: EpmArgs = 'EpmArgs) KeyPath = '\NEPMD\User\AutoRestore\Ring\LoadLast' Enabled = NepmdQueryConfigValue( nepmd_hini, KeyPath) if (EpmArgs = '' & Enabled) then -- Restore last edit ring if started without args dprintf( 'MAIN', 'executing: RestoreRing') 'RestoreRing' else -- Make EpmArgs a parameter for the Edit command and execute it dprintf( 'MAIN', 'executing: e ' EpmArgs) 'e' EpmArgs endif ; Quit automatically loaded empty file ------------------------------------- -- E automatically created an empty file when it started. -- If user specified file(s) to edit, get rid of the empty file. -- This must be processed at defmain, because this file is the only one, -- that doesn't trigger a defload event. -- Get fileid after processing of EpmArgs. getfileid newfid dprintf( 'MAIN', 'filesinring = 'filesinring()', filename = '.filename) dprintf( 'MAIN_EMPTY_FILE', 'filesinring = 'filesinring()', filename = '.filename) if validatefileid(unnamedfid) <> 0 then activatefile unnamedfid -- Check if other files in ring next_file getfileid otherfid if otherfid = unnamedfid then -- no other file in ring -- For the automatically created empty file no defload event is -- triggered. -- Load a new empty file, for that the defload event will -- process. dprintf( 'MAIN_EMPTY_FILE', 'load a new empty file...') 'xcom e /n' getfileid newfid -- xcom edit doesn't call defc edit, therefore set the following -- universal vars to make ProcessAfterload happy. -- Usually they are set by defc edit. firstloadedfid = newfid -- first file for this edit cmd firstinringfid = newfid -- first file in the ring dprintf( 'MAIN_EMPTY_FILE', 'now filesinring = 'filesinring()) endif -- Get rid of the automatically created empty file dprintf( 'MAIN_EMPTY_FILE', 'quit internally loaded empty file... unnamedfid = 'unnamedfid) activatefile unnamedfid 'xcom q' dprintf( 'MAIN_EMPTY_FILE', 'now filesinring = 'filesinring()) endif dprintf( 'MAIN_EMPTY_FILE', 'activating newfid = 'newfid', filename = 'newfid.filename) dprintf( 'MAIN', 'activating newfid = 'newfid', filename = 'newfid.filename) activatefile newfid ; Workaround --------------------------------------------------------------- -- Ensure that ProcessSelect is called. Sometimes it will be suppressed if -- longer commands have to be executed by the Edit command. ProcessSelect -- won't process a file twice, because the previous fileid is checked. -- BTW: The select event for the automatically created empty file is -- always executed too early and therefore further processing is -- suppressed in SELECT.E. -- 2 postmes would decrease stability compared with 1. dprintf( 'MAIN', 'executing: ProcessSelect') 'postme ProcessSelect' ; Execute just-installed stuff, if any ------------------------------------- -- The JustInstalled key is written with value 1 on import of -- DEFAULTS.CFG. Therefore it is added to the RegDefaults ini -- application. App = 'RegDefaults' Key = '\NEPMD\Install\JustInstalled' JustInstalled = QueryProfile( nepmd_hini, App, Key) if JustInstalled = '' then -- if key doesn't exist 'postme postme DefaultsMissingMsgBox' elseif JustInstalled = 1 then -- Link JustInst.ex if present display -2 link 'justinst' display 2 if rc > 0 then -- Execute defc JustInst if isadefc('JustInst') then 'AtPostStartup JustInst' endif endif -- Reset JustInstalled ini key call SetProfile( nepmd_hini, App, Key, 0) -- Execute install cmd here because for WarpIN 1.0.18 it can't read -- WarpIN's database while WarpIN is running. NepmdRootDir = Get_Env( 'NEPMD_ROOTDIR') --quietshell 'call' NepmdRootDir'\netlabs\install\expobj.cmd NOMSG' 'rx' NepmdRootDir'\netlabs\install\expobj.cmd NOMSG' -- Popup a message box if user files were moved by the installation. -- The UserFilesMoved key is not added to RegDefaults in order to -- keep the RegDefaults application empty unitil DEFAULTS.CFG is -- imported. Keep in sync with MVUSER.CMD. App = 'Install' Key = 'UserFilesMoved' next = QueryProfile( nepmd_hini, App, Key) if next = 1 then 'postme postme UserFilesMovedMsgBox' endif next = SetProfile( nepmd_hini, App, Key, 0) -- Rename and remove obsolete reg keys 'AtPostStartup CleanUpConfigKeys' -- Remove all file entries to force a recompile of all -- on the next RcompileNew call 'AtPostStartup RecompileNew RESET NOMSG' -- Import all .bar files to be able to select them 'ImportAllToolbarFiles' endif ; --------------------------------------------------------------------------- defc DefaultsMissingMsgBox universal nepmd_hini App = 'RegDefaults' Key = '\NEPMD\Install\JustInstalled' Title = 'Initialization failed - default values missing' Text = '' Text = Text || 'Error: The default values were not found in NEPMD.INI.' Text = Text || ' This leads to many uninitialized settings.'\n\n Text = Text || 'As a workaround, you can either delete the ini' Text = Text || ' application ''RegDefaults'' from NEPMD.INI manually' Text = Text || ' or let EPM do that.'\n\n Text = Text || 'Should the workaround be applied now?' Style = MB_OKCANCEL + MB_ERROR + MB_MOVEABLE ret1 = winmessagebox( Title, Text, Style) if ret1 = MBID_OK then TestKey = 'Test' -- Write a test value next = SetProfile( nepmd_hini, App, TestKey, '1') -- Delete the App next = SetProfile( nepmd_hini, App, '', '') -- delete the App -- Query test value TestVal = QueryProfile( nepmd_hini, App, TestKey) if TestVal = '' then -- if key doesn't exist Title = 'RegDefaults deleted from NEPMD.INI' Text = '' Text = Text || 'On the next EPM start, default values will be imported.'\n\n Text = Text || 'Should EPM be restarted now?' Style = MB_OKCANCEL + MB_INFORMATION + MB_MOVEABLE ret2 = winmessagebox( Title, Text, Style) if ret2 = MBID_OK then 'Restart closeother' endif else Title = 'RegDefaults not deleted from NEPMD.INI' Text = '' Text = Text || 'Error: The default values ''RegDefaults'' were' Text = Text || 'not deleted from NEPMD.INI.' Style = MB_OK + MB_ERROR + MB_MOVEABLE ret3 = winmessagebox( Title, Text, Style) endif endif ; --------------------------------------------------------------------------- defc UserFilesMovedMsgBox Title = 'User files were moved' Text = '' Text = Text || 'You''ve just updated/reinstalled NEPMD.'\n\n Text = Text || 'Some of your user files were moved into subdirectories in order to' Text = Text || ' ensure that EPM starts in a safe state. These subdirectories are placed in' Text = Text || ' your tree and are named bin, ex and mode as before, but the installation' Text = Text || ' date was appended.'\n\n Text = Text || 'Note that NEPMD.INI was not moved. That means that your previous settings' Text = Text || ' were not lost.'\n\n Text = Text || 'To restore all or some of the moved files, copy them to the newly created' Text = Text || ' bin, ex or mode subdirectories.' Style = MB_OK + MB_INFORMATION + MB_MOVEABLE ret = winmessagebox( Title, Text, Style)