/****************************** Module Header ******************************* * * Module Name: infoline.e * * Copyright (c) Netlabs EPM Distribution Project 2004 * * $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. * ****************************************************************************/ compile if not defined( SMALL) -- If compiled separately EA_comment 'This defines macros for title an status bars.' define INCLUDING_FILE = 'INFOLINE.E' include 'stdconst.e' const tryinclude 'mycnf.e' const compile if not defined( NLS_LANGUAGE) NLS_LANGUAGE = 'ENGLISH' compile endif include NLS_LANGUAGE'.e' compile endif ; Macros for enhanced title bar and status bar ; The check, if an update is required, is a little bit opaque: Every ; title- or statusline defines a with it in order to ; determine at several events, if a line must be updated or not. ; ; The advantage of this is, that a (maybe external) defproc or defc ; can simply call RefreshInfoLine . A line is only refreshed, ; if a with a matching is defined for that line. ; ; The title- and statusline defs are parsed by defproc ; ResolveInfoFields. There, for every , GetInfoFieldValue is ; called, that returns not only the resolved value, but also the ; defined for it. This is compared with the submitted ; arg of RefreshInfoLine. ; ; If any requires an update, the entire line is updated. ; The refresh of additional (compared to standard EPM) statusline and ; titleline fields is done via E macros and therefore not quite good in ; performance. If problems occur during execution of a macro, the refresh ; can be disabled and enabled after the execution with a universal var: ; ; infolinerefresh = 0 ==> disabled ; infolinerefresh <> 0 ==> enabled (default is empty after startup ; for universal vars) ; The refresh is already disabled for hidden files. ; ; To use it in your macros: ; defc MyMacro ; universal infolinerefresh ; saved_modify = .modify ; saved_autosave = .autosave ; .autosave = 0 ; infolinerefresh = 0 ; ; ; infolinerefresh = 1 ; if .modify > saved_modify ; .modify = saved_modify + 1 ; endif ; .autosave = saved_autosave ; Bug: ; o If file was altered by another file, then the old date is shown in ; title when file is temporary selected by ring_more dialog. On final ; selection, when the dialog is closed, the date is updated. ; -> won't (can't) fix. ; --------------------------------------------------------------------------- ; Compare args with statusfieldflags and titlefieldflags. If they match, ; RefreshStatusLine and/or RefreshTitleText is executed. defc RefreshInfoLine universal statusfieldflags universal titlefieldflags universal loadstate universal infolinerefresh -- disable refresh of infolines if = 0 do once = 1 to 1 -- This must not be processed too early, otherwise EPM init fails. -- loadstate is set to 1, 2 and 0 at loading the first file. Before -- that, loadstate is empty. if loadstate = '' then leave endif if not .visible then leave endif if infolinerefresh = 0 then leave endif Flags = arg( 1) -- Todo: 'FILE' should not redetermine to make 'quit' -- process faster -- Init list of flags -- Following is only called if the universal vars were empty: if statusfieldflags = '' then call GetStatusFields() endif if titlefieldflags = '' then call GetTitleFields() endif do w = 1 to words( Flags) Flag = word( Flags, w) if wordpos( upcase( Flag), upcase( statusfieldflags)) > 0 then 'RefreshStatusLine' leave endif enddo do w = 1 to words( Flags) Flag = word( Flags, w) if wordpos( upcase( Flag), upcase( titlefieldflags)) > 0 then 'RefreshTitleText' leave endif enddo enddo ; --------------------------------------------------------------------------- ; RefreshStatusLine refreshes the statusline with the current values. ; ; This defc is required, if the statusbar template should contain ; non-standard fields (without a '%'). Then it doesn't suffice to set the ; universal var current_status_template or the const STATUS_TEMPLATE. ; ; Calling refreshstatusline as a defselect theoretically means a little ; overhead, comparing with the internal mechanism of the E toolkit. ; ; Currently it overwrites the setting made by STATUS_TEMPLATE. ; ; Known bug: ; When selecting a file from the 'Files in Ring' listbox, the statusbar ; is not refreshed. The refresh is only processed after the listbox ; is closed. ; Against this, the internal defined statusbar fields (all values with a '%') ; are refreshed immediately. ; ; Standard EPM statusline fields: ; %A Autosave count value (number of changes made to the file since the last ; autosave) ; %C current Column number ; %F number of Files in ring (followed by the word "File" or "Files") ; %I Insert or replace state (cursor status) ; %L current Line number ; %M Modified status (if the file has been modified) ; %S total number of lines in the current file ; %X displays the hexadecimal value of the current character ; %Z displays the ASCII value of the current character ; ; In contrast to the docs, the default value if STATUS_TEMPLATE was ; not defined as: 'Line %l of %s Column %c %i %m %f' defc RefreshStatusLine if .visible then 'SetStatusLine 'GetStatusFields() endif -- .visible return ; --------------------------------------------------------------------------- ; Determine fields and flags for statusline. Return resolved statusline ; fields containing only '%' fields or strings. defproc GetStatusFields universal statusfieldflags universal statusfields -- Note: The length for the StatusLine string is limitted. if statusfields = '' then KeyPath = '\NEPMD\User\Appearance\InfoLine\Status\Template' statusfields = QueryConfigKey( KeyPath) endif ResolvedFields = ResolveInfoFields( statusfields, Flags) -- Add 'MODIFIED' flag for StatusLine to update color if wordpos( 'MODIFIED', Flags) = 0 then Flags = Flags' MODIFIED' endif -- Add 'FILE' flag for StatusLine to update file-specific fields, -- that are not refreshed internally (mode, margins, tabs, ...) -- 'refreshinfoline FILE' is called by defload, save, defselect). if wordpos( 'FILE', Flags) = 0 then Flags = Flags' FILE' endif statusfieldflags = Flags return ResolvedFields ; --------------------------------------------------------------------------- ; Determine fields and flags for titletext. Return resolved titletext fields. defproc GetTitleFields universal titlefieldflags universal titlefields if titlefields = '' then KeyPath = '\NEPMD\User\Appearance\InfoLine\Title\Template' titlefields = QueryConfigKey( KeyPath) endif ResolvedFields = ResolveInfoFields( titlefields, Flags) titlefieldflags = Flags return ResolvedFields ; --------------------------------------------------------------------------- ; Determine separator for statusline and titletext. defproc GetFieldSep universal fieldsep if FieldSep = '' then KeyPath = '\NEPMD\User\Appearance\InfoLine\Sep' fieldsep = QueryConfigKey( KeyPath) endif return fieldsep ; --------------------------------------------------------------------------- defc ResetStatusFields universal statusfields statusfields = '' call GetStatusFields() -- set universal vars defc ResetTitleFields universal titlefields titlefields = '' call GetTitleFields() -- set universal vars defc ResetFieldSep universal FieldSep FieldSep = '' ; --------------------------------------------------------------------------- ; Standard EPM %... patterns may be used here too for compatibility. ; The string '' will be replaced by its value. ; Therefore a new escape char pair '<' and '>' is introduced (at the ; start and end of an info field var). ; See defproc GetInfoFieldValue for all new defined info field vars. ; A single '*' is replaced by the definition for the separator. ; To get a '*' char, it must be escaped by another '*': '**' gives '*' ; To get a '<' char, it must be escaped by another '<': '<<' gives '<' ; To get a '>' char, it must be escaped by another '>': '>>' gives '>' defproc ResolveInfoFields( Fields, var Flags) Flags = '' -- replace separator chars '*' with '' startp = 1 do forever p = pos( '*', Fields, startp) if not p then leave endif if substr( Fields, p + 1, 1) = '*' then -- if '*' is escaped by another '*', gobble the 2nd Fields = substr( Fields, 1, p) || substr( Fields, p + 2) startp = p + 1 else -- if a single '*', then it is a separator Fields = substr( Fields, 1, p - 1) || '' || substr( Fields, p + 1) startp = p + length( '') endif enddo -- forever -- resolve '<...>' for 'setstatustemplate' command startp = 1 do forever -- find '<' p1 = pos( '<', Fields, startp) if not p1 then leave endif -- find '<<' at p1 and replace '<<' with '<' if substr( Fields, p1, 2) = '<<' then Fields = substr( Fields, 1, p1) || substr( Fields, p1 + 2) startp = p1 + 1 else startp = p1 + 1 -- find '>' p2 = pos( '>', Fields, startp) if not p2 then leave endif -- don't replace '>>' if substr( Fields, p2, 2) = '>>' then startp = p2 + 2 else -- resolve var '<...>' FValue = GetInfoFieldValue( substr( Fields, p1 + 1, p2 - p1 - 1), FFlag) Fields = substr( Fields, 1, p1 - 1) || FValue || substr( Fields, p2 + 1) if (FFlag <> '' & wordpos( FFlag, Flags) = 0) then Flags = Flags' 'FFlag endif startp = p1 + length( FValue) endif endif enddo -- forever -- replace '>>' with '>' startp = 1 do forever p = pos( '>>', Fields, startp) if p then Fields = substr( Fields, 1, p) || substr( Fields, p + 2) startp = p + 1 else leave endif enddo Flags = strip( Flags) return Fields ; --------------------------------------------------------------------------- ; Helper for defproc GetInfoFieldValue. ; Now always return the filename. If .LONGNAME display is active, the EA ; exists and is different from short name, append it enclosed in parens. defproc GetFileName universal show_longnames do once = 1 to 1 Filename = .filename if leftstr( Filename, 1) = '.' then -- if a temp file leave endif if not show_longnames then leave endif Longname = get_EAT_ASCII_value( '.LONGNAME') if Longname = '' then leave endif lp = lastpos( '\', Filename) if lp = 0 then leave endif FileDir = leftstr( Filename, lp - 1) Shortname = substr( Filename, lp + 1) if Shortname = Longname then leave endif --Filename = FileDir'\'Longname' ('Shortname')' Filename = Filename' ('Longname')' enddo return Filename ; --------------------------------------------------------------------------- ; Replace info field vars with '%...' or other values defproc GetInfoFieldValue( FVar, var FFlag) universal stream_mode universal expand_on universal matchtab_on universal activeaccel -- Get Sep Sep = GetFieldSep() FVar = upcase( FVar) FValue = '' FFlag = '' -- Synonyms: if FVar = 'MARGINS' then FVar = 'MA' elseif FVar = 'MOD' then FVar = 'MODIFIED' elseif FVar = 'LOCK' then FVar = 'LOCKED' elseif FVar = 'NAME' then FVar = 'FILENAME' elseif FVar = 'DTMOD' then FVar = 'DATETIMEMODIFIED' elseif FVar = 'STREAM' then FVar = 'STREAMMODE' elseif FVar = 'LINEMODE' then FVar = 'STREAMMODE' elseif FVar = 'SYNTAX' then FVar = 'EXPAND' elseif FVar = 'SYNTAXEXPANSION' then FVar = 'EXPAND' elseif FVar = 'EXPANDMODE' then FVar = 'EXPAND' elseif FVar = 'ADVANCEDMARKING' then FVar = 'MARKINGMODE' elseif FVar = 'CUAMARKING' then FVar = 'MARKINGMODE' elseif FVar = 'KEYS' then FVar = 'KEYSET' elseif FVar = 'SPELLCHECK' then FVar = 'DYNASPELL' elseif FVar = 'SPELL' then FVar = 'DYNASPELL' elseif FVar = 'DICTLANG' then FVar = 'DICT' elseif FVar = 'ENC' then FVar = 'ENCODING' endif if FVar = 'SEP' then FValue = Sep -- Internal refreshed fields elseif FVar = 'LINES' then FValue = '%S' elseif FVar = 'LINE' then FValue = '%L' elseif FVar = 'COL' then FValue = '%C' elseif FVar = 'HEX' then FValue = '%X' elseif FVar = 'DEC' then FValue = '%Z' --elseif FVar = 'INS' then FValue = '%I' -- Insert | Replace elseif FVar = 'INS' then FValue = word( 'OVR INS', insertstate() + 1) FFlag = 'INS' -- non-percent values need an extra refresh elseif FVar = 'MODIFIED' then FValue = '%M' elseif FVar = 'AUTOSAVE' then FValue = '%A' ; elseif FVar = '' then FValue = '%F' -- better use filesinring() to customize the text part -- Additional fields elseif FVar = 'FILE' then FValue = GetFileNumber() FFlag = 'FILELIST' elseif FVar = 'FILES' then FValue = filesinring() FFlag = 'FILELIST' elseif FVar = 'MODE' then FValue = GetMode() FFlag = 'MODE' elseif FVar = 'MA' then FValue = .margins FFlag = 'MARGINS' elseif FVar = 'TABS' then FValue = word( .tabs, 1 ) -- show only 1st tab FFlag = 'TABS' elseif FVar = 'MATCHTAB' then FValue = word( '- match', (matchtab_on = 1) + 1) -- show '-' or 'match' FFlag = 'MATCHTAB' elseif FVar = 'LOCKED' then FValue = word( 'L -', (.lockhandle = 0) + 1) -- show 'L' or '-' FFlag = 'LOCKED' elseif FVar = 'READONLY' then FValue = word( '- R', (.readonly = 0) + 1) -- show 'R' or '-' FFlag = 'READONLY' elseif FVar = 'FILENAME' then FValue = GetFileName() FFlag = 'FILE' elseif FVar = 'DATETIME' then FValue = NepmdQueryPathInfo( .filename, 'MTIME') -- show YYYY/MM/DD HH:MM:SS from file on disk FFlag = 'FILE' elseif FVar = 'ATTR' then FValue = NepmdQueryPathInfo( .filename, 'ATTR') -- show 'ADSHR' or '-----' FFlag = 'FILE' elseif FVar = 'SIZE' then FValue = NepmdQueryPathInfo( .filename, 'SIZE') -- show size in bytes FFlag = 'FILE' elseif FVar = 'EASIZE' then FValue = NepmdQueryPathInfo( .filename, 'EASIZE') -- show size of EAs in bytes FFlag = 'FILE' elseif FVar = 'DATETIMEMODIFIED' then FValue = GetDateTimeModified() -- show date - time or modified or other infos FFlag = 'MODIFIED' elseif FVar = 'STREAMMODE' then FValue = word( 'L S', (stream_mode = 1) + 1) -- show 'S' or 'L' FFlag = 'STREAMMODE' elseif FVar = 'EXPAND' then DisplayText = GetExpandMode() if DisplayText = '' then DisplayText = 'no exp.' else CodingStyle = GetCodingStyle() if CodingStyle then DisplayText = DisplayText' ('CodingStyle')' endif endif FValue = DisplayText FFlag = 'EXPAND' elseif FVar = 'MARKINGMODE' then CurrentMarkingMode = QueryMarkingMode() FValue = word( 'Adv CUA User', (CurrentMarkingMode = 'A') + 2 * (CurrentMarkingMode = 'C') + 3 * (not wordpos( CurrentMarkingMode, 'A C'))) -- show 'Adv' or 'CUA' or 'User' FFlag = 'MARKINGMODE' elseif FVar = 'KEYSET' then FValue = activeaccel' = 'GetKeysAVar( 'keyset.'activeaccel) FFlag = 'KEYSET' elseif FVar = 'CODINGSTYLE' then FValue = GetCodingStyle() FFlag = 'FILE' elseif FVar = 'DYNASPELL' then FValue = word( '- Spchk', (activeaccel = 'spell') + 1) -- show '-' or 'Spchk' FFlag = 'KEYS' elseif FVar = 'DICT' then FValue = GetDictBaseName() FFlag = 'DICT' elseif FVar = 'ENCODING' then FValue = GetEncoding() FFlag = 'ENCODING' ; Not fully implemented yet, just for testing: elseif FVar = 'SECTION' & isadefproc( 'GetCurSection') then FValue = GetCurSection() -- shows current section or function endif return FValue ; --------------------------------------------------------------------------- ; Called with a string to set the statusline text to that string; with no ; argument to just set the statusline color. defc SetStatusLine universal vstatuscolor universal vmodifiedstatuscolor universal vreadonlystatuscolor universal current_status_template if .modify = 0 then if .readonly then newstatuscolor = vreadonlystatuscolor else newstatuscolor = vstatuscolor endif else newstatuscolor = vmodifiedstatuscolor endif if arg( 1) then current_status_template = arg( 1) template = atoi( length( current_status_template)) || current_status_template template_ptr = put_in_buffer( template) else template_ptr = 0 endif call windowmessage( 1, getpminfo( EPMINFO_EDITCLIENT), 5431, -- EPM_FRAME_STATUSLINE template_ptr, newstatuscolor) ; --------------------------------------------------------------------------- ; Called with a string to set the messageline text to that string. That text ; will be diplayed until the next message text is set. The timer won't apply ; here. Additionally, the message text won't be saved to the message box. So, ; using an arg is not very useful. When called with no argument, the ; messageline color is just set. defc SetMessageLine universal vmessagecolor if arg( 1) then template = atoi( length( arg( 1))) || arg( 1) template_ptr = put_in_buffer( template) else template_ptr = 0 endif call windowmessage( 1, getpminfo( EPMINFO_EDITCLIENT), 5432, -- EPM_FRAME_MESSAGELINE template_ptr, vmessagecolor) ; --------------------------------------------------------------------------- ; This is executed at defmodify. It was moved to a cmd to control the ; execution time (omit it) by defmodify. See MODIFY.E. ; defmodify is triggered ; 1) when .modify changes from 0 to > 0 ; 2) when .modify changes from < .autosave to >= .autosave ; 3) when .modify changes from > 0 to 0 ; 4) when a modified file is selected after a non-modified file ; 5) when a non-modified file is selected after a modified file ; The universal var ModifyDisabled can be used to disable defmodify ; processing. Since defmodify code is used at several places, the execution ; of the defmodify code has also be checked for this universal var at all ; these places to disable them all. defc InfolineModify universal lastselectedfid universal infolinerefresh -- Disable refresh of infolines if = 0 do once = 1 to 1 getfileid fid -- Don't process the following on file switching if fid <> lastselectedfid then leave endif if infolinerefresh = 0 then leave endif fModifiedChanged = 0 -- Get last saved value of array var next = GetAVar( fid'.datetimemodified') -- No need for a refresh if modified state hasn't changed if (next <> 'Modified' & .modify > 0) then fModifiedChanged = 1 elseif (next = 'Modified' & .modify = 0) then fModifiedChanged = 1 endif if fModifiedChanged then -- Update info lines 'RenewDateTimeModified' 'RefreshInfoLine MODIFIED' endif enddo ; --------------------------------------------------------------------------- ; Executed by ProcessFileSwitched, using the postfileswitched hook. defc ProcessSelectRefresh universal datetimecheckdisabled if datetimecheckdisabled then return elseif not .visible then return endif --drintf( 'ProcessSelectRefresh: executing RefreshInfoLine -- '.filename) --dprintf( 'Select: RenewDateTimeModified for '.filename) 'RenewDateTimeModified' -- required to check file on disk Flags = 'TABS MATCHTAB MODE MARGINS FILE SECTION MODIFIED' || ' STREAMMODE EXPAND MARKINGMODE KEYSET' 'RefreshInfoLine' Flags ; --------------------------------------------------------------------------- ; Add cmd to hook. definit -- PostMe required to popup the MsgBox after switching the file. Cmd = 'PostMe ProcessSelectRefresh' 'HookAdd postfileswitched 'Cmd ; --------------------------------------------------------------------------- ; Moved defproc settitletext() from STDCTRL.E to INFOLINE.E ; See also: MODIFY.E (SHOW_MODIFY_METHOD), ; call show_modify() is obsolete (SELECT.E in epmbbs only) ; See also: STDCMDS.E, defc n,name ; See also: STDCMDS.E, defc s,save ; See also: ENTER.E, def c_enter, c_pad_enter= /* 旼컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴커 � what's it called: settitletext � � � � what does it do : set the text in the editors active title bar. � � � 읕컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴켸 */ ; unused defproc SetTitleText() text = arg( 1) ;compile if SHOW_MODIFY_METHOD = 'TITLE' -- obsolete ; if .modify then ; text = text || SHOW_MODIFY_TEXT ; endif ;compile endif .titletext = text return ; --------------------------------------------------------------------------- defc SetTitleText --call NepmdPmPrintf( 'SETTITLETEXT called with' arg( 1)', hwnd = 0x'ltoa( gethwndc(6), 16)) .titletext = arg( 1) --refresh -- Required when altered file was selected with the 'List ring' dialog. -- Otherwise titletext will be updated just on the next (internal) refresh, -- while messageline shows the text 'Altered by another application' -- correctly. -- Disabled, because it slows file loading down. ; --------------------------------------------------------------------------- defc RefreshTitleText 'SetTitleText 'GetTitleFields() ; --------------------------------------------------------------------------- const compile if not defined( SLOW_DRIVES) SLOW_DRIVES = 'A: B:' compile endif compile if not defined( SLOW_FILESYSTEMS) SLOW_FILESYSTEMS = 'CDFS UDF' compile endif defc RenewDateTimeModified universal infolinerefresh -- Disable refresh of infolines if = 0 universal datetimecheckdisabled do once = 1 to 1 ThisDrive = upcase( substr( .filename, 1, 2)) if infolinerefresh = 0 then leave -- Don't act on files from slow drives or if file is readonly elseif .readonly then leave elseif browse() then leave elseif FileShouldBeDiscarded() then leave elseif IsARestartFile() then leave elseif datetimecheckdisabled then leave elseif wordpos( ThisDrive, SLOW_DRIVES) then leave elseif wordpos( QueryFileSys( ThisDrive), SLOW_FILESYSTEMS) then leave else /* -- Better avoid additional disk access -- If .readonly is deactivated (standard in EPM) rcx = qfilemode( .filename, attrib) -- DosQFileMode --dprintf( 'RenewDateTimeModified: qfilemode for '.filename) if not rcx then readonly = (attrib // 2) if readonly then leave endif endif */ endif -- Redetermine DateTime and save it in array var --dprintf( '** RenewDateTimeModified, '.filename) Msg = '' DateTime = '' ArrayVal = '' Filename = .filename getfileid fid fAlteredOnDisk = 0 PrevDateTimeRc = GetAVar( fid'.lastdatetimerc') KeyPath = '\NEPMD\User\AlteredOnDisk\Check' fCheckForAlteredOnDisk = QueryConfigKey( KeyPath) LoadFileDateHex = ltoa( substr( .fileinfo, 9, 4), 16) -- If modified if .modify > 0 then -- Display text instead of DateTime DateTime = 'Modified' -- If virtual elseif IsVirtual( Filename) then DateTime = '' -- Restart tree - this is used as temp. filename for virtual files elseif IsARestartFile( Filename) then DateTime = '' -- Renamed, moved or deleted files elseif not Exist( Filename) & pos( ':\', Filename) then rc = 2 Msg = 'New file' DateTime = Msg -- Check disabled elseif not fCheckForAlteredOnDisk then PrevDateTimeModified = GetAVar( fid'.datetimemodified') -- If 'Modified' is displayed but file isn't modified (anymore) if (PrevDateTimeModified = 'Modified' & not .modify) | -- If array var is empty on file loading (PrevDateTimeModified = '') then -- Apply initial DateTime DateTime = FileDateHexToIsoDate( LoadFileDateHex) else -- Keep previous ArrayVal leave endif -- Check enabled, not modified, not virtual and existing etc. else NewFileDateHex = GetFileDateHex( Filename) if not rc then if NewFileDateHex <> LoadFileDateHex then -- File was altered by another application fAlteredOnDisk = 1 Msg = 'Altered by another application' endif if Msg = '' then DateTime = FileDateHexToIsoDate( NewFileDateHex) endif elseif rc = 2 then Msg = 'New file' --'File not found' elseif rc = 3 then Msg = 'Path not found' elseif rc = 6 then Msg = 'Invalid handle' elseif rc = 15 then Msg = 'Drive not valid' elseif rc = 18 then Msg = 'No more files' elseif rc = 21 then Msg = 'Drive not ready' elseif rc = 26 then Msg = 'Unknown media type' elseif rc = 87 then Msg = 'Invalid parameter' elseif rc = 108 then Msg = 'Drive locked' elseif rc = 111 then Msg = 'Buffer overflow' elseif rc = 113 then Msg = 'No more search handles' elseif rc = 206 then Msg = 'Filename exceeds range' else Msg = 'DosQueryPathInfo: rc = 'rc endif endif -- Output on messageline if Msg <> '' then -- Give that message only once per fileid, until rc changes if PrevDateTimeRc <> rc then SetAVar( fid'.lastdatetimerc', rc) 'SayError 'Filename': 'Msg endif endif if fAlteredOnDisk & PrevDateTimeRc <> rc then KeyPath1 = '\NEPMD\User\AlteredOnDisk\MessageBoxOnChange' KeyPath2 = '\NEPMD\User\AlteredOnDisk\AutoReload' KeyPath3 = '\NEPMD\User\AlteredOnDisk\AutoReadonly' if QueryConfigKey( KeyPath1) = 1 then -- Message box with opportunity to reload if altered on disk -- Complete file switching first, to popup the MsgBox with the -- correct file in background. refresh 'AlteredMsgBox' elseif QueryConfigKey( KeyPath2) = 1 then -- Auto-reload if altered on disk 'Revert' elseif QueryConfigKey( KeyPath3) = 1 then -- Auto-read-only if altered on disk .readonly = 1 endif endif -- Save DateTime or Msg as array var if Msg <> '' then -- Msg set ArrayVal = Msg elseif DateTime <> '' then -- DateTime set ArrayVal = DateTime else -- Msg and DateTime empty -- ArrayVal must be set to make the following GetDateTimeModified -- avoid the execution of RenewDateTimeModified ArrayVal = '-empty-' endif call SetAVar( fid'.datetimemodified', ArrayVal) enddo ; --------------------------------------------------------------------------- defproc GetDateTimeModified getfileid fid ArrayVal = GetAVar( fid'.datetimemodified') -- ArrayVal unset: if ArrayVal = '' then 'RenewDateTimeModified' endif ArrayVal = GetAVar( fid'.datetimemodified') --dprintf( 'GetDateTimeModified, '.filename', ArrayVal = 'ArrayVal) -- ArrayVal must be set to make GetDateTimeModified avoid the -- execution of RenewDateTimeModified again if ArrayVal = '-empty-' then DateTime = '' else DateTime = ArrayVal endif return DateTime ; --------------------------------------------------------------------------- ; PM Message box with opportunity to reload. Executed if altered on disk. defc AlteredMsgBox Title = 'Filedate changed' Text = '' Text = Text'"'.filename'"'\n Text = Text'was altered on disk by another application.'\n\n Text = Text'Reload it?' Style = MB_OKCANCEL + MB_ICONQUESTION + MB_MOVEABLE rcx = WinMessageBox( Title, Text, Style) if rcx = MBID_OK then 'PostMe Revert' endif ; --------------------------------------------------------------------------- defc ConfigInfoLine Type = upcase( arg( 1)) if Type = 'TITLE' then KeyPath = '\NEPMD\User\Appearance\InfoLine\Title\Template' Title = 'Enter new string for titletext fields' Text = 'Put the field names in <...> chars.' || ' Specify * as separator.' Cmd = 'mc /ResetTitleFields/RefreshTitleText' -- The following uses only internally defined fields and -- therefore avoids the overhead for additional refreshs Standard = '' elseif Type = 'STATUS' then KeyPath = '\NEPMD\User\Appearance\InfoLine\Status\Template' Title = 'Enter new string for statusline fields' Text = 'Put the field names in <...> chars.' || ' Specify * as separator.' Cmd = 'mc /ResetStatusFields/RefreshStatusLine' -- The following uses only internally defined fields and -- therefore avoids the overhead for additional refreshs --Example = "Line of * Col * 0x= * * Tabs , * - * * * * * " --Standard = "Line of * Column * * File(s)" Standard = "Line %l of %s Column %c %i %m %f" elseif Type = 'SEP' then KeyPath = '\NEPMD\User\Appearance\InfoLine\Sep' Title = 'Enter new string as separator between fields' Text = 'Default char is \250.' || ' Surround it with spaces for a poportional font.' Cmd = 'mc /ResetFieldSep/RefreshTitleText/RefreshStatusLine' Standard = ' ' else 'SayError ConfigInfoLine: Error: Unknown parameter "'Type'".' return endif IniValue = QueryConfigKey( KeyPath) parse value EntryBox( Title, '/~Set/~Reset/Standard ~EPM/'CANCEL__MSG, IniValue, 400, 260, atoi( 1) || atoi( 0) || -- help id gethwndc( APP_HANDLE) || Text) with Button 2 NewValue \0 if Button = \1 then WriteConfigKey( KeyPath, NewValue) elseif Button = \2 then DeleteConfigKey( KeyPath) elseif Button = \3 then WriteConfigKey( KeyPath, Standard) elseif Button = \4 then return endif if not rc then Cmd endif