// // DI1-PAGER.VDM Christian Ziemski 21.08.2003 // 24.08.2003 // // Dialog with pageable text of free length. // For more documentation see at end of this macro. // // Interface: // ------------------------------------ // $103 Name of textfile to display // $104 Label to start with (optional) // $105 title to display instead of the one define in line 1 of textfile (optional) // ------------------------------------ // // Internally used and restored at end: // ------------------------------------ // #90 temp line # // #91 max. number of lines to display at once (longer paragraphs are split to this size) // #92 flag whether the text to display is already open // #93 Cur_Pos // #94 Buf_Num of original text // #95 Buf_Num of text to display // #96 temp // temp Cur_Pos // #97 length of longest paragraph // #98 temp length of longest line // temp Cur_Line // temp lines of paragraph // #99 temp Button# of DI1() // // $94 title line // $95 button label // $96 current paragraph // $97 line of underscores // $98 paragraph label // ------------------------------------ if (OS_Type != 1) { Statline_Message("Sorry, this macro requires VEDIT for Windows.") return } if (Reg_Size(103) > 0){ if (! File_Exist('"|@(103)"')) { Dialog_Input_1(103,"`Error`, `The file '|@(103)' was not found.`", SCREEN+CENTER,0,0) return } } Num_Push(90,99) // save used registers Reg_Push(94,99) #91=10 // max. number of lines to display at once // longer paragraphs are split to this size #94=Buf_Num // current text if (Reg_Size(103) > 0){ #92=File_Check('"|@(103)"') // is file to display already open? if (#92 != -1) { // yes: switch to it Buf_Switch(#92) File_Save(NOMSG) // o.k.? #93=Cur_Pos // remember Cursor_Position } else { // no: load it Buf_Switch(Buf_Free(EXTRA)) File_Open('"|@(103)"', NOEVENT+FORCE) } } else { // if no filname was given: show help Buf_Switch(Buf_Free(EXTRA)) Call("GETHELP") Reg_Ins(103) Reg_Empty(103) } #95=Buf_Num // text to display BoF Reg_Copy_Block(94,0, Max(EoL_Pos, 30)) // get title line if ((Reg_Size(105) > 0) && (Reg_Size(105) < 30)) { // possibly overwrite it Reg_Set(94, @105) } // Delete 1st paragraph containing title and optional comments Search("|<--", NOERR) if (!EM) { Del_Block(0,Cur_Pos) } // For security; to prevent DI1() from beeing killed - but not foolproof! Replace("`","'", BEGIN+ALL+NOERR) Replace("||","!", BEGIN+ALL+NOERR) // remove trailing blanks Replace("|W|>", "", BEGIN+ALL+NOERR) // Remove trailing blank lines just before and after a -- and before EoF Replace("|X|<--", "|N--", BEGIN+ALL+NOERR) BoF repeat (ALL) { Search("|<--", NOERR+ERRBREAK) Line(1) #98=Cur_Pos Search("|!|X", NOERR) BoL Del_Block(#98, Cur_Pos) } EoF Search("|!|X", REVERSE+NOERR) Line(1, NOERR) Del_Block(Cur_Pos, File_Size) // Make backslashes usable Replace("\","\\", BEGIN+ALL+NOERR) // find longest line #98=0 BoF while (! At_EoF) { EoL if (Cur_Col > #98) { #98=Cur_Col } Line(1, NOERR) } // Create a line of underscores of (hopefully) appropriate length // to size the dialog's width. // (Due to the used proportional font it's only guessing!) BoF Ins_Char(95, COUNT, Max(37,#98)) Ins_Newline(1) BoF Reg_Copy(97, 1) Del_Line(1) // find longest "paragraph" ==> #97 BoF #97=0 #96=Cur_Line while (! At_EoF) { Search("|<--", NOERR+NORESTORE) if ((Cur_Line - #96) > #97) { #97=Cur_Line - #96 } Line(1, NOERR+ERRBREAK) #96=Cur_Line } BoF if (Reg_Size(104) > 0) { // goto starting label (if any) Search("|<--|@(104)", NOERR) } // scroll through the text Reg_Set(95, "&Next") // button label while (! At_EoF) { if (Match("|<--") == 0) { // if on label Call("GetLabel") Line(1) } #96=Cur_Pos #98=Cur_Line Search("|<--", NOERR+NORESTORE) // search next label (and so the end of the current one) #98=Cur_Line - #98 // number of lines of current paragraph from Cur_Pos on if (#98 > #91) { // if exceeds max # of lines Line(#91-#98) // go up the difference #98=#91 // set current length to max. } Reg_Copy_Block(96, #96, Cur_Pos) // text of current paragraph // Add appropriate number of NewLines to a copy of the current paragraph // to make they all the same number of lines on display Buf_Switch(Buf_Free(EXTRA)) Reg_Ins(96) EoF Ins_Newline(Min(#97,#91) - #98) Reg_Copy_Block(96, 0, ALL) Buf_Quit(OK) Buf_Switch(#95) if (At_EoF) { // change the button label if at EoF Reg_Set(95, "E&nd") } #99=Dialog_Input_1(94,^`|@(94) |@(98)`, `|@(96)`, `|@(97)`, `[&Previous]`,`.i[|@(95)]`,`[&Cancel]`^,SET+APP+CENTER,0,0) if (#99 == 1) { // [Previous] Reg_Set(95, "&Next") #96=Cur_Pos Line(-1, NOERR) #90=Cur_Line Search("|<--", REVERSE+NOERR+NORESTORE) if ((#90-Cur_Line) > #91) { // current label more than max lines away? Goto_Pos(#96) Line(-#98) // if yes: last lines up Line(-#91) // and max lines up } else { Line(-1, NOERR) Search("|<--", REVERSE+NOERR+NORESTORE) if(! EM) { Call("GetLabel") Line(1) } } continue } if (#99 != 2) { // not [Next] break } } if (#92 == -1) { // if file was not already open Buf_Quit(OK) // simply quit it now } else { // otherwise: File_Quit(OK) Buf_Switch(#95) // reload to undo changes File_Open('"|@(103)"', NOEVENT) Goto_Pos(#93) } Buf_Switch(#94) // back to original buffer Reg_Pop(94,99) // restore used std. registers Num_Pop(90,99) Reg_Empty(103) // empty "local" registers; o.k. ? Reg_Empty(104) Reg_Empty(105) return(0, Delete) //--------------------------------------------------------------- // get a label and let it add to the title text :GetLabel: Reg_Empty(98) Char(2) if (! At_EoL) { Reg_Set(98, " [") Reg_Copy_Block(98, Cur_Pos, EoL_Pos, APPEND) // restrict?! Reg_Set(98, "]", APPEND) } return //--------------------------------------------------------------- :GETHELP: Reg_Set(103, ^Online-Help for DI1-PAGER.VDM This is version 1.1 24.08.2003 Written by Christian Ziemski Hopefully this help makes the macro easily usable. ;-) --Start *** This is DI1-PAGER.VDM *** This macro generates a dialog window with free text out of a text file of any length. You can page forward/backward through this text. So you can implement an advanced popup (e.g. for help infos or the like). Using the optional labels and title described below it is flexible to be called with different starting points. --Usage 1/2 *** How to use this macro *** The text to be displayed is loaded from a file. The filename is passed via T-Reg 103 to this macro. T-Reg 104 can contain an optional paragraph label to jump to ("--label") T-Reg 105 can contain an optional title which is used instead of the title defined in the very first line of the text file. --Usage 2/2 So a typical call could be: Reg_Set(103, "C:\Data\Infotext.txt") Reg_Set(104, "Usage") Call_File(Reg_Free, "DI1-PAGER.VDM") If T-Reg 103 is empty this help is displayed. --file format *** How to format the text file *** The first line contains the title of the dialog. The following lines up to the first -- at BoL are comments that are not displayed. Then there are one or more paragraphs beginning with a -- at BoL followed by an optional label ("--label") Empty lines just before and just after the line with -- are ignored. (Files without those labels are displayed as continuous text without any special paragraph handling.) Look into the macro itself. At the end you can see this help text in "source format". --paragraph Due to those special "paragraphs" of text it's possible to have empty lines in the text to make it better readable. Every paragraph is displayed in one dialog window if possible. The maximum size in lines of the window can be defined in the beginning of the macro. Longer paragraphs are then split into parts. Moving forward/backward pages through these parts. But if you are on the beginning of a paragraph a "move back" jumps to the beginning of the previous paragraph and not to the (possibly) last part of it. --Last *** Have fun with this macro! *** If you find any problem or would like to place a suggestion: Let me know! Christian -- ChZiemski [at] bigfoot [dot] com ^) return //=============================================================================