Changeset 3387


Ignore:
Timestamp:
Dec 28, 2018, 7:30:21 PM (6 years ago)
Author:
Andreas Schnellbacher
Message:
Location:
trunk/src/netlabs/macros
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/netlabs/macros/bookmark.e

    r3386 r3387  
    4545
    4646; ---------------------------------------------------------------------------
    47 ; Used array vars:
    48 ;    bm = bookmark
    49 ;       'bmname.'bmfid'.0'      max. bmidx
    50 ;       'bmname.'bmfid'.'bmidx  bmname
    51 ;    style
    52 ;       'stylename.0'            max. styleidx
    53 ;       'stylename.'styleidx     stylename
    54 ;       'styleindex.'stylename   styleidx
     47; o  Following atrribute classes are used:
     48;       COLOR_CLASS     =  1
     49;       PAGEBREAK_CLASS =  6
     50;       BOOKMARK_CLASS  = 13
     51;       STYLE_CLASS     = 14
     52;       FONT_CLASS      = 16
     53;    Additional user classes can be created.
     54; o  Some attributes are saved as EAs. Additionally, each file has a field
     55;    var .EAarea that holds EA info. Save calls SaveAttributes, reads
     56;    attributes and array vars and merges them to .EAarea. .EAarea is then
     57;    converted to EAs.
     58; o  Changed EA info may be saved immediately to disk. But it must always
     59;    be saved to .EAarea to preserve that info on Save.
     60; o  Some EAs are read on Edit (file opening) by LoadAttributes. They are
     61;    converted to attributes. Addtional info is saved as array vars.
     62; o  Attributes can only store integer numbers, not strings. Therefore they
     63;    have to be extended with array vars for bookmark names and font/color
     64;    style names. Bookmark names are file-specific. Style names are global
     65;    for an EPM window. Style array vars are only created when they are
     66;    used. All existing styles are saved in NEPMD.INI.
     67; o  Used array vars:
     68;       bm = bookmark
     69;          'bmname.'bmfid'.0'       max. bmidx
     70;          'bmname.'bmfid'.'bmidx   bmname
     71;       style
     72;          'stylename.0'            max. styleidx
     73;          'stylename.'styleidx     stylename
     74;          'styleindex.'stylename   styleidx
    5575
    5676; ===========================================================================
     
    179199   do forever
    180200      class = 0  -- Find any class
    181       attribute_action 1, class, offst, col, line, startfid  -- 1 = FIND NEXT ATTR
    182       --dprintf( 'SaveAttributes: attribute_action 1 class = 'class', offst = 'offst', col = 'col', line = 'line', startfid = 'startfid)
     201      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line, startfid
     202      --dprintf( 'SaveAttributes: attribute_action FIND_NEXT_ATTR_SUBOP class = 'class', offst = 'offst', col = 'col', line = 'line', startfid = 'startfid)
    183203      if class = 0 then  -- No attribute found
    184204         leave
     
    457477
    458478; ===========================================================================
    459 ; Part 2: Bookmarks
     479; Part 2: Attributes
    460480; ===========================================================================
    461481
    462482; ---------------------------------------------------------------------------
    463 defproc InitBookmarks( bmfid)
    464    SetAvar( 'bmname.'bmfid'.0', '')
    465 
    466 ; ---------------------------------------------------------------------------
    467 defc SetBookmark
    468    bmname = arg( 1)
    469    bmperm = 3  -- 3 = non-permanent
    470    line = .line
    471    col  = .col
    472    call SetBookmark( bmperm, line, col, bmname)
    473 
    474 ; ---------------------------------------------------------------------------
    475 defc SetBookmarkP
    476    bmname = arg( 1)
    477    bmperm = 4  -- 4 = permanent
    478    line = .line
    479    col  = .col
    480    call SetBookmark( bmperm, line, col, bmname)
    481 
    482 ; ---------------------------------------------------------------------------
    483 defc Bm, SetMark
    484    parse arg bmperm line col bmname
    485    bmname = strip( bmname)
    486    call SetBookmark( bmperm, line, col, bmname)
    487 
    488 ; ---------------------------------------------------------------------------
    489 defproc SetBookmark( bmperm, line, col, bmname)
    490    if .readonly then
    491       sayerror READ_ONLY__MSG
    492       return
    493    endif
    494    if browse() then
    495       sayerror BROWSE_IS__MSG ON__MSG
    496       return
    497    endif
    498 
    499    if line = '' then
    500       line = .line
    501    endif
    502    if col = '' then
    503       col = .col
    504    endif
    505    if bmname = '' then
    506       Title = SETMARK__MSG
    507       Text  = SETMARK_PROMPT__MSG
    508       DefaultEntry = subword( textline( .line), 1, 7)
    509       KeyPath = '\NEPMD\Var\Bookmarks\LastSetMarkButton'
    510       DefaultButton = QueryConfigKey( KeyPath)
    511       if DefaultButton = 2 then  -- permanent
    512          -- nop
    513       else
    514          DefaultButton = 1
    515       endif
    516 
    517       parse value EntryBox( Title,
    518                             '/'Set__MSG'/'Setp__MSG'/'Cancel__MSG'/'Help__MSG'/',
    519                             DefaultEntry,
    520                             '',
    521                             200,
    522                             atoi( DefaultButton)  ||
    523                             atoi( 6020)           ||
    524                             GetHwndC( APP_HANDLE) ||
    525                             Text) with Button 2 bmname \0
    526 
    527       Button = asc( Button)
    528       if Button = 0 | Button = 3 then  -- Esc or Cancel
    529          return
    530       elseif Button = 2 then
    531          bmperm = 4  -- permanent
    532       else
    533          bmperm = 3  -- non-permanent
    534       endif
    535 
    536       -- Save selected button for next call
    537       WriteConfigKey( KeyPath, Button)
    538 
    539       if not bmname then
    540          --sayerror NOTHING_ENTERED__MSG
    541          'postme SetMark' bmperm line col bmname
    542          return
    543       endif
    544    endif
    545 
    546    oldmod = .modify
    547    -- Get bmfid
    548    getfileid bmfid
    549    -- Get bmidx
    550    bmidxmax = GetAVar( 'bmname.'bmfid'.0')  -- bmidxmax says how many bookmarks there are
    551    if bmidxmax = '' then
    552       bmidxmax = 0
    553    endif
    554    bmidx = bmidxmax + 1
    555 
    556    -- Insert attribute
    557    class = BOOKMARK_CLASS
    558    val   = bmidx  -- can't be used for bmname - only for numbers
    559    offst = 0
    560    insert_attribute class, val, bmperm, offst, col, line
    561    --dprintf( 'SetBookmark: After insert_attribute 'class', 'val', 'bmperm', 'offst', 'col', 'line)
    562    if bmperm = 4 then
    563       call Attribute_On( 8)  -- "Save attributes" flag
    564    else
    565       .modify = oldmod
    566    endif
    567 
    568    -- Write array var to save bookmark name
    569    --dprintf( 'SetBookmark: bmname = 'bmname)
    570    SetAVar( 'bmname.'bmfid'.'bmidx, bmname)  -- Store the bmname
    571    SetAVar( 'bmname.'bmfid'.0', bmidx)       -- Store back the new number
    572 
    573    return
    574 
    575 ; ---------------------------------------------------------------------------
    576 defproc DelBmArrayVars( bmfid)
    577    bmidx = arg( 2)
    578    if bmidx = '' then
    579       -- Find all array vars for bmfid
    580       bmidxmax = GetAVar( 'bmname.'bmfid'.0')
    581       do bmidx = 1 to bmidxmax
    582          -- Delete array var
    583          call SetAVar( 'bmname.'bmfid'.'bmidx, '')
    584       enddo
    585    else
    586       -- Delete array var
    587       call SetAVar( 'bmname.'bmfid'.'bmidx, '')
    588    endif
    589 
    590 ; ---------------------------------------------------------------------------
    591 defproc GetBmName( bmfid, bmidx)
    592    -- Get bmname from array var
    593    bmname = GetAVar( 'bmname.'bmfid'.'bmidx)  -- Query bmname
    594    return bmname
    595 
    596 ; ---------------------------------------------------------------------------
    597 defc Go, GoMark
    598    parse arg bmidx bmfid .
    599    fIndexFound = 0
    600    do once = 1 to 1
    601       if bmidx = '' then
    602          leave
    603       elseif not IsNum( bmidx) then
    604          leave
    605       elseif bmfid = '' then
    606          getfileid bmfid
    607       elseif not IsNum( bmfid) then
    608          leave
    609       endif
    610       fIndexFound = 1
    611    enddo
    612    if not fIndexFound then
    613       sayerror UNKNOWN_BOOKMARK__MSG
    614       return
    615    endif
    616 
    617    -- Switch to bmfid
    618    display -2
    619    activatefile bmfid
    620    display 2
    621    if rc then
    622       sayerror FILE_GONE__MSG BM_DELETED__MSG
    623       return
    624    endif
    625 
    626    -- Find attribute
    627    line  = 0
    628    col   = 1
    629    offst = 0
    630    fAttrFound = 0
    631    val = ''
    632    do forever
    633       class = BOOKMARK_CLASS
    634       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    635       if class = 0 then
    636          leave
    637       endif
    638       -- Query attribute to get val
    639       query_attribute class, val, ispush, offst, col, line
    640       if val <> bmidx then
    641          iterate
    642       endif
    643 
    644       fAttrFound = 1
    645       leave
    646    enddo
    647 
    648    if fAttrFound then
    649       -- Go to position
    650       .cursory = .windowheight % 2
    651       line
    652       .col = col
    653       'HighlightCursor'
    654    else
    655       sayerror BM_NOT_FOUND__MSG ITS_DELETED__MSG
    656    endif
    657 
    658 ; ---------------------------------------------------------------------------
    659 defc DeleteBm
    660    parse arg bmidx bmfid .
    661    fIndexFound = 0
    662    do once = 1 to 1
    663       if bmidx = '' then
    664          leave
    665       elseif not IsNum( bmidx) then
    666          leave
    667       elseif bmfid = '' then
    668          getfileid bmfid
    669       elseif not IsNum( bmfid) then
    670          leave
    671       endif
    672       fIndexFound = 1
    673    enddo
    674    if not fIndexFound then
    675       sayerror UNKNOWN_BOOKMARK__MSG
    676       return
    677    endif
    678 
    679    getfileid startfid
    680    -- Switch to bmfid
    681    display -2
    682    activatefile bmfid
    683    display 2
    684    if rc then  -- File no longer in ring - all done.
    685       return
    686    endif
    687 
    688    -- Find attribute
    689    line  = 0
    690    col   = 1
    691    offst = 0
    692    fAttrFound = 0
    693    val = ''
    694    do forever
    695       class = BOOKMARK_CLASS
    696       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    697       if class = 0 then
    698          leave
    699       endif
    700       -- Query attribute to get ispush and val
    701       query_attribute class, val, ispush, offst, col, line
    702       if val <> bmidx then
    703          iterate
    704       endif
    705 
    706       fAttrFound = 1
    707       leave
    708    enddo
    709 
    710    if fAttrFound then
    711       -- Delete attribute
    712       bmperm = ispush
    713       oldmod = .modify
    714       attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTRIBUTE
    715       -- attribute_action 16 changes class to 1 on deletion
    716       if bmperm <> 4 then
    717          .modify = oldmod
    718       endif
    719 
    720       sayerror BM_DELETED__MSG
    721    endif
    722 
    723    activatefile startfid
    724 
    725 ; ---------------------------------------------------------------------------
    726 ; Fill a string in a proportional font with spaces to line up with other
    727 ; strings of variable width. A number is right-aligned, other strings are
    728 ; left-aligned.
    729 defproc AlignPropStr( Str, MaxStrLen)
    730    Factor = arg( 3)
    731    if Factor = '' then
    732       Factor = 2.5
    733    endif
    734    NumSpc = Factor * (MaxStrLen - length( Str))
    735    -- Convert NumSpc to an integer
    736    parse value NumSpc with iNumSpc'.'rest
    737    -- Round iNumSpc
    738    if leftstr( rest, 1) >= 5 then
    739       iNumSpc = iNumSpc + 1
    740    endif
    741    Spc = copies( ' ', iNumSpc)
    742    if IsNum( Str) then
    743       return Spc''Str
    744    else
    745       return Str''Spc
    746    endif
    747 
    748 ; ---------------------------------------------------------------------------
    749 defc ListMark
    750 
    751    getfileid startfid
    752    -- Workaround: This avoids unwanted window scrolling of the previous file.
    753    'VSyncCursor'
    754 
    755    'xcom e /c .listbookmarks'
    756    if rc <> -282 then  -- -282 = sayerror( "New file")
    757       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc)
    758       return
    759    endif
    760    browse_mode = browse()     -- query current state
    761    if browse_mode then
    762       call browse( 0)
    763    endif
    764    .autosave = 0
    765    getfileid tmpfid
    766 
    767    display -2
    768    -- Query bookmarks
    769    curfidline = 1  -- default value for the listbox
    770    SetAVar( 'bmfidlist', '')
    771    do f = 1 to filesinring( 1)
    772       nextfile
    773       getfileid bmfid
    774       if bmfid = tmpfid then
    775          leave
    776       endif
    777       -- Don't list bookmarks of an additional view
    778       -- Save list of processed file ids only if multiple views exist
    779       if bmfid.currentview_of_file <> bmfid.nextview_of_file then
    780          if wordpos( bmfid, GetAVar( 'bmfidlist')) then
    781             leave
    782          endif
    783          AddAvar( 'bmfidlist', bmfid)
    784       endif
    785 
    786       -- Find bookmarks
    787       line  = 0
    788       col   = 1
    789       offst = 0
    790       class = BOOKMARK_CLASS
    791       bmidxmax = 0
    792       do forever
    793          -- Find attribute
    794          attribute_action 1, class, offst, col, line, bmfid  -- 1 = FIND NEXT ATTR
    795          if class = 0 then  -- No attribute found
    796             leave
    797          endif
    798 
    799          -- Query attribute for ispush and val
    800          query_attribute class, val, ispush, offst, col, line, bmfid
    801          bmperm = ispush
    802          bmidx  = val
    803 
    804          -- Get bmname from array var
    805          bmname = GetBmName( bmfid, bmidx)
    806 
    807          -- Fill with spaces. Looks good with 9.WarpSans and 8.Helv:
    808          sep = copies( ' ', 2)
    809          alignfid   = AlignPropStr( bmfid, 6)
    810          alignidx   = AlignPropStr( bmidx, 3)
    811          alignline  = AlignPropStr( line, 6)
    812          aligncol   = AlignPropStr( col, 4)
    813          alignoffst = AlignPropStr( offst, 2)  -- unused
    814          if bmperm = 4 then
    815             alignperm  = sep''sep''AlignPropStr( 'perm', 4)
    816          elseif bmperm = 3 then
    817             alignperm  = sep''sep''AlignPropStr( 'temp', 4)
    818          else
    819             alignperm  = sep''sep''AlignPropStr( bmperm, 4)
    820          endif
    821          alignname = sep''sep''bmname
    822 
    823          -- Write listbox line
    824          insertline alignfid''sep''alignline''sep''alignidx''sep''alignperm''sep''alignname, tmpfid.last + 1, tmpfid
    825       enddo
    826    enddo
    827    SetAVar( 'bmfidlist', '')
    828 
    829    activatefile tmpfid
    830 
    831    -- Sort bookmark entries
    832    if .last > 2 then
    833       call Sort( 2, .last, 1, 40, tmpfid, 'I')
    834    endif
    835 
    836    -- Insert filenames
    837    lastfid = ''
    838    l = 1
    839    do forever
    840       -- Don't insert filenames if no bookmarks were found
    841       if .last < 2 then
    842          leave
    843       endif
    844 
    845       l = l + 1
    846       parse value textline( l) with bmfid .
    847       bmfid = strip( bmfid)
    848       -- The rows bmfid and bmidx can't be removed here,
    849       -- because they are used by GoMark and DeleteBm.
    850 
    851       if bmfid <> lastfid then
    852          -- New fid, add filename
    853          lp = lastpos( '\', bmfid.filename)
    854          fname = substr( bmfid.filename, lp + 1)
    855          fdir = ''
    856          if lp > 1 then
    857             fdir = leftstr( bmfid.filename, lp - 1)
    858             -- Handle drives: Re-append backslash
    859             if rightstr( fdir, 1) = ':' then
    860                fdir = fdir'\'
    861             endif
    862             fdir = '  ('fdir')'
    863          endif
    864 
    865          -- Save line nmuber of filename
    866          if bmfid = startfid then
    867             curfidline = l
    868          endif
    869 
    870          -- Insert filename before the current line
    871          insertline fname''fdir, l, tmpfid
    872          l = l + 1
    873 
    874          -- Save current file id as lastfid
    875          lastfid = bmfid
    876       endif
    877 
    878       if l >= .last then
    879          leave
    880       endif
    881    enddo
    882 
    883    if browse_mode then  -- restore browse state
    884       call browse( 1)
    885    endif
    886    display 2
    887    if not .modify then  -- Nothing added?
    888       sayerror NO_BOOKMARKS__MSG
    889       'xcom quit'
    890       return
    891    endif
    892 
    893    if ListBox_Buffer_From_File( startfid, bufhndl, noflines, usedsize) then
    894       return
    895    endif
    896 
    897    Title = LIST_BOOKMARKS__MSG
    898    -- Looks good with 9.WarpSans and 8.Helv:
    899    Text = '       FileId       Line      Idx     Type       Name'
    900    DefaultButton = 1
    901    parse value ListBox( Title,
    902                         \0 || atol( usedsize) || atoi( 32) || atoi( bufhndl),
    903                         '/'GOMARK__MSG'/'DELETEMARK__MSG'/'Cancel__MSG'/'Help__MSG,
    904                         0, 0,  -- 1, 5,
    905                         Min( noflines, 30), 80,  -- lines, cols
    906                         GetHwndC( APP_HANDLE) ||
    907                         atoi( curfidline)     ||  -- selected item
    908                         atoi( DefaultButton)  ||  -- selected button
    909                         atoi( 6030)           ||  -- help id
    910                         Text) with Button 2 selectedbm \0
    911 
    912    call buffer( FREEBUF, bufhndl)
    913 
    914    Button = asc( Button)
    915    if Button = 0 | Button = 3 then
    916       return
    917    endif
    918 
    919    parse value selectedbm with bmfid bmline bmidx bmtype bmname
    920    bmfid  = strip( bmfid)
    921    bmidx  = strip( bmidx)
    922    bmline = strip( bmline)
    923    bmtype = strip( bmtype)
    924    bmname = strip( bmname)
    925 
    926    if not IsNum( bmidx) then
    927       -- Filename selected
    928       parse value selectedbm with fname '('fdir')'
    929       fname = strip( fname)
    930 
    931       if fdir = '' then
    932          SelectedFilename = fname
    933       else
    934          if rightstr( fdir, 1) = '\' then
    935             SelectedFilename = fdir''fname
    936          else
    937             SelectedFilename = fdir'\'fname
    938          endif
    939       endif
    940 
    941       -- Switch to SelectedFilename
    942       getfileid SelectedFid, SelectedFilename
    943       activatefile SelectedFid
    944       return
    945    endif
    946 
    947    if Button = 1 then      -- Go to
    948       'GoMark' bmidx bmfid
    949       return
    950    elseif Button = 2 then  -- Delete
    951       'DeleteBm' bmidx bmfid
    952       'postme ListMark'
    953       return
    954    endif
    955 
    956 ; ---------------------------------------------------------------------------
    957 defproc DelBookmarkAtPos
    958    rcx = 2
    959    old_level = .levelofattributesupport
    960    if old_level & not (old_level bitand 2) then
    961       .levelofattributesupport = .levelofattributesupport + 2
    962    endif
    963    getfileid bmfid
    964 
    965    firstline = arg( 1)
    966    firstcol  = arg( 2)
    967    if firstline =  '' then
    968       firstline = .line
    969    endif
    970    if firstcol = '' then
    971       firstcol = .col
    972    endif
    973 
    974    SavedLine  = firstline
    975    SavedCol   = firstcol
    976    SavedOffst = -300
    977    do forever
    978       class = BOOKMARK_CLASS
    979       line  = SavedLine
    980       col   = SavedCol
    981       offst = SavedOffst
    982       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    983       --dprintf( 'DelBookmarkAtPos: FindNextAttr: class = 'class', offst = 'offst', col = 'col', line = 'line)
    984       if not class then
    985          leave
    986       endif
    987       if line > firstline then
    988          leave
    989       elseif line = firstline & col > firstcol then
    990          leave
    991       endif
    992       SavedLine  = line
    993       SavedCol   = col
    994       SavedOffst = offst
    995 
    996       -- Query attribute to get ispush
    997       query_attribute class, val, ispush, offst, col, line
    998       --dprintf( 'DelBookmarkAtPos: QueryAttr: class = 'class', val = 'val', ispush = 'ispush', offst = 'offst', col = 'col', line = 'line)
    999       bmperm = ispush
    1000 
    1001       -- Delete attribute
    1002       oldmod = .modify
    1003       attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTRIBUTE
    1004       -- attribute_action 16 changes class to 1 on deletion
    1005       if not class then
    1006          iterate
    1007       endif
    1008       if bmperm <> 4 then
    1009          .modify = oldmod
    1010       endif
    1011       if bmperm = 4 then
    1012          bmtype = 'permanent'
    1013       else
    1014          bmtype = 'non-permanent'
    1015       endif
    1016       --dprintf( 'DelBookmarkAtPos: Deleted 'bmtype' bookmark with idx 'val' at line = 'line', col = 'col', offst = 'offst)
    1017 
    1018       rcx = 0
    1019    enddo
    1020 
    1021    .levelofattributesupport = old_level
    1022    rc = rcx
    1023    return
    1024 
    1025 ; ---------------------------------------------------------------------------
    1026 defproc DelBookmarkInRegion
    1027    rcx = 2
    1028    getfileid bmfid
    1029 
    1030    firstline = arg( 1)
    1031    firstcol  = arg( 2)
    1032    lastline  = arg( 3)
    1033    lastcol   = arg( 4)
    1034    if arg( 1) = '' | arg( 2) = '' | arg( 3) = '' | arg( 4) = '' then
    1035       getmark mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid
    1036       mktype = marktype()
    1037       if bmfid <> mkfid then
    1038          return rcx
    1039       endif
    1040 
    1041       if firstline =  '' then
    1042          firstline = mkfirstline
    1043       endif
    1044       if firstcol = '' then
    1045          firstcol = mkfirstcol
    1046       endif
    1047       if lastline =  '' then
    1048          lastline = mklastline
    1049       endif
    1050       if lastcol = '' then
    1051          lastcol = mklastcol
    1052       endif
    1053    else
    1054       if firstcol = 1 & lastcol = MAXCOL then
    1055          mktype = 'LINE'
    1056       else
    1057          -- Block mark can't be distiguished from char mark with the
    1058          -- mark coordinates only
    1059          mktype = 'CHAR'
    1060       endif
    1061    endif
    1062 
    1063    SavedLine  = firstline
    1064    SavedCol   = firstcol
    1065    SavedOffst = -300
    1066    do forever
    1067       class = BOOKMARK_CLASS
    1068       line  = SavedLine
    1069       col   = SavedCol
    1070       offst = SavedOffst
    1071       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    1072       --dprintf( 'DelBookmarkInRegion: FindNextAttr: class = 'class', offst = 'offst', col = 'col', line = 'line)
    1073       if not class then
    1074          leave
    1075       endif
    1076       if line > lastline then
    1077          leave
    1078       elseif line = lastline & col > lastcol then
    1079          leave
    1080       elseif mktype = 'BLOCK' & (col < firstcol | col > lastcol) then
    1081          iterate
    1082       endif
    1083       SavedLine  = line
    1084       SavedCol   = col
    1085       SavedOffst = offst
    1086 
    1087       -- Query attribute to get val and ispush
    1088       query_attribute class, val, ispush, offst, col, line
    1089       --dprintf( 'DelBookmarkInRegion: QueryAttr: class = 'class', val = 'val', ispush = 'ispush', offst = 'offst', col = 'col', line = 'line)
    1090       bmperm = ispush
    1091 
    1092       -- Delete attribute
    1093       oldmod = .modify
    1094       attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTRIBUTE
    1095       -- attribute_action 16 changes class to 1 on deletion
    1096       if not class then
    1097          iterate
    1098       endif
    1099       if bmperm <> 4 then
    1100          .modify = oldmod
    1101       endif
    1102       if bmperm = 4 then
    1103          bmtype = 'permanent'
    1104       else
    1105          bmtype = 'non-permanent'
    1106       endif
    1107       --dprintf( 'DelBookmarkInRegion: Deleted 'bmtype' bookmark with idx 'val' at line = 'line', col = 'col', offst = 'offst)
    1108 
    1109       rcx = 0
    1110    enddo
    1111 
    1112    rc = rcx
    1113    return
    1114 
    1115 ; ---------------------------------------------------------------------------
    1116 defproc ChangeBmAttribInMark( Action, mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid)
    1117 
    1118    getfileid destfid
    1119    -- Get idxmax value for bookmarks in destfile from before copy/move
    1120    destidxmax = GetAVar( 'bmname.'destfid'.0')
    1121    if destidxmax = '' then
    1122       destidxmax = 0
    1123    endif
    1124 
    1125    getmark destfirstline, destlastline, destfirstcol, destlastcol, destfid
    1126    desttype = marktype()
    1127    Action = upcase( Action)
    1128 
    1129    -- Change (append) idx values for copied bookmarks
    1130    -- Change array vars for copied bookmarks
    1131    SavedLine  = destfirstline
    1132    SavedCol   = destfirstcol
    1133    SavedOffst = -300
    1134    do forever
    1135       class = BOOKMARK_CLASS
    1136       line  = SavedLine
    1137       col   = SavedCol
    1138       offst = SavedOffst
    1139       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    1140       if not class then
    1141          leave
    1142       endif
    1143       if line > destlastline then
    1144          leave
    1145       elseif line = destlastline & col > destlastcol then
    1146          leave
    1147       elseif desttype = 'BLOCK' & (col < destfirstcol | col > destlastcol) then
    1148          iterate
    1149       endif
    1150       SavedLine  = line
    1151       SavedCol   = col
    1152       SavedOffst = offst
    1153 
    1154       -- Query attribute to get val and ispush
    1155       query_attribute class, val, ispush, offst, col, line
    1156       bmperm = ispush
    1157 
    1158       -- Get bmname for the previously marked file with the same idx value
    1159       bmidx = val
    1160       bmname = GetAVar( 'bmname.'mkfid'.'bmidx)
    1161       --dprintf( 'Found bookmark  : line = 'line', col = 'col', bmname = 'bmname', bmidx = 'bmidx', offst = 'offst', class = 'class)
    1162 
    1163       -- For copy mark or for move mark to another file
    1164       if (Action = 'COPY' | destfid <> mkfid) then
    1165          -- Delete copied bookmark with old bmidx
    1166          class = BOOKMARK_CLASS
    1167          line  = SavedLine
    1168          col   = SavedCol
    1169          offst = SavedOffst
    1170          attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTRIBUTE
    1171          -- attribute_action 16 sets class = 1 instead of 13 (bookmark).
    1172          --dprintf( 'After delete bm : line = 'line', col = 'col', bmname = 'bmname', bmidx = 'bmidx', offst = 'offst', class = 'class)
    1173 
    1174          -- Recreate copied bookmark with new bmidx
    1175          class = BOOKMARK_CLASS
    1176          line  = SavedLine
    1177          col   = SavedCol
    1178          offst = SavedOffst
    1179          destidx = destidxmax + 1
    1180          val = destidx
    1181          insert_attribute class, val, bmperm, offst, col, line
    1182 
    1183          -- Change/create name array var
    1184          SetAVar( 'bmname.'destfid'.'destidx, bmname)
    1185          SetAVar( 'bmname.'destfid'.0', destidx)
    1186          --dprintf( 'Changed bookmark: line = 'line', col = 'col', bmname = 'bmname', destidx = 'destidx', offst = 'offst', class = 'class)
    1187       endif
    1188 
    1189    enddo
    1190 
    1191 ; ---------------------------------------------------------------------------
    1192 ; Moves all attributes from source position (line, col) to destination
    1193 ; position (line, col). If destination position isn't specified, the
    1194 ; current position is used. Sets file to modified state.
    1195 defproc MoveAttr( SrcLine, SrcCol)
    1196    rcx = 2
    1197    DestLine = arg( 3)
    1198    if DestLine = '' then
    1199       DestLine = .line
    1200    endif
    1201    DestCol = arg( 4)
    1202    if DestCol = '' then
    1203       DestCol = .col
    1204    endif
    1205    if DestLine = SrcLine & DestCol = SrcCol then
    1206       rc = 0
    1207       return
    1208    endif
    1209 
    1210    SavedLine  = SrcLine
    1211    SavedCol   = SrcCol
    1212    SavedOffst = -300
    1213    do forever
    1214       class = 0  -- Find all classes
    1215       line  = SavedLine
    1216       col   = SavedCol
    1217       offst = SavedOffst
    1218       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    1219       --dprintf( 'MoveAttr: FindPrevAttr: class = 'class', offst = 'offst', col = 'col', line = 'line)
    1220       if not class then
    1221          leave
    1222       endif
    1223       if line <> SrcLine then
    1224          leave
    1225       endif
    1226       if col <> SrcCol then
    1227          leave
    1228       endif
    1229       SavedLine  = line
    1230       SavedCol   = col
    1231       SavedOffst = offst
    1232       SavedClass = class
    1233 
    1234       -- Query attribute to get val
    1235       query_attribute class, val, ispush, offst, col, line
    1236       --dprintf( 'MoveAttr: QueryAttr: class = 'class', val = 'val', ispush = 'ispush', offst = 'offst', col = 'col', line = 'line)
    1237 
    1238       -- Delete attribute
    1239       attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTRIBUTE
    1240       -- attribute_action 16 changes class to 1 on deletion
    1241       --dprintf( 'MoveAttr: After attribute_action 16, 'class', 'offst', 'col', 'line)
    1242       if not class then
    1243          iterate
    1244       endif
    1245 
    1246       -- Insert attribute at destination position
    1247       class = SavedClass
    1248       line  = DestLine
    1249       col   = DestCol
    1250       offst = 0
    1251       insert_attribute class, val, ispush, offst, col, line
    1252       --dprintf( 'MoveAttr: After insert_attribute 'class', 'val', 'ispush', 'offst', 'col', 'line)
    1253 
    1254       rcx = 0
    1255    enddo
    1256 
    1257    rc = rcx
    1258    return
    1259 
    1260 ; ---------------------------------------------------------------------------
    1261 ; Syntax: DeleteBmClass bmtype
    1262 ; Deletes all bookmarks of type 3 (non-permanent) or 4 (permanent).
    1263 ; When bmtype = 4 is specified, a MsgBox pops up to confirm the deletion.
    1264 defc DeleteBmClass
    1265    parse arg Bmtype .
    1266    if Bmtype = '' then
    1267       sayerror NEED_BM_CLASS__MSG
    1268       return
    1269    endif
    1270    if Bmtype = 4 then
    1271       if AskYesNo( DELETE_PERM_BM__MSG) <> YES_CHAR then
    1272          return
    1273       endif
    1274    endif
    1275    getfileid bmfid
    1276 
    1277    line  = 0
    1278    col   = 1
    1279    offst = 0
    1280    oldmod = .modify
    1281    do forever
    1282       class = BOOKMARK_CLASS
    1283       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
    1284       if class = 0 then  -- No more of that class
    1285          leave
    1286       endif
    1287 
    1288       query_attribute class, val, ispush, offst, col, line
    1289 
    1290       if ispush = Bmtype then
    1291          -- Delete attribute
    1292          attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTRIBUTE
    1293          -- attribute_action 16 changes class to 1 on deletion
    1294       endif
    1295    enddo
    1296 
    1297    if BMtype <> 4 then
    1298       .modify = oldmod
    1299    endif
    1300 
    1301 ; ---------------------------------------------------------------------------
    1302 defc NextBookmark
    1303    parse arg next bmclass .
    1304 
    1305    class = BOOKMARK_CLASS
    1306    col   = .col
    1307    line  = .line
    1308    offst = 0
    1309    if next = 'P' then
    1310       col = col - 1
    1311    endif
    1312    do forever
    1313       attribute_action 1 + (next = 'P'), class, offst, col, line  -- 1 = FIND NEXT ATTR; 2 = FIND PREV ATTR
    1314       if class = 0 then
    1315          sayerror BM_NOT_FOUND__MSG
    1316          return
    1317       endif
    1318       query_attribute class, val, ispush, offst, col, line
    1319       if ispush = bmclass | bmclass = '' then
    1320          .cursory = .windowheight % 2
    1321          line
    1322          .col = col
    1323          'HighlightCursor'
    1324          return
    1325       endif
    1326    enddo
    1327 
    1328 ; ===========================================================================
    1329 ; Part 3: Font and color attributes and styles
    1330 ; ===========================================================================
    1331 
    1332 ; ---------------------------------------------------------------------------
    1333 ; Array var names were exchanged compared to the original:
    1334 ;    'stylename.0'           max. styleidx  (was 'si.0')
    1335 ;    'stylename.'styleidx    stylename      (was 'si.'styledx)
    1336 ;    'styleindex.'stylename  styleidx       (was 'sn.'stylename)
    1337 ; These array vars are valid for an EPM window. Styles are saved in NEPMD.INI
    1338 ; and style array vars were set only when styles are used in a file.
    1339 defc ShowStyleAVars
    1340    styleidxmax = GetAVar( 'stylename.0')
    1341    dprintf( "GetAVar( 'stylename.0') = "styleidxmax)
    1342    do i = 1 to styleidxmax
    1343       sname = GetAVar( 'stylename.'i)
    1344       dprintf( "GetAVar( 'stylename."i"') = "sname)
    1345       styleidx = GetAVar( 'styleindex.'sname)
    1346       dprintf( "GetAVar( 'styleindex."sname"') = "styleidx)
    1347    enddo
     483; Turns on the specified bit (1, 2, 4, etc.) and returns 0 or 1 depending
     484; on whether it was originally off or on.
     485; .levelofattributesupport is a bit field indicating the level of attribute
     486; support desired. The bits are:
     487;    1  Display color attributes.
     488;    2  Don't skip over attributes when moving the cursor.
     489;    4  Display font attributes.
     490;    8  Save attributes in an Extended Attribute when saving the file.
     491;   16  Used by the macros to indicate that the Compiler menu was added
     492;       (part of the Workframe support).
     493defproc Attribute_On( bit)
     494   flag = (.levelofattributesupport bitand bit) <> 0
     495   if not flag then  -- Is that bit off?
     496      .levelofattributesupport = .levelofattributesupport + bit  -- Turn it on!
     497   endif
     498   return flag
    1348499
    1349500; ---------------------------------------------------------------------------
     
    1354505   line = fstline
    1355506   pairoffst = -255
    1356    attribute_action 1, class, offst1, col, line, fileid  -- 1 = FIND NEXT ATTR
     507   attribute_action FIND_NEXT_ATTR_SUBOP, class, offst1, col, line, fileid
    1357508   if class & col = fstcol & line = fstline then  -- Found one!
    1358509
    1359510      offst2 = offst1
    1360       attribute_action 3, class, offst2, col, line, fileid  -- 3 = FIND MATCH ATTR
     511      attribute_action FIND_MATCH_ATTR_SUBOP, class, offst2, col, line, fileid
    1361512      if class then
    1362513
     
    1380531compile endif
    1381532            if freplaceit then
    1382                attribute_action 16, class, offst1, fstcol, fstline, fileid  -- 16 = DELETE ATTR
    1383                attribute_action 16, class, offst2, lc1, lstline, fileid  -- 16 = DELETE ATTR
    1384                -- attribute_action 16 changes class to 1 on deletion
     533               attribute_action DELETE_ATTR_SUBOP, class, offst1, fstcol, fstline, fileid
     534               attribute_action DELETE_ATTR_SUBOP, class, offst2, lc1, lstline, fileid
     535               -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    1385536
    1386537               pairoffst = offst1 + 1
     
    1410561         col2 = col
    1411562         line2 = line
    1412          attribute_action 3, class, offst2, col2, line2, fileid  -- 3 = FIND MATCH ATTR
     563         attribute_action FIND_MATCH_ATTR_SUBOP, class, offst2, col2, line2, fileid
    1413564         if not class then  -- No match?  Most curious...
    1414565            leave
     
    1422573         col = col2
    1423574         line = line2
    1424          attribute_action 1, class, offst1, col, line, fileid  -- 1 = FIND NEXT ATTR
     575         attribute_action FIND_NEXT_ATTR_SUBOP, class, offst1, col, line, fileid
    1425576      enddo
    1426577compile endif
     
    1432583
    1433584; ---------------------------------------------------------------------------
    1434 ; Turns on the specified bit (1, 2, 4, etc.) and returns 0 or 1 depending
    1435 ; on whether it was originally off or on.
    1436 ; .levelofattributesupport is a bit field indicating the level of attribute
    1437 ; support desired. The bits are:
    1438 ;    1  Display color attributes.
    1439 ;    2  Don't skip over attributes when moving the cursor.
    1440 ;    4  Display font attributes.
    1441 ;    8  Save attributes in an Extended Attribute when saving the file.
    1442 ;   16  Used by the macros to indicate that the Compiler menu was added
    1443 ;       (part of the Workframe support).
    1444 defproc Attribute_On( bit)
    1445    flag = (.levelofattributesupport bitand bit) <> 0
    1446    if not flag then  -- Is that bit off?
    1447       .levelofattributesupport = .levelofattributesupport + bit  -- Turn it on!
    1448    endif
    1449    return flag
     585; Moves all attributes from source position (line, col) to destination
     586; position (line, col). If destination position isn't specified, the
     587; current position is used. Sets file to modified state.
     588defproc MoveAttr( SrcLine, SrcCol)
     589   rcx = 2
     590   DestLine = arg( 3)
     591   if DestLine = '' then
     592      DestLine = .line
     593   endif
     594   DestCol = arg( 4)
     595   if DestCol = '' then
     596      DestCol = .col
     597   endif
     598   if DestLine = SrcLine & DestCol = SrcCol then
     599      rc = 0
     600      return
     601   endif
     602
     603   SavedLine  = SrcLine
     604   SavedCol   = SrcCol
     605   SavedOffst = -300
     606   do forever
     607      class = 0  -- Find all classes
     608      line  = SavedLine
     609      col   = SavedCol
     610      offst = SavedOffst
     611      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     612      --dprintf( 'MoveAttr: FindPrevAttr: class = 'class', offst = 'offst', col = 'col', line = 'line)
     613      if not class then
     614         leave
     615      endif
     616      if line <> SrcLine then
     617         leave
     618      endif
     619      if col <> SrcCol then
     620         leave
     621      endif
     622      SavedLine  = line
     623      SavedCol   = col
     624      SavedOffst = offst
     625      SavedClass = class
     626
     627      -- Query attribute to get val
     628      query_attribute class, val, ispush, offst, col, line
     629      --dprintf( 'MoveAttr: QueryAttr: class = 'class', val = 'val', ispush = 'ispush', offst = 'offst', col = 'col', line = 'line)
     630
     631      -- Delete attribute
     632      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     633      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
     634      --dprintf( 'MoveAttr: After attribute_action DELETE_ATTR_SUBOP, 'class', 'offst', 'col', 'line)
     635      if not class then
     636         iterate
     637      endif
     638
     639      -- Insert attribute at destination position
     640      class = SavedClass
     641      line  = DestLine
     642      col   = DestCol
     643      offst = 0
     644      insert_attribute class, val, ispush, offst, col, line
     645      --dprintf( 'MoveAttr: After insert_attribute 'class', 'val', 'ispush', 'offst', 'col', 'line)
     646
     647      rcx = 0
     648   enddo
     649
     650   rc = rcx
     651   return
     652
     653; ---------------------------------------------------------------------------
     654; Deletes all attributes of current file.
     655defc DeleteAllAttributes, DelAllAttr
     656   line  = 0
     657   col   = 0
     658   offst = -300
     659   do forever
     660      class = ANY_CLASS
     661      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     662      if class = 0 then
     663         leave
     664      endif
     665      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     666      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
     667   enddo
     668
     669; ---------------------------------------------------------------------------
     670; Called by DeleteLine. Deletes all attributes in current line. Push/pop
     671; attribute pairs which don't start and end on the current line are preserved
     672; by moving the matching attribute either to the begin of the next line or
     673; after the end of the previous line.
     674defproc DelAttrInLine
     675
     676   do once = 1 to 1
     677
     678      if not .levelofattributesupport then
     679         leave
     680      endif
     681
     682      -- If this is not the last line
     683      if .line < .last then
     684
     685         -- Put the attributes after the line since there may not
     686         -- be a line before this line (as when .line == 1)
     687         destcol  = 1
     688         destline = .line + 1
     689
     690         -- Search backwards, therefore start at the end of current line
     691         findoffst = 0  -- above the max. offset = -1, search is exclusive
     692         findline  = .line
     693         findcol   = MAXCOL
     694         do forever
     695            findclass = ANY_CLASS
     696            attribute_action FIND_PREV_ATTR_SUBOP, findclass, findoffst, findcol, findline
     697            if not findclass | (findline <> .line) then  -- No attribute, or not on this line
     698               leave
     699            endif
     700
     701            -- Query more parameters
     702            query_attribute class, val, ispush, findoffst, findcol, findline
     703            -- Only move push/pop model attributes (tags and bookmarks are just deleted)
     704            if ispush > 1 then
     705               iterate
     706            endif
     707
     708            -- Move found attribute to destination.
     709            -- If cancellation, delete both attributes.
     710            srccol   = findcol
     711            srcline  = findline
     712            srcoffst = findoffst
     713
     714            if ispush <> 1 then
     715               -- An end attribute cannot cancel any attribute when placed at the
     716               -- beginning (most negative), so it must be inserted.
     717
     718               insert_attribute class, val, ispush, -300, destcol, destline
     719               -- Delete the old attribute
     720               attribute_action DELETE_ATTR_SUBOP, class, srcoffst, srccol, srcline
     721
     722            else
     723               -- If the matching end attr is on the destination (next line,
     724               -- col = 1), then both attrs can be deleted.
     725
     726               matchclass = class
     727               matchoffst = srcoffst
     728               matchcol   = srccol
     729               matchline  = srcline
     730               attribute_action FIND_MATCH_ATTR_SUBOP, matchclass, matchoffst, matchcol, matchline
     731
     732               if ((matchcol == destcol) and (matchline == destline)) then
     733                  -- Matching end attr is on the destination
     734
     735                  -- Delete the matching attribute
     736                  attribute_action DELETE_ATTR_SUBOP, class, matchoffst, matchcol, matchline
     737                  -- Delete the old attribute
     738                  attribute_action DELETE_ATTR_SUBOP, class, srcoffst, srccol, srcline
     739
     740               else
     741                  -- Matching end attr is not on the destination
     742
     743                  insert_attribute class, val, ispush, -300, destcol, destline
     744                  -- Delete the old attribute
     745                  attribute_action DELETE_ATTR_SUBOP, class, srcoffst, srccol, srcline
     746
     747               endif
     748            endif
     749
     750            -- Advance offset for next search. The found attr rec was deleted
     751            -- and all attr rec's were shifted to fill the vacancy.
     752            findoffst = findoffst + 1
     753         enddo
     754
     755      -- If this is the last line and there is a previous line to store attributes on
     756      elseif (.line == .last & .line <> 1) then
     757
     758         destline = .line - 1
     759         getline PrevLineStr, destline
     760         destcol = length( PrevLineStr) + 1
     761
     762         -- Search forewards, therefore start at the begin of current line
     763         findoffst = -300  -- below the min. offset = -255, search is exclusive
     764         findline  = .line
     765         findcol   = 1
     766         do forever        -- search until no more attr's (since this is last line)
     767            findclass = ANY_CLASS
     768            attribute_action FIND_NEXT_ATTR_SUBOP, findclass, findoffst, findcol, findline
     769            if not findclass | (findline <> .line) then  -- No attribute, or not on this line
     770               leave
     771            endif
     772
     773            query_attribute class, val, ispush, findoffst, findcol, findline   -- push or pop?
     774            -- If it's a pop attr and ...
     775            if ispush then
     776               iterate
     777            endif
     778
     779            matchclass = class
     780            matchoffst = findoffst
     781            matchline  = findline
     782            matchcol   = findcol
     783            attribute_action FIND_MATCH_ATTR_SUBOP, matchclass, matchoffst, matchcol, matchline
     784
     785            -- ... and if its match is just after the end of previous line
     786            if ((matchline == destline) & (matchcol == destcol)) then
     787               -- then there is a cancellation of attributes
     788
     789               -- Delete the matching attribute
     790               attribute_action DELETE_ATTR_SUBOP, class, matchoffst, matchcol, matchline
     791               -- Delete the old attribute
     792               attribute_action DELETE_ATTR_SUBOP, class, findoffst, findcol, findline
     793
     794            -- ... and if its match is not on this line
     795            elseif (matchline <> .line) then
     796               -- ... then move attribute after the end of previous line
     797
     798               -- Insert attr at the end of the attr list (offset = 0)
     799               insert_attribute class, val, 0, 0, destcol, destline
     800               -- Delete the old attribute
     801               attribute_action DELETE_ATTR_SUBOP, class, findoffst, findcol, findline
     802            endif
     803         enddo
     804
     805      endif  -- if .line ...
     806
     807   enddo  -- once
     808
     809; ===========================================================================
     810; Part 3: Bookmarks
     811; ===========================================================================
     812
     813; ---------------------------------------------------------------------------
     814defproc InitBookmarks( bmfid)
     815   SetAvar( 'bmname.'bmfid'.0', '')
     816
     817; ---------------------------------------------------------------------------
     818defc SetBookmark
     819   bmname = arg( 1)
     820   bmperm = 3  -- 3 = non-permanent
     821   line = .line
     822   col  = .col
     823   call SetBookmark( bmperm, line, col, bmname)
     824
     825; ---------------------------------------------------------------------------
     826defc SetBookmarkP
     827   bmname = arg( 1)
     828   bmperm = 4  -- 4 = permanent
     829   line = .line
     830   col  = .col
     831   call SetBookmark( bmperm, line, col, bmname)
     832
     833; ---------------------------------------------------------------------------
     834defc Bm, SetMark
     835   parse arg bmperm line col bmname
     836   bmname = strip( bmname)
     837   call SetBookmark( bmperm, line, col, bmname)
     838
     839; ---------------------------------------------------------------------------
     840defproc SetBookmark( bmperm, line, col, bmname)
     841   if .readonly then
     842      sayerror READ_ONLY__MSG
     843      return
     844   endif
     845   if browse() then
     846      sayerror BROWSE_IS__MSG ON__MSG
     847      return
     848   endif
     849
     850   if line = '' then
     851      line = .line
     852   endif
     853   if col = '' then
     854      col = .col
     855   endif
     856   if bmname = '' then
     857      Title = SETMARK__MSG
     858      Text  = SETMARK_PROMPT__MSG
     859      DefaultEntry = subword( textline( .line), 1, 7)
     860      KeyPath = '\NEPMD\Var\Bookmarks\LastSetMarkButton'
     861      DefaultButton = QueryConfigKey( KeyPath)
     862      if DefaultButton = 2 then  -- permanent
     863         -- nop
     864      else
     865         DefaultButton = 1
     866      endif
     867
     868      parse value EntryBox( Title,
     869                            '/'Set__MSG'/'Setp__MSG'/'Cancel__MSG'/'Help__MSG'/',
     870                            DefaultEntry,
     871                            '',
     872                            200,
     873                            atoi( DefaultButton)  ||
     874                            atoi( 6020)           ||
     875                            GetHwndC( APP_HANDLE) ||
     876                            Text) with Button 2 bmname \0
     877
     878      Button = asc( Button)
     879      if Button = 0 | Button = 3 then  -- Esc or Cancel
     880         return
     881      elseif Button = 2 then
     882         bmperm = 4  -- permanent
     883      else
     884         bmperm = 3  -- non-permanent
     885      endif
     886
     887      -- Save selected button for next call
     888      WriteConfigKey( KeyPath, Button)
     889
     890      if not bmname then
     891         --sayerror NOTHING_ENTERED__MSG
     892         'postme SetMark' bmperm line col bmname
     893         return
     894      endif
     895   endif
     896
     897   oldmod = .modify
     898   -- Get bmfid
     899   getfileid bmfid
     900   -- Get bmidx
     901   bmidxmax = GetAVar( 'bmname.'bmfid'.0')  -- bmidxmax says how many bookmarks there are
     902   if bmidxmax = '' then
     903      bmidxmax = 0
     904   endif
     905   bmidx = bmidxmax + 1
     906
     907   -- Insert attribute
     908   class = BOOKMARK_CLASS
     909   val   = bmidx  -- can't be used for bmname - only for numbers
     910   offst = 0
     911   insert_attribute class, val, bmperm, offst, col, line
     912   --dprintf( 'SetBookmark: After insert_attribute 'class', 'val', 'bmperm', 'offst', 'col', 'line)
     913   if bmperm = 4 then
     914      call Attribute_On( 8)  -- "Save attributes" flag
     915   else
     916      .modify = oldmod
     917   endif
     918
     919   -- Write array var to save bookmark name
     920   --dprintf( 'SetBookmark: bmname = 'bmname)
     921   SetAVar( 'bmname.'bmfid'.'bmidx, bmname)  -- Store the bmname
     922   SetAVar( 'bmname.'bmfid'.0', bmidx)       -- Store back the new number
     923
     924   return
     925
     926; ---------------------------------------------------------------------------
     927defproc GetBmName( bmfid, bmidx)
     928   -- Get bmname from array var
     929   bmname = GetAVar( 'bmname.'bmfid'.'bmidx)  -- Query bmname
     930   return bmname
     931
     932; ---------------------------------------------------------------------------
     933defc Go, GoMark
     934   parse arg bmidx bmfid .
     935   fIndexFound = 0
     936   do once = 1 to 1
     937      if bmidx = '' then
     938         leave
     939      elseif not IsNum( bmidx) then
     940         leave
     941      elseif bmfid = '' then
     942         getfileid bmfid
     943      elseif not IsNum( bmfid) then
     944         leave
     945      endif
     946      fIndexFound = 1
     947   enddo
     948   if not fIndexFound then
     949      sayerror UNKNOWN_BOOKMARK__MSG
     950      return
     951   endif
     952
     953   -- Switch to bmfid
     954   display -2
     955   activatefile bmfid
     956   display 2
     957   if rc then
     958      sayerror FILE_GONE__MSG BM_DELETED__MSG
     959      return
     960   endif
     961
     962   -- Find attribute
     963   line  = 0
     964   col   = 1
     965   offst = 0
     966   fAttrFound = 0
     967   val = ''
     968   do forever
     969      class = BOOKMARK_CLASS
     970      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     971      if class = 0 then
     972         leave
     973      endif
     974      -- Query attribute to get val
     975      query_attribute class, val, ispush, offst, col, line
     976      if val <> bmidx then
     977         iterate
     978      endif
     979
     980      fAttrFound = 1
     981      leave
     982   enddo
     983
     984   if fAttrFound then
     985      -- Go to position
     986      .cursory = .windowheight % 2
     987      line
     988      .col = col
     989      'HighlightCursor'
     990   else
     991      sayerror BM_NOT_FOUND__MSG ITS_DELETED__MSG
     992   endif
     993
     994; ---------------------------------------------------------------------------
     995defc DeleteBm
     996   parse arg bmidx bmfid .
     997   fIndexFound = 0
     998   do once = 1 to 1
     999      if bmidx = '' then
     1000         leave
     1001      elseif not IsNum( bmidx) then
     1002         leave
     1003      elseif bmfid = '' then
     1004         getfileid bmfid
     1005      elseif not IsNum( bmfid) then
     1006         leave
     1007      endif
     1008      fIndexFound = 1
     1009   enddo
     1010   if not fIndexFound then
     1011      sayerror UNKNOWN_BOOKMARK__MSG
     1012      return
     1013   endif
     1014
     1015   getfileid startfid
     1016   -- Switch to bmfid
     1017   display -2
     1018   activatefile bmfid
     1019   display 2
     1020   if rc then  -- File no longer in ring - all done.
     1021      return
     1022   endif
     1023
     1024   -- Find attribute
     1025   line  = 0
     1026   col   = 1
     1027   offst = 0
     1028   fAttrFound = 0
     1029   val = ''
     1030   do forever
     1031      class = BOOKMARK_CLASS
     1032      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     1033      if class = 0 then
     1034         leave
     1035      endif
     1036      -- Query attribute to get ispush and val
     1037      query_attribute class, val, ispush, offst, col, line
     1038      if val <> bmidx then
     1039         iterate
     1040      endif
     1041
     1042      fAttrFound = 1
     1043      leave
     1044   enddo
     1045
     1046   if fAttrFound then
     1047      -- Delete attribute
     1048      bmperm = ispush
     1049      oldmod = .modify
     1050      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1051      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
     1052      if bmperm <> 4 then
     1053         .modify = oldmod
     1054      endif
     1055
     1056      sayerror BM_DELETED__MSG
     1057   endif
     1058
     1059   activatefile startfid
     1060
     1061; ---------------------------------------------------------------------------
     1062; Fill a string in a proportional font with spaces to line up with other
     1063; strings of variable width. A number is right-aligned, other strings are
     1064; left-aligned.
     1065defproc AlignPropStr( Str, MaxStrLen)
     1066   Factor = arg( 3)
     1067   if Factor = '' then
     1068      Factor = 2.5
     1069   endif
     1070   NumSpc = Factor * (MaxStrLen - length( Str))
     1071   -- Convert NumSpc to an integer
     1072   parse value NumSpc with iNumSpc'.'rest
     1073   -- Round iNumSpc
     1074   if leftstr( rest, 1) >= 5 then
     1075      iNumSpc = iNumSpc + 1
     1076   endif
     1077   Spc = copies( ' ', iNumSpc)
     1078   if IsNum( Str) then
     1079      return Spc''Str
     1080   else
     1081      return Str''Spc
     1082   endif
     1083
     1084; ---------------------------------------------------------------------------
     1085defc ListMark
     1086
     1087   getfileid startfid
     1088   -- Workaround: This avoids unwanted window scrolling of the previous file.
     1089   'VSyncCursor'
     1090
     1091   'xcom e /c .listbookmarks'
     1092   if rc <> -282 then  -- -282 = sayerror( "New file")
     1093      sayerror ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext( rc)
     1094      return
     1095   endif
     1096   browse_mode = browse()     -- query current state
     1097   if browse_mode then
     1098      call browse( 0)
     1099   endif
     1100   .autosave = 0
     1101   getfileid tmpfid
     1102
     1103   display -2
     1104   -- Query bookmarks
     1105   curfidline = 1  -- default value for the listbox
     1106   SetAVar( 'bmfidlist', '')
     1107   do f = 1 to filesinring( 1)
     1108      nextfile
     1109      getfileid bmfid
     1110      if bmfid = tmpfid then
     1111         leave
     1112      endif
     1113      -- Don't list bookmarks of an additional view
     1114      -- Save list of processed file ids only if multiple views exist
     1115      if bmfid.currentview_of_file <> bmfid.nextview_of_file then
     1116         if wordpos( bmfid, GetAVar( 'bmfidlist')) then
     1117            leave
     1118         endif
     1119         AddAvar( 'bmfidlist', bmfid)
     1120      endif
     1121
     1122      -- Find bookmarks
     1123      line  = 0
     1124      col   = 1
     1125      offst = 0
     1126      class = BOOKMARK_CLASS
     1127      bmidxmax = 0
     1128      do forever
     1129         -- Find attribute
     1130         attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line, bmfid
     1131         if class = 0 then  -- No attribute found
     1132            leave
     1133         endif
     1134
     1135         -- Query attribute for ispush and val
     1136         query_attribute class, val, ispush, offst, col, line, bmfid
     1137         bmperm = ispush
     1138         bmidx  = val
     1139
     1140         -- Get bmname from array var
     1141         bmname = GetBmName( bmfid, bmidx)
     1142
     1143         -- Fill with spaces. Looks good with 9.WarpSans and 8.Helv:
     1144         sep = copies( ' ', 2)
     1145         alignfid   = AlignPropStr( bmfid, 6)
     1146         alignidx   = AlignPropStr( bmidx, 3)
     1147         alignline  = AlignPropStr( line, 6)
     1148         aligncol   = AlignPropStr( col, 4)
     1149         alignoffst = AlignPropStr( offst, 2)  -- unused
     1150         if bmperm = 4 then
     1151            alignperm  = sep''sep''AlignPropStr( 'perm', 4)
     1152         elseif bmperm = 3 then
     1153            alignperm  = sep''sep''AlignPropStr( 'temp', 4)
     1154         else
     1155            alignperm  = sep''sep''AlignPropStr( bmperm, 4)
     1156         endif
     1157         alignname = sep''sep''bmname
     1158
     1159         -- Write listbox line
     1160         insertline alignfid''sep''alignline''sep''alignidx''sep''alignperm''sep''alignname, tmpfid.last + 1, tmpfid
     1161      enddo
     1162   enddo
     1163   SetAVar( 'bmfidlist', '')
     1164
     1165   activatefile tmpfid
     1166
     1167   -- Sort bookmark entries
     1168   if .last > 2 then
     1169      call Sort( 2, .last, 1, 40, tmpfid, 'I')
     1170   endif
     1171
     1172   -- Insert filenames
     1173   lastfid = ''
     1174   l = 1
     1175   do forever
     1176      -- Don't insert filenames if no bookmarks were found
     1177      if .last < 2 then
     1178         leave
     1179      endif
     1180
     1181      l = l + 1
     1182      parse value textline( l) with bmfid .
     1183      bmfid = strip( bmfid)
     1184      -- The rows bmfid and bmidx can't be removed here,
     1185      -- because they are used by GoMark and DeleteBm.
     1186
     1187      if bmfid <> lastfid then
     1188         -- New fid, add filename
     1189         lp = lastpos( '\', bmfid.filename)
     1190         fname = substr( bmfid.filename, lp + 1)
     1191         fdir = ''
     1192         if lp > 1 then
     1193            fdir = leftstr( bmfid.filename, lp - 1)
     1194            -- Handle drives: Re-append backslash
     1195            if rightstr( fdir, 1) = ':' then
     1196               fdir = fdir'\'
     1197            endif
     1198            fdir = '  ('fdir')'
     1199         endif
     1200
     1201         -- Save line nmuber of filename
     1202         if bmfid = startfid then
     1203            curfidline = l
     1204         endif
     1205
     1206         -- Insert filename before the current line
     1207         insertline fname''fdir, l, tmpfid
     1208         l = l + 1
     1209
     1210         -- Save current file id as lastfid
     1211         lastfid = bmfid
     1212      endif
     1213
     1214      if l >= .last then
     1215         leave
     1216      endif
     1217   enddo
     1218
     1219   if browse_mode then  -- restore browse state
     1220      call browse( 1)
     1221   endif
     1222   display 2
     1223   if not .modify then  -- Nothing added?
     1224      sayerror NO_BOOKMARKS__MSG
     1225      'xcom quit'
     1226      return
     1227   endif
     1228
     1229   if ListBox_Buffer_From_File( startfid, bufhndl, noflines, usedsize) then
     1230      return
     1231   endif
     1232
     1233   Title = LIST_BOOKMARKS__MSG
     1234   -- Looks good with 9.WarpSans and 8.Helv:
     1235   Text = '       FileId       Line      Idx     Type       Name'
     1236   DefaultButton = 1
     1237   parse value ListBox( Title,
     1238                        \0 || atol( usedsize) || atoi( 32) || atoi( bufhndl),
     1239                        '/'GOMARK__MSG'/'DELETEMARK__MSG'/'Cancel__MSG'/'Help__MSG,
     1240                        0, 0,  -- 1, 5,
     1241                        Min( noflines, 30), 80,  -- lines, cols
     1242                        GetHwndC( APP_HANDLE) ||
     1243                        atoi( curfidline)     ||  -- selected item
     1244                        atoi( DefaultButton)  ||  -- selected button
     1245                        atoi( 6030)           ||  -- help id
     1246                        Text) with Button 2 selectedbm \0
     1247
     1248   call buffer( FREEBUF, bufhndl)
     1249
     1250   Button = asc( Button)
     1251   if Button = 0 | Button = 3 then
     1252      return
     1253   endif
     1254
     1255   parse value selectedbm with bmfid bmline bmidx bmtype bmname
     1256   bmfid  = strip( bmfid)
     1257   bmidx  = strip( bmidx)
     1258   bmline = strip( bmline)
     1259   bmtype = strip( bmtype)
     1260   bmname = strip( bmname)
     1261
     1262   if not IsNum( bmidx) then
     1263      -- Filename selected
     1264      parse value selectedbm with fname '('fdir')'
     1265      fname = strip( fname)
     1266
     1267      if fdir = '' then
     1268         SelectedFilename = fname
     1269      else
     1270         if rightstr( fdir, 1) = '\' then
     1271            SelectedFilename = fdir''fname
     1272         else
     1273            SelectedFilename = fdir'\'fname
     1274         endif
     1275      endif
     1276
     1277      -- Switch to SelectedFilename
     1278      getfileid SelectedFid, SelectedFilename
     1279      activatefile SelectedFid
     1280      return
     1281   endif
     1282
     1283   if Button = 1 then      -- Go to
     1284      'GoMark' bmidx bmfid
     1285      return
     1286   elseif Button = 2 then  -- Delete
     1287      'DeleteBm' bmidx bmfid
     1288      'postme ListMark'
     1289      return
     1290   endif
     1291
     1292; ---------------------------------------------------------------------------
     1293defproc DelBookmarkAtPos
     1294   rcx = 2
     1295   old_level = .levelofattributesupport
     1296   if old_level & not (old_level bitand 2) then
     1297      .levelofattributesupport = .levelofattributesupport + 2
     1298   endif
     1299   getfileid bmfid
     1300
     1301   firstline = arg( 1)
     1302   firstcol  = arg( 2)
     1303   if firstline =  '' then
     1304      firstline = .line
     1305   endif
     1306   if firstcol = '' then
     1307      firstcol = .col
     1308   endif
     1309
     1310   SavedLine  = firstline
     1311   SavedCol   = firstcol
     1312   SavedOffst = -300
     1313   do forever
     1314      class = BOOKMARK_CLASS
     1315      line  = SavedLine
     1316      col   = SavedCol
     1317      offst = SavedOffst
     1318      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     1319      --dprintf( 'DelBookmarkAtPos: FindNextAttr: class = 'class', offst = 'offst', col = 'col', line = 'line)
     1320      if not class then
     1321         leave
     1322      endif
     1323      if line > firstline then
     1324         leave
     1325      elseif line = firstline & col > firstcol then
     1326         leave
     1327      endif
     1328      SavedLine  = line
     1329      SavedCol   = col
     1330      SavedOffst = offst
     1331
     1332      -- Query attribute to get ispush
     1333      query_attribute class, val, ispush, offst, col, line
     1334      --dprintf( 'DelBookmarkAtPos: QueryAttr: class = 'class', val = 'val', ispush = 'ispush', offst = 'offst', col = 'col', line = 'line)
     1335      bmperm = ispush
     1336
     1337      -- Delete attribute
     1338      oldmod = .modify
     1339      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1340      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
     1341      if not class then
     1342         iterate
     1343      endif
     1344      if bmperm <> 4 then
     1345         .modify = oldmod
     1346      endif
     1347      if bmperm = 4 then
     1348         bmtype = 'permanent'
     1349      else
     1350         bmtype = 'non-permanent'
     1351      endif
     1352      --dprintf( 'DelBookmarkAtPos: Deleted 'bmtype' bookmark with idx 'val' at line = 'line', col = 'col', offst = 'offst)
     1353
     1354      rcx = 0
     1355   enddo
     1356
     1357   .levelofattributesupport = old_level
     1358   rc = rcx
     1359   return
     1360
     1361; ---------------------------------------------------------------------------
     1362defproc DelBookmarkInRegion
     1363   rcx = 2
     1364   getfileid bmfid
     1365
     1366   firstline = arg( 1)
     1367   firstcol  = arg( 2)
     1368   lastline  = arg( 3)
     1369   lastcol   = arg( 4)
     1370   if arg( 1) = '' | arg( 2) = '' | arg( 3) = '' | arg( 4) = '' then
     1371      getmark mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid
     1372      mktype = marktype()
     1373      if bmfid <> mkfid then
     1374         return rcx
     1375      endif
     1376
     1377      if firstline =  '' then
     1378         firstline = mkfirstline
     1379      endif
     1380      if firstcol = '' then
     1381         firstcol = mkfirstcol
     1382      endif
     1383      if lastline =  '' then
     1384         lastline = mklastline
     1385      endif
     1386      if lastcol = '' then
     1387         lastcol = mklastcol
     1388      endif
     1389   else
     1390      if firstcol = 1 & lastcol = MAXCOL then
     1391         mktype = 'LINE'
     1392      else
     1393         -- Block mark can't be distiguished from char mark with the
     1394         -- mark coordinates only
     1395         mktype = 'CHAR'
     1396      endif
     1397   endif
     1398
     1399   SavedLine  = firstline
     1400   SavedCol   = firstcol
     1401   SavedOffst = -300
     1402   do forever
     1403      class = BOOKMARK_CLASS
     1404      line  = SavedLine
     1405      col   = SavedCol
     1406      offst = SavedOffst
     1407      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     1408      --dprintf( 'DelBookmarkInRegion: FindNextAttr: class = 'class', offst = 'offst', col = 'col', line = 'line)
     1409      if not class then
     1410         leave
     1411      endif
     1412      if line > lastline then
     1413         leave
     1414      elseif line = lastline & col > lastcol then
     1415         leave
     1416      elseif mktype = 'BLOCK' & (col < firstcol | col > lastcol) then
     1417         iterate
     1418      endif
     1419      SavedLine  = line
     1420      SavedCol   = col
     1421      SavedOffst = offst
     1422
     1423      -- Query attribute to get val and ispush
     1424      query_attribute class, val, ispush, offst, col, line
     1425      --dprintf( 'DelBookmarkInRegion: QueryAttr: class = 'class', val = 'val', ispush = 'ispush', offst = 'offst', col = 'col', line = 'line)
     1426      bmperm = ispush
     1427
     1428      -- Delete attribute
     1429      oldmod = .modify
     1430      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1431      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
     1432      if not class then
     1433         iterate
     1434      endif
     1435      if bmperm <> 4 then
     1436         .modify = oldmod
     1437      endif
     1438      if bmperm = 4 then
     1439         bmtype = 'permanent'
     1440      else
     1441         bmtype = 'non-permanent'
     1442      endif
     1443      --dprintf( 'DelBookmarkInRegion: Deleted 'bmtype' bookmark with idx 'val' at line = 'line', col = 'col', offst = 'offst)
     1444
     1445      rcx = 0
     1446   enddo
     1447
     1448   rc = rcx
     1449   return
     1450
     1451; ---------------------------------------------------------------------------
     1452defproc ChangeBmAttrInMark( Action, mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid)
     1453
     1454   getfileid destfid
     1455   oldmod = .modify
     1456   -- Get idxmax value for bookmarks in destfile from before copy/move
     1457   destidxmax = GetAVar( 'bmname.'destfid'.0')
     1458   if destidxmax = '' then
     1459      destidxmax = 0
     1460   endif
     1461
     1462   getmark destfirstline, destlastline, destfirstcol, destlastcol, destfid
     1463   desttype = marktype()
     1464   Action = upcase( Action)
     1465
     1466   -- Change (append) idx values for copied bookmarks
     1467   -- Change array vars for copied bookmarks
     1468   SavedLine  = destfirstline
     1469   SavedCol   = destfirstcol
     1470   SavedOffst = -300
     1471   do forever
     1472      class = BOOKMARK_CLASS
     1473      line  = SavedLine
     1474      col   = SavedCol
     1475      offst = SavedOffst
     1476      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     1477      if not class then
     1478         leave
     1479      endif
     1480      if line > destlastline then
     1481         leave
     1482      elseif line = destlastline & col > destlastcol then
     1483         leave
     1484      elseif desttype = 'BLOCK' & (col < destfirstcol | col > destlastcol) then
     1485         iterate
     1486      endif
     1487      SavedLine  = line
     1488      SavedCol   = col
     1489      SavedOffst = offst
     1490
     1491      -- Query attribute to get val and ispush
     1492      query_attribute class, val, ispush, offst, col, line
     1493      bmperm = ispush
     1494
     1495      -- Get bmname for the previously marked file with the same idx value
     1496      bmidx = val
     1497      bmname = GetAVar( 'bmname.'mkfid'.'bmidx)
     1498      --dprintf( 'Found bookmark  : line = 'line', col = 'col', bmname = 'bmname', bmidx = 'bmidx', offst = 'offst', class = 'class)
     1499
     1500      -- For copy mark or for move mark to another file
     1501      if (Action = 'COPY' | destfid <> mkfid) then
     1502         -- Delete copied bookmark with old bmidx
     1503         class = BOOKMARK_CLASS
     1504         line  = SavedLine
     1505         col   = SavedCol
     1506         offst = SavedOffst
     1507         attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1508         -- attribute_action DELETE_ATTR_SUBOP sets class = 1 instead of 13 (bookmark).
     1509         --dprintf( 'After delete bm : line = 'line', col = 'col', bmname = 'bmname', bmidx = 'bmidx', offst = 'offst', class = 'class)
     1510
     1511         -- Recreate copied bookmark with new bmidx
     1512         class = BOOKMARK_CLASS
     1513         line  = SavedLine
     1514         col   = SavedCol
     1515         offst = SavedOffst
     1516         destidx = destidxmax + 1
     1517         val = destidx
     1518         insert_attribute class, val, bmperm, offst, col, line
     1519
     1520         -- Change/create name array var
     1521         SetAVar( 'bmname.'destfid'.'destidx, bmname)
     1522         SetAVar( 'bmname.'destfid'.0', destidx)
     1523
     1524         -- Set save as EA bit
     1525         if bmperm = 4 then
     1526            Attribute_On( 8)  -- "Save attributes" flag
     1527         else
     1528            .modify = oldmod
     1529         endif
     1530         --dprintf( 'Changed bookmark: line = 'line', col = 'col', bmname = 'bmname', destidx = 'destidx', offst = 'offst', class = 'class)
     1531      endif
     1532
     1533   enddo
     1534
     1535; ---------------------------------------------------------------------------
     1536; Syntax: DeleteBmClass bmtype
     1537; Deletes all bookmarks of type 3 (non-permanent) or 4 (permanent).
     1538; When bmtype = 4 is specified, a MsgBox pops up to confirm the deletion.
     1539defc DeleteBmClass
     1540   parse arg Bmtype .
     1541   if Bmtype = '' then
     1542      sayerror NEED_BM_CLASS__MSG
     1543      return
     1544   endif
     1545   if Bmtype = 4 then
     1546      if AskYesNo( DELETE_PERM_BM__MSG) <> YES_CHAR then
     1547         return
     1548      endif
     1549   endif
     1550   getfileid bmfid
     1551
     1552   line  = 0
     1553   col   = 1
     1554   offst = 0
     1555   oldmod = .modify
     1556   do forever
     1557      class = BOOKMARK_CLASS
     1558      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
     1559      if class = 0 then  -- No more of that class
     1560         leave
     1561      endif
     1562
     1563      query_attribute class, val, ispush, offst, col, line
     1564
     1565      if ispush = Bmtype then
     1566         -- Delete attribute
     1567         attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1568         -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
     1569      endif
     1570   enddo
     1571
     1572   if BMtype <> 4 then
     1573      .modify = oldmod
     1574   endif
     1575
     1576; ---------------------------------------------------------------------------
     1577defc NextBookmark
     1578   parse arg next bmclass .
     1579
     1580   class = BOOKMARK_CLASS
     1581   col   = .col
     1582   line  = .line
     1583   offst = 0
     1584   if next = 'P' then
     1585      col = col - 1
     1586   endif
     1587   do forever
     1588      if next = 'P' then
     1589         Action = FIND_PREV_ATTR_SUBOP
     1590      else
     1591         Action = FIND_NEXT_ATTR_SUBOP
     1592      endif
     1593      attribute_action Action, class, offst, col, line
     1594      if class = 0 then
     1595         sayerror BM_NOT_FOUND__MSG
     1596         return
     1597      endif
     1598      query_attribute class, val, ispush, offst, col, line
     1599      if ispush = bmclass | bmclass = '' then
     1600         .cursory = .windowheight % 2
     1601         line
     1602         .col = col
     1603         'HighlightCursor'
     1604         return
     1605      endif
     1606   enddo
     1607
     1608; ===========================================================================
     1609; Part 3: Font and color attributes and styles
     1610; ===========================================================================
     1611
     1612; ---------------------------------------------------------------------------
     1613; Array var names were exchanged compared to the original:
     1614;    'stylename.0'           max. styleidx  (was 'si.0')
     1615;    'stylename.'styleidx    stylename      (was 'si.'styledx)
     1616;    'styleindex.'stylename  styleidx       (was 'sn.'stylename)
     1617; These array vars are valid for an EPM window. Styles are saved in NEPMD.INI
     1618; and style array vars were set only when styles are used in a file.
     1619defc ShowStyleAVars
     1620   styleidxmax = GetAVar( 'stylename.0')
     1621   dprintf( "GetAVar( 'stylename.0') = "styleidxmax)
     1622   do i = 1 to styleidxmax
     1623      sname = GetAVar( 'stylename.'i)
     1624      dprintf( "GetAVar( 'stylename."i"') = "sname)
     1625      styleidx = GetAVar( 'styleindex.'sname)
     1626      dprintf( "GetAVar( 'styleindex."sname"') = "styleidx)
     1627   enddo
    14501628
    14511629; ---------------------------------------------------------------------------
     
    15971775         do forever
    15981776            class = STYLE_CLASS
    1599             attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
     1777            attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
    16001778            if class = 0 then  -- not found
    16011779               leave
     
    16081786               if class = FONT_CLASS & val <> fontid then  -- Replace the font ID (if changed)
    16091787                  insert_attribute class, fontid, ispush, offst, col, line
    1610                   attribute_action 16, class, offst, col, line -- 16 = DELETE_ATTR_SUBOP
    1611                   -- attribute_action 16 changes class to 1 on deletion
     1788                  attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1789                  -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    16121790               endif
    16131791
     
    16161794               if class = COLOR_CLASS & val <> colornum then  -- Replace the color attribute (if changed)
    16171795                  insert_attribute class, colornum, ispush, offst, col, line
    1618                   attribute_action 16, class, offst, col, line -- 16 = DELETE_ATTR_SUBOP
    1619                   -- attribute_action 16 changes class to 1 on deletion
     1796                  attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1797                  -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    16201798               endif
    16211799            endif
     
    16621840         do forever
    16631841            class = STYLE_CLASS
    1664             attribute_action 1, class, offst, col, line -- 1 = FIND NEXT ATTR
     1842            attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
    16651843            if class = 0 then  -- not found
    16661844               if .modify <> oldmod then  -- We've deleted at least one...
     
    16741852            query_attribute class, val, ispush, offst, col, line
    16751853            if val = styleidx then  -- If it's this style, then...
    1676                attribute_action 16, class, offst, col, line -- 16 = DELETE_ATTR_SUBOP
    1677                -- attribute_action 16 changes class to 1 on deletion
     1854               attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1855               -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    16781856
    16791857               offst = offst + 1
    16801858               query_attribute class, val, ispush, offst, col, line
    16811859               if class = FONT_CLASS then  -- Delete the font ID
    1682                   attribute_action 16, class, offst, col, line -- 16 = DELETE_ATTR_SUBOP
    1683                   -- attribute_action 16 changes class to 1 on deletion
     1860                  attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1861                  -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    16841862               endif
    16851863
     
    16871865               query_attribute class, val, ispush, offst, col, line
    16881866               if class = COLOR_CLASS then  -- Delete the color attribute
    1689                   attribute_action 16, class, offst, col, line -- 16 = DELETE_ATTR_SUBOP
    1690                   -- attribute_action 16 changes class to 1 on deletion
     1867                  attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     1868                  -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    16911869               endif
    16921870            endif
     
    17021880
    17031881   activatefile startfid  -- Make sure we're back where we started (in case was .HIDDEN)
    1704 
    1705 ; ---------------------------------------------------------------------------
    1706 ; Delete all attributes of current file.
    1707 defc DeleteAllAttributes, DelAttribs
    1708    line  = 0
    1709    col   = 0
    1710    offst = -300
    1711    do forever
    1712       class = 0  -- 0 means: find all attributes
    1713       attribute_action 1, class, offst, col, line   -- find next attribute
    1714       if class = 0 then
    1715          leave
    1716       endif
    1717       attribute_action 16, class, offst, col, line  -- delete attribute
    1718       -- attribute_action 16 changes class to 1 on deletion
    1719    enddo
    17201882
    17211883; ===========================================================================
     
    17681930   do forever
    17691931      class = BOOKMARK_CLASS
    1770       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
     1932      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
    17711933      if class = 0 | line <> .line then
    17721934         sayerror NO_COMPILER_ERROR__MSG
     
    18622024   do forever
    18632025      class = BOOKMARK_CLASS
    1864       attribute_action 1, class, offst, col, line  -- 1 = FIND NEXT ATTR
     2026      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line
    18652027      if class = 0 then  -- No more of that class
    18662028         leave
     
    18722034
    18732035      -- Delete attribute
    1874       attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTIBUTE
    1875       -- attribute_action 16 changes class to 1 on deletion
     2036      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     2037      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    18762038
    18772039      class = COLOR_CLASS
     
    18792041      col   = 1
    18802042      line2 = line
    1881       attribute_action 1, class, offst, col, line2  -- 1 = FIND NEXT ATTR
     2043      attribute_action FIND_NEXT_ATTR_SUBOP, class, offst, col, line2
    18822044      if class = 0 | line2 <> line then  -- No color class
    18832045         iterate
     
    18912053      offst2 = offst
    18922054      col2   = col
    1893       attribute_action 3, class, offst2, col2, line2  -- 3 = FIND MATCH ATTR
     2055      attribute_action FIND_MATCH_ATTR_SUBOP, class, offst2, col2, line2
    18942056      if class then
    1895          attribute_action 16, class, offst2, col2, line2  -- 16 = DELETE ATTIBUTE
    1896          -- attribute_action 16 changes class to 1 on deletion
     2057         attribute_action DELETE_ATTR_SUBOP, class, offst2, col2, line2
     2058         -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    18972059      endif
    18982060
    18992061      class = COLOR_CLASS
    1900       attribute_action 16, class, offst, col, line  -- 16 = DELETE ATTIBUTE
    1901       -- attribute_action 16 changes class to 1 on deletion
     2062      attribute_action DELETE_ATTR_SUBOP, class, offst, col, line
     2063      -- attribute_action DELETE_ATTR_SUBOP changes class to 1 on deletion
    19022064   enddo
    19032065   .modify = oldmod
  • TabularUnified trunk/src/netlabs/macros/charops.e

    r3386 r3387  
    9595      endif
    9696
    97       call ChangeBmAttribInMark( 'COPY', mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid)
     97      call ChangeBmAttrInMark( 'COPY', mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid)
    9898   enddo
    9999
     
    134134      endif
    135135
    136       call ChangeBmAttribInMark( 'MOVE', mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid)
     136      call ChangeBmAttrInMark( 'MOVE', mkfirstline, mklastline, mkfirstcol, mklastcol, mkfid)
    137137   enddo
    138138
     
    303303   return
    304304
    305 ; ---------------------------------------------------------------------------
    306 defproc FastMoveAttrToBeg( theclass, thevalue, thepush, DestCol, DestLine, scol, slin, soff)
    307    if thepush <> 1 then    -- an end attribute cannot cancel any attribute
    308                            -- when placed at the beginning (most negative) so it must be
    309                            -- inserted...
    310       insert_attribute theclass, thevalue, thepush, -300, DestCol, DestLine
    311       attribute_action DELETE_ATTR_SUBOP, theclass, soff, scol, slin
    312    else                    -- this begin attribute must be checked for cancellation
    313       findclass  = theclass
    314       findoffset = soff
    315       findcolumn = scol
    316       findline   = slin
    317       attribute_action FIND_MATCH_ATTR_SUBOP, findclass, findoffset, findcolumn, findline
    318       if ((findcolumn == DestCol) and (findline == DestLine)) then
    319          -- then the attribute is canceled out
    320          attribute_action DELETE_ATTR_SUBOP, theclass, soff, scol, slin
    321          attribute_action DELETE_ATTR_SUBOP, theclass, findoffset, findcolumn, findline
    322       else
    323          insert_attribute theclass, thevalue, thepush, -300, DestCol, DestLine
    324          attribute_action DELETE_ATTR_SUBOP, theclass, soff, scol, slin
    325       endif
    326    endif
    327 
  • TabularUnified trunk/src/netlabs/macros/keys.e

    r3371 r3387  
    35893589
    35903590   call NextCmdAltersText()
    3591    if .levelofattributesupport then
    3592 
    3593       if (.line == .last and .line <> 1) then   -- this is the last line
    3594          destinationLine = .line - 1            -- and there is a previous line to store attributes on
    3595          getline prevline, DestinationLine
    3596          DestinationCol = length(prevline) + 1  -- start search parameters
    3597                                                 -- destination of attributes
    3598          findoffset = -300                      -- start at the begin of the attr list
    3599          findline = .line                       -- of the first char on this line
    3600          findcolumn = 1
    3601 
    3602          do forever        -- search until no more attr's (since this is last line)
    3603             findclass = 0          -- 0 is anyclass
    3604             Attribute_action FIND_NEXT_ATTR_SUBOP, findclass, findoffset, findcolumn, findline
    3605             if not findclass or (findline <> .line) then  -- No attribute, or not on this line
    3606                leave
    3607             endif
    3608             query_attribute theclass, thevalue, thepush, findoffset, findcolumn, findline   -- push or pop?
    3609             if not thePush then       -- ..if its a pop attr and ..
    3610                MatchClass = theClass
    3611                MatchOffset = FindOffset
    3612                MatchLine = FindLine
    3613                MatchColumn = FindColumn  -- ..and if its match is not on this line or at the destination
    3614                Attribute_Action FIND_MATCH_ATTR_SUBOP, MatchClass, MatchOffset, Matchcolumn, MatchLine
    3615                if ((Matchline == DestinationLine) and (Matchcolumn == destinationcol)) then
    3616                   -- then there is a cancellation of attributes
    3617                   Attribute_action Delete_ATTR_SUBOP, theclass, Findoffset, Findcolumn, Findline
    3618                   Attribute_action Delete_ATTR_SUBOP, Matchclass, Matchoffset, Matchcolumn, Matchline
    3619                elseif (MatchLine <> .line)  then
    3620                   -- .. then move attribute to destination (before attributes which have been scanned so its OK.)
    3621                   -- insert attr at the end of the attr list (offset=0)
    3622                   Insert_Attribute theclass, thevalue, 0, 0, DestinationCol, DestinationLine
    3623                   Attribute_action Delete_ATTR_SUBOP, theclass, Findoffset, Findcolumn, Findline
    3624                endif -- end if attr is on line or at destination
    3625             endif -- end if found attr is a pop
    3626          enddo  -- end search for attr's
    3627 
    3628       elseif .line < .last then  -- put the attributes after the line since there may not
    3629                                  -- be a line before this line (as when .line==1)
    3630          DestinationCol = 1
    3631          DestinationLine = .line + 1     -- error point since this puts attr's after last line if .line=.last
    3632          findoffset = 0                  -- cant make it .line-1 cause then present attributes there become
    3633          findline = .line                -- after these attributes which is wrong
    3634          findcolumn = MAXCOL
    3635 
    3636          do forever
    3637             findclass = 0
    3638             Attribute_action FIND_PREV_ATTR_SUBOP, findclass, findoffset, findcolumn, findline
    3639             if not findclass or (findline <> .line) then  -- No attribute, or not on this line
    3640                leave
    3641             endif
    3642             -- Move Attribute
    3643             query_attribute theclass, thevalue, thepush, findoffset, findcolumn, findline
    3644             -- only move push/pop model attributes (tags are just deleted)
    3645             if ((thepush == 0) or (thepush == 1)) then
    3646                -- move attribute to destination, if cancellation delete both attributes
    3647                FastMoveAttrToBeg( theclass, thevalue, thepush, DestinationCol, DestinationLine, findcolumn, findline, findoffset)
    3648                findoffset = findoffset + 1  -- since the attr rec was deleted and all attr rec's were shifted to fill the vacancy
    3649                                             -- and search is exclusive
    3650             endif
    3651          enddo
    3652 
    3653       endif -- endif .line=.last and .line=1
    3654 
    3655    endif -- .levelofattributesupport
     3591   call DelAttrInLine()
    36563592
    36573593   deleteline
  • TabularUnified trunk/src/netlabs/macros/newmenu.e

    r3367 r3387  
    14731473   DefMenuItem( '',                                                                 -- Remove all attributes
    14741474                'R~emove all attributes',
    1475                 'DelAttribs',
     1475                'DelAllAttr',
    14761476                'Remove all attributes, even bookmarks, from current file',
    14771477                '')
Note: See TracChangeset for help on using the changeset viewer.