File: n_svc_dwlv.sru
Size: 27245
Date: Mon, 07 Apr 2008 21:31:44 +0200
$PBExportHeader$n_svc_dwlv.sru
$PBExportComments$u_dwlv service
forward
global type n_svc_dwlv from n_svc_dw_form
end type
end forward

global type n_svc_dwlv from n_svc_dw_form
boolean #pooled = true
end type
global n_svc_dwlv n_svc_dwlv

type variables
Private:

//cache directory
CONSTANT string CACHE_DIRECTORY = "KodigoHeaderCache"

//prefix-suffix
CONSTANT string HEADER = "dwlvheader"
CONSTANT string LINES = "line"
CONSTANT string NORMAL = "_n"
CONSTANT string HOT = "_h"

/*
 1 = dwobjname
 2 = filename
 3 = x
 4 = y
 5 = width
 6 = height
*/

CONSTANT string NORMAL_LINE_SYNTAX = 'CREATE bitmap(band=header filename="{2}" x="{3}" y="{4}" height="{6}" width="{5}" border="0" name={1} visible="1")'
CONSTANT string HOT_LINE_SYNTAX = 'CREATE bitmap(band=header filename="{2}" x="{3}" y="{4}" height="{6}" width="{5}" border="0" name={1} visible="0")'

/*
 1 - name
 2 - text
 3 - x
 4 - y
 5 - width
 6 - height
 7 - color
*/
CONSTANT string HOT_BACKGROUND_SYNTAX = 'CREATE text(band=header alignment="0" text="{2}" border="0" color="0" x="{3}" y="{4}" height="{6}" width="{5}" html.valueishtml="0"  name={1} visible="0"  font.face="Tahoma" font.height="-8" font.weight="400"  font.family="2" font.pitch="2" font.charset="0" background.mode="0" background.color="{7}")'

CONSTANT string F_EXT = ".bmp"

CONSTANT string GRAYSEP1 = "gsep1_"
CONSTANT string GRAYSEP2 = "gsep2_"

CONSTANT string GAP = "48"
CONSTANT long MINWIDTH = 64
CONSTANT long SIZE_TOLERANCE = 24

/*
1 - name
2 - color
3 - x
4 - y
5 - width
6 - height
*/
CONSTANT string GRAY = "text(band=header alignment='0' text='' border='0' color='{2}' x='{3}' y='{4}' height='{6}' width='{5}' html.valueishtml='0'  name={1} visible='1'  font.face='Marlett' font.height='-12' font.weight='400'  font.family='0' font.pitch='2' font.charset='2' background.mode='0' background.color='{2}')"
/*
1 - name
2 - color
3 - x
*/
CONSTANT string SEP = "text(band=foreground alignment='0' text='' border='0' color='{2}' x='{3}' y='12' height='{4}' width='4' html.valueishtml='0'  name={1} visible='1'  font.face='Marlett' font.height='-12' font.weight='400'  font.family='0' font.pitch='2' font.charset='2' background.mode='0' background.color='{2}')"// pointer='SizeWE!')"
/*
1 - name
2 - x
3 - text
*/
CONSTANT string ARROW = "text(band=foreground alignment='0' text='{3}' border='0' color='268435456' x='{2}' y='0' height='48' width='55' html.valueishtml='0'  name={1} visible='1'  font.face='Marlett' font.height='-12' font.weight='400'  font.family='0' font.pitch='2' font.charset='2' background.mode='1' background.color='553648127')"
/*
1 - name
2 - x
3 - width
4 - height
5 - color
*/
CONSTANT string SHADE = "text(band=background alignment='0' text='' border='0' color='268435456' x='{2}' y='0' height='{4}' width='{3}' html.valueishtml='0'  name={1} visible='1'  font.face='Marlett' font.height='-12' font.weight='400'  font.family='0' font.pitch='2' font.charset='2' background.mode='0' background.color='{5}')"
CONSTANT string ARROW_ASCENDING = "t"
CONSTANT string ARROW_DESCENDING = "u"
CONSTANT string HEADER_HEIGHT = "80"
CONSTANT string ARROW_SUFFIX = "_arrow"
CONSTANT string SHADE_SUFFIX = "_shade"
end variables

forward prototypes
public subroutine of_resizelines (readonly u_dwlv adw, readonly str_dwheader headers[])
public function boolean of_isheader (readonly string as_dwoname, readonly str_dwheader astr_headers[])
public function boolean of_isinheader (readonly u_dwlv adw, readonly integer xpos, readonly integer ypos)
public subroutine of_resizeheader (readonly u_dwlv adw, readonly integer ai_index, long al_xpos, ref str_dwheader astr_headers[], ref long al_anchor)
public subroutine of_showsortarrows (readonly u_dwlv adw, readonly str_dwheader astr_headers[])
public function boolean of_isexcluded (readonly string as_header, readonly str_dwheader astr_exclude[])
public subroutine of_hotheader (ref n_svc_mgr anv_svc, readonly u_dwlv adw, readonly string as_dwoname, readonly str_dwheader astr_headers[])
public function long of_isbetween (readonly u_dwlv adw, integer ai_xpos, integer ai_ypos, readonly str_dwheader astr_headers[], readonly str_dwheader astr_exclude[])
public function integer of_getheaderindex (readonly string as_dwoname, readonly string as_headers[])
public function integer of_getheaderindex (readonly string as_dwoname, readonly str_dwheader astr_headers[])
public subroutine of_pressheader (readonly u_dwlv adw, readonly str_dwheader astr_header, readonly boolean ab_press)
public function long of_markanchor (readonly u_dwlv adw, readonly integer ai_xpos, readonly integer ai_ypos, readonly str_dwheader astr_headers[], readonly str_dwheader astr_exclude[])
public subroutine of_clicked (ref n_svc_mgr anv_svc, readonly u_dwlv adw, string as_object, ref str_dwheader astr_headers[], readonly str_dwheader astr_exclude[])
public subroutine of_editmode (ref n_svc_mgr anv_svc, readonly u_dw_form adw, readonly string as_taborders, readonly string as_validatecolumns[], readonly boolean ab_editmode)
public subroutine of_dwmousemove (ref n_svc_mgr anv_svc, readonly u_dwlv adw, readonly integer ai_xpos, readonly integer ai_ypos, readonly long al_row, readonly string as_dwoname, ref str_dwheader astr_headers[], readonly str_dwheader astr_exclude[], readonly boolean ab_mousedown, ref boolean ab_mousecaptured, readonly boolean ab_allowhot, ref long al_anchor, ref long al_sizeindex)
public subroutine of_alternaterowcolor (readonly u_dwlv adw, readonly boolean ab_alternate, readonly long al_alternatecolor)
protected function string of_getlinenormalname ()
protected function string of_getlinehotname ()
public function integer of_settheme (ref n_svc_mgr anv_svc, readonly u_dwlv adw, readonly str_dwheader astr_headers[], readonly str_theme astr)
public function integer of_makedwlv (ref n_svc_mgr anv_svc, readonly u_dwlv adw, ref str_dwheader astr_headers[])
end prototypes

public subroutine of_resizelines (readonly u_dwlv adw, readonly str_dwheader headers[]);long ll, n, llt, llp
string lsx, lsw, lsw2, ls_mod

ll = UPPERBOUND(headers)

lsw = STRING(LONG(adw.Describe(headers[ll].header + ".x")) + LONG(adw.Describe(headers[ll].header + ".width")))

ls_mod = of_GetLineNormalName() + ".width=" + lsw

//position separators
FOR n = 1 to ll
   llt = LONG(adw.Describe(headers[n].header + ".X")) + LONG(adw.Describe(headers[n].header + ".Width"))
   llp = UnitsToPixels(llt, XUnitsToPixels!)
   lsw = STRING(llt)
   lsx = STRING(PixelsToUnits(llp - 1, XPixelsToUnits!))
   ls_mod += " " + GRAYSEP1 + headers[n].header + ".X=" + lsx

   lsx = STRING(PixelsToUnits(llp - 2, XPixelsToUnits!))
   ls_mod += " " + GRAYSEP2 + headers[n].header + ".X=" + lsx
NEXT

adw.Modify(ls_mod)
this.of_ShowSortArrows(adw, headers)
end subroutine

public function boolean of_isheader (readonly string as_dwoname, readonly str_dwheader astr_headers[]);long llc, n

//check name
IF POS(as_dwoname, HEADER) > 0 THEN RETURN TRUE

llc = UPPERBOUND(astr_headers)
FOR n = 1 to llc
   IF as_dwoname = astr_headers[n].header THEN RETURN TRUE
NEXT

RETURN FALSE
end function

public function boolean of_isinheader (readonly u_dwlv adw, readonly integer xpos, readonly integer ypos);long ll, ll2

ll = PixelsToUnits(ypos, YPixelsToUnits!)
ll2 = PixelsToUnits(xpos, XPixelsToUnits!)

IF ll < 0 THEN RETURN FALSE
IF ll2 < 0 THEN RETURN FALSE

RETURN ll <= LONG(adw.Describe("Datawindow.Header.height")) AND (ll2 <= adw.width)
end function

public subroutine of_resizeheader (readonly u_dwlv adw, readonly integer ai_index, long al_xpos, ref str_dwheader astr_headers[], ref long al_anchor);string ls_mod
long ll_newwidth, ll_inc, llx, llc, n, llw, lls
string lsx, ls_column

IF al_anchor = CRet.FAILURE THEN RETURN

al_xpos += UnitsToPixels(LONG(adw.Describe("Datawindow.HorizontalScrollPosition")), XUnitsTopixels!)

llx = LONG(adw.Describe(astr_headers[ai_index].header + ".x"))
//header resize
llw = UnitsToPixels(LONG(adw.Describe(astr_headers[ai_index].header + ".width")), XUnitsToPixels!)
ll_inc = al_xpos - al_anchor
ll_newwidth = llw + ll_inc
ll_newwidth = PixelsToUnits(ll_newwidth, XPixelsToUnits!)
IF ll_newwidth <= MINWIDTH THEN RETURN
ls_mod = astr_headers[ai_index].header + ".width=" + STRING(ll_newwidth)
//column resize
ls_column = astr_headers[ai_index].column
llw = UnitsToPixels(LONG(adw.Describe(ls_column + ".width")), XUnitsToPixels!)
ll_newwidth = llw + ll_inc
ll_newwidth = PixelsToUnits(ll_newwidth, XPixelsToUnits!)
ls_mod += " " + ls_column + ".width=" + STRING(ll_newwidth)
astr_headers[ai_index].lgap = (llx + ll_newwidth) - size_tolerance
astr_headers[ai_index].rgap = (llx + ll_newwidth) + size_tolerance
//set new al_anchor
al_anchor = al_xpos

llc = UPPERBOUND(astr_headers)

IF ai_index < llc THEN
   lls = ai_index + 1
   ll_inc = PixelsToUnits(ll_inc, XPixelsToUnits!)
   FOR n = lls to llc
      lsx = adw.Describe(astr_headers[n].header + ".x")
      llw = LONG(adw.Describe(astr_headers[n].header + ".width"))
      llx = LONG(lsx) + ll_inc
      astr_headers[n].lgap = (llx + llw) - size_tolerance
      astr_headers[n].rgap = (llx + llw) + size_tolerance      
      ls_mod += " " + astr_headers[n].header + ".x=" + STRING(llx)
      ls_column = astr_headers[n].column
      lsx = adw.Describe(ls_column + ".x")
      ls_mod += " " + ls_column + ".x=" + STRING(LONG(lsx) + ll_inc)
   NEXT
END IF

//one-hit modify
adw.SetRedraw(FALSE)
adw.Modify(ls_mod)
//fire event
adw.EVENT ke_headersizing(ai_index)
//resize line
this.of_ResizeLines(adw, astr_headers)
adw.SetRedraw(TRUE)
end subroutine

public subroutine of_showsortarrows (readonly u_dwlv adw, readonly str_dwheader astr_headers[]);n_svc_mgr lnv_svc
n_svc_string lnv_str
long ll_count, n, ll_x, ll_w, ll_h, ll_color
string ls_cols[], ls_sort[], ls_mod, ls_modtmp
string ls_shade, ls_arrow, ls_header, ls_sorttype, ls_amod
Boolean lb_mod
string ls_x, ls_w

IF NOT ISVALID(adw) THEN RETURN

//load services
lnv_svc.of_LoadSvc(lnv_str, CSvc.STRING)
   
//set shade color
ll_color = CColor.WHITE_SMOKE
   
//destroy arrows
ll_count = UPPERBOUND(astr_headers)
FOR n = 1 to ll_count
   //arrows
   ls_arrow = astr_headers[n].column + ARROW_SUFFIX
   ls_mod = "DESTROY " + ls_arrow
   adw.Modify(ls_mod)
   ls_shade = astr_headers[n].column + SHADE_SUFFIX
   ls_mod = "DESTROY " + ls_shade
   adw.Modify(ls_mod)
NEXT
   
//create sort arrows
ll_count = this.of_getsort(lnv_svc, adw, ls_cols, ls_sort)
FOR n = 1 to ll_count
   //build arrow
   ls_header = ls_cols[n] + "_t"
   IF NOT this.of_isheader(ls_header, astr_headers) THEN CONTINUE
   //flag draw
   lb_mod = TRUE     
   ls_arrow = ls_cols[n] + ARROW_SUFFIX
   //get coord
   ll_x = LONG(adw.Describe(ls_header + ".X")) + LONG(adw.Describe(ls_header + ".width")) - 80
   //get sort type
   IF ls_sort[n] = "A" THEN
      ls_sorttype = ARROW_ASCENDING
   ELSE
      ls_sorttype = ARROW_DESCENDING
   END IF
   ls_mod = "CREATE " + lnv_str.of_Format(ARROW, {ls_arrow, STRING(ll_x), ls_sorttype})
   adw.Modify(ls_mod)
   //build shade
   ls_shade = ls_cols[n] + SHADE_SUFFIX
   //get coord
   ll_x = LONG(adw.Describe(ls_header + ".X")) - LONG(GAP)
   ll_w = LONG(adw.Describe(ls_header + ".width")) + LONG(GAP)
   ll_h = LONG(adw.Describe("Datawindow.Detail.height")) + 30 //off-set
   ll_h *= adw.RowCount()
   IF ll_h < adw.Height THEN ll_h = adw.Height
   ls_mod = "CREATE " + lnv_str.of_Format(SHADE, {ls_shade, STRING(ll_x), STRING(ll_w), STRING(ll_h), STRING(ll_color)})
   adw.Modify(ls_mod)
NEXT
end subroutine

public function boolean of_isexcluded (readonly string as_header, readonly str_dwheader astr_exclude[]);long llc, n

llc = UPPERBOUND(astr_exclude)
FOR n = 1 to llc
   IF as_header = astr_exclude[n].header THEN RETURN TRUE
NEXT

RETURN FALSE
end function

public subroutine of_hotheader (ref n_svc_mgr anv_svc, readonly u_dwlv adw, readonly string as_dwoname, readonly str_dwheader astr_headers[]);n_svc_win32 lnw
n_svc_string lns
string ls_mod
long ll_color, ll_count, n, ll_color2
long llt
string ls_x, ls_h, ls_w

IF NOT this.of_IsHeader(as_dwoname, astr_headers) THEN
   ls_mod = HEADER + ".Visible=0"
   ls_mod += CString.SPACE + HEADER + LINES + HOT + ".Visible=0"
   adw.Modify(ls_mod)
   RETURN
ELSE
   //is it hot already?
   long ll_index, ll
   string lsw, lsx
   
   ls_mod = HEADER + ".Visible=1"
   ls_mod += CString.SPACE + of_GetLineHotName() + ".Visible=1"
   
   ll_index = of_GetHeaderIndex(as_dwoname, astr_headers)
   IF ll_index > 0 THEN
      ll = LONG(adw.Describe(astr_headers[ll_index].header + ".x"))
      ll = UnitsToPixels(ll - LONG(GAP), XUnitsToPixels!)
      lsx = STRING(PixelsToUnits(ll, XPixelsToUnits!))
      
      lsw = STRING(LONG(adw.Describe(astr_headers[ll_index].header + ".width")) + LONG(GAP) + 4)
      ls_mod += CString.SPACE + HEADER + ".x=" + lsx
      ls_mod += CString.SPACE + HEADER + ".width=" + lsw
      ls_mod += CString.SPACE + of_GetLineHotName() + ".x=" + lsx
      ls_mod += CString.SPACE + of_GetLineHotName() + ".width=" + lsw
   END IF

   adw.Modify(ls_mod)
   RETURN
END IF
end subroutine

public function long of_isbetween (readonly u_dwlv adw, integer ai_xpos, integer ai_ypos, readonly str_dwheader astr_headers[], readonly str_dwheader astr_exclude[]);long llc, n, llc2, m
boolean lb

ai_xpos = PixelsToUnits(ai_xpos, XPixelsToUnits!)
ai_ypos = PixelsToUnits(ai_ypos, YPixelsToUnits!)

IF ai_ypos > LONG(adw.Describe("Datawindow.Header.Height")) THEN RETURN CRet.FAILURE

llc = UPPERBOUND(astr_headers)
llc2 = UPPERBOUND(astr_exclude)
ai_xpos += LONG(adw.Describe("Datawindow.HorizontalScrollPosition"))
FOR n = 1 to llc
   lb = FALSE
   FOR m = 1 to llc2
      IF astr_headers[n].header = astr_exclude[m].header THEN
         lb = TRUE
         EXIT
      END IF
   NEXT
   IF lb THEN CONTINUE
   IF ai_xpos >= astr_headers[n].lgap AND ai_xpos <= astr_headers[n].rgap THEN RETURN n
NEXT

RETURN CRet.FAILURE
end function

public function integer of_getheaderindex (readonly string as_dwoname, readonly string as_headers[]);long llc, n

llc = UPPERBOUND(as_headers)
FOR n = 1 to llc
   IF as_dwoname = as_headers[n] THEN RETURN n
NEXT

RETURN CRet.FAILURE
end function

public function integer of_getheaderindex (readonly string as_dwoname, readonly str_dwheader astr_headers[]);long llc, n

llc = UPPERBOUND(astr_headers)
FOR n = 1 to llc
   IF as_dwoname = astr_headers[n].header THEN RETURN n
NEXT

RETURN CRet.FAILURE
end function

public subroutine of_pressheader (readonly u_dwlv adw, readonly str_dwheader astr_header, readonly boolean ab_press);string ls_val, ls_mod, ls_vis
long ll_color, llpx

IF ab_press THEN
   ll_color = RGB(210, 210, 210)
   ls_vis = "0"
ELSE
   n_svc_mgr lnv_svc
   n_svc_theme lnv_t
   str_theme lstr
   
   lnv_svc.of_LoadSvc(lnv_t, CSvc.THEME)
   lstr = lnv_t.of_GetTheme()
   ll_color = lstr.ListviewBackgroundHot
   ls_vis = "1"
END IF

//IF adw.PointerY() > 0 AND adw.PointerY() < LONG(adw.Describe("Datawindow.Header.Height")) THEN
IF adw.Describe(HEADER + ".Visible") = "1" THEN
   ls_mod += of_GetLineHotName() + ".Visible='" + ls_vis + "'"
END IF
ls_mod += CString.SPACE + HEADER + ".Background.Color=" + STRING(ll_color)

long llp

llp = LONG(adw.Describe("Datawindow.Header.Height")) * .15

IF ab_press THEN
   llpx = UnitsToPixels(LONG(adw.Describe(astr_header.header + ".X")), XUnitsToPixels!)
   ls_mod += " " + astr_header.header + ".X=" + STRING(PixelsToUnits(llpx + 1, XPixelsToUnits!))
   ls_mod += " " + astr_header.header + ".Y=" + STRING(llp + 4)//16"// + STRING(INTEGER(adw.Describe(astr_header.header + ".Y")) + 4)
ELSE
   IF INTEGER(adw.Describe(astr_header.header + ".Y")) > llp THEN
      llpx = UnitsToPixels(LONG(adw.Describe(astr_header.header + ".X")), XUnitsToPixels!)
      ls_mod += " " + astr_header.header + ".X=" + STRING(PixelsToUnits(llpx - 1, XPixelsToUnits!))
      ls_mod += " " + astr_header.header + ".Y=" + STRING(llp)//12" //+ STRING(INTEGER(adw.Describe(astr_header.header + ".Y")) - 4)
   END IF
END IF

adw.Modify(ls_mod)
end subroutine

public function long of_markanchor (readonly u_dwlv adw, readonly integer ai_xpos, readonly integer ai_ypos, readonly str_dwheader astr_headers[], readonly str_dwheader astr_exclude[]);long ll_index

ll_index = this.of_IsBetween(adw, ai_xpos, ai_ypos, astr_headers, astr_exclude)

IF ll_index <> CRet.FAILURE THEN
   RETURN ai_xpos + UnitsToPixels(LONG(adw.Describe("Datawindow.HorizontalScrollPosition")), XUnitsToPixels!)
END IF

RETURN CRet.FAILURE
end function

public subroutine of_clicked (ref n_svc_mgr anv_svc, readonly u_dwlv adw, string as_object, ref str_dwheader astr_headers[], readonly str_dwheader astr_exclude[]);string ls_sort, ls_cols[], ls_type[], ls_sorttype
long ll_count, n
Boolean lb_found

//skip astr_excluded 
IF this.of_isexcluded(as_object, astr_exclude) THEN RETURN

as_object = MID(as_object, 1, LEN(as_object) - 2)

//get prev sort
ll_count = this.of_GetSort(anv_svc, adw, ls_cols, ls_type)
IF ll_count > 0 THEN
   FOR n = 1 to ll_count
      IF ls_cols[n] = as_object THEN
         lb_found = TRUE
         IF ls_type[n] = "A" THEN
            ls_sorttype = " D"
         ELSE
            ls_sorttype = " A"
         END IF
         ls_sort += ls_cols[n] + ls_sorttype
      END IF
   NEXT
   IF NOT lb_found THEN ls_sort = as_object + " A"
ELSE
   ls_sort = as_object + " A"
END IF

adw.SetSort(ls_sort)
adw.Sort()

adw.EVENT ke_rowchanged()

this.of_ShowSortArrows(adw, astr_headers)
end subroutine

public subroutine of_editmode (ref n_svc_mgr anv_svc, readonly u_dw_form adw, readonly string as_taborders, readonly string as_validatecolumns[], readonly boolean ab_editmode);long ll_count, n, ll_labelcolor, ll_backcolor
string ls_mod, ls_backmode, ls_weight

IF ab_editmode THEN
   of_SetTabSequence(anv_svc, adw, as_taborders)
   of_Removedropdownarrows(anv_svc, adw, FALSE)
   of_Standarddddw(anv_svc, adw)
   ll_labelcolor = REQUIRED_LABEL_COLOR
   ll_backcolor = REQUIRED_COLUMN_COLOR
   ls_backmode = "0"
   ls_weight = "400"
ELSE
   of_RemoveTabSequence(anv_svc, adw)
   of_Removedropdownarrows(anv_svc, adw, TRUE)
   ll_labelcolor = CColor.WINDOW_TEXT
   ll_backcolor = CColor.WINDOW_BACKGROUND
   ll_backcolor = CColor.WINDOW_BACKGROUND
   ls_backmode = "1"
   ls_weight = "400"
END IF

ll_count = UPPERBOUND(as_validatecolumns)

FOR n = 1 to ll_count
   ls_mod += as_validatecolumns[n] + "_t.Color=" + STRING(ll_labelcolor) + CString.SPACE &
          + as_validatecolumns[n] + "_t.Font.Weight=" + ls_weight + CString.SPACE &
          + as_validatecolumns[n] + ".Background.Mode =" + ls_backmode + CString.SPACE &
          + as_validatecolumns[n] + ".Background.Color=" + STRING(ll_backcolor) + CString.SPACE
NEXT

//one-hit modify
adw.Modify(ls_mod)
end subroutine

public subroutine of_dwmousemove (ref n_svc_mgr anv_svc, readonly u_dwlv adw, readonly integer ai_xpos, readonly integer ai_ypos, readonly long al_row, readonly string as_dwoname, ref str_dwheader astr_headers[], readonly str_dwheader astr_exclude[], readonly boolean ab_mousedown, ref boolean ab_mousecaptured, readonly boolean ab_allowhot, ref long al_anchor, ref long al_sizeindex);string ls_l, ls_r
string lslx, lslw, lsrx
long llc, n, ll_lt, ll_rt, ll_lindex
n_svc_win32 lnw

anv_svc.of_loadsvc(lnw, CSvc.WIN32)

IF this.of_IsInHeader(adw, ai_xpos, ai_ypos) THEN
   IF NOT ab_MouseCaptured THEN
      ab_MouseCaptured = TRUE
      lnw.SetCapture(Handle(adw))
   END IF
ELSE
   IF ab_MouseCaptured THEN
      ab_MouseCaptured = FALSE
      lnw.Releasecapture()
   END IF
END IF

//skip if excluded column
IF this.of_IsExcluded(as_dwoname, astr_exclude) THEN RETURN

//hot header
IF ab_allowhot THEN
   IF NOT ab_mousedown THEN
      this.of_HotHeader(anv_svc, adw, as_dwoname, astr_headers)
   ELSE
      this.of_HotHeader(anv_svc, adw, CString.EMPTY, astr_headers)
   END IF
END IF
//check if we are at header band
IF as_dwoname = CString.EMPTY THEN RETURN

IF NOT ab_mousedown THEN
   al_SizeIndex = this.of_IsBetween(adw, ai_xpos, ai_ypos, astr_headers, astr_exclude)
   IF al_SizeIndex = CRet.FAILURE THEN 
      SetPointer(Arrow!)
   ELSE
      SetPointer(SizeWE!)
   END IF
ELSE
   IF al_SizeIndex > 0 THEN
         SetPointer(SizeWE!)  
         this.of_ResizeHeader(adw, al_SizeIndex, ai_xpos, astr_headers, al_anchor)
   END IF
END IF
end subroutine

public subroutine of_alternaterowcolor (readonly u_dwlv adw, readonly boolean ab_alternate, readonly long al_alternatecolor);string ls_mod

IF ab_alternate THEN
   ls_mod = "Datawindow.Detail.Color=~"" + &
               STRING(CColor.WINDOW_BACKGROUND) + &
               "~tif (mod(getrow(), 2) = 0, " + STRING(al_alternatecolor) + &
               ", " + STRING(CColor.TRANSPARENT) + ")~""
ELSE
   ls_mod = "Datawindow.Detail.Color=" + STRING(CColor.TRANSPARENT)
END IF

ls_mod = adw.Modify(ls_mod)
end subroutine

protected function string of_getlinenormalname ();RETURN HEADER + LINES + NORMAL
end function

protected function string of_getlinehotname ();RETURN HEADER + LINES + HOT
end function

public function integer of_settheme (ref n_svc_mgr anv_svc, readonly u_dwlv adw, readonly str_dwheader astr_headers[], readonly str_theme astr);string ls_path, ls_filenamenorm, ls_filenamehot
n_svc_mgr lnv_svc
n_svc_files lnv_f
n_svc_resource lnv_r

lnv_svc.of_LoadSvc(lnv_f, CSvc.FILES)
ls_path = lnv_f.of_GetTempPath(lnv_svc)

ls_path = lnv_f.of_CombinePath(ls_path, CACHE_DIRECTORY)

IF NOT DirectoryExists(ls_path) THEN
   CreateDirectory(ls_path)
END IF

ls_filenamenorm = HEADER + LINES + STRING(astr.ThemeID) + NORMAL + F_EXT
ls_filenamenorm = lnv_f.of_CombinePath(ls_path, ls_filenamenorm)

lnv_svc.of_LoadSvc(lnv_r, CSvc.RESOURCE)

IF NOT FileExists(ls_filenamenorm) THEN
   lnv_r.of_MakeHeaderLine(anv_svc, &
      astr.listviewline1normal, &
      astr.listviewline2normal, &
      astr.listviewline3normal, &
      ls_filenamenorm)
END IF

ls_filenamehot = HEADER + LINES + STRING(astr.ThemeID) + HOT + F_EXT
ls_filenamehot = lnv_f.of_CombinePath(ls_path, ls_filenamehot)

IF NOT FileExists(ls_filenamehot) THEN
   lnv_r.of_MakeHeaderLine(anv_svc, &
      astr.listviewline1hot , &
      astr.listviewline2hot , &
      astr.listviewline3hot, &
      ls_filenamehot)
END IF

string ls_mod

ls_mod = "Datawindow.Header.Color=" + STRING(astr.ListviewBackgroundNormal)
ls_mod += " " + HEADER + ".Background.Color=" + STRING(astr.ListviewBackgroundHot)
ls_mod += " " + of_GetLineNormalName() + ".FileName='" + ls_filenamenorm + "'"
ls_mod += " " + of_GetLineHotName() + ".FileName='" + ls_filenamehot + "'"

//separator
long ll_count, n

ll_count = UPPERBOUND(astr_headers)
FOR n = 1 to ll_count
   ls_mod += " " + GRAYSEP1 + astr_headers[n].header + ".Background.Color=" + STRING(astr.ListviewSeparator2)
   ls_mod += " " + GRAYSEP2 + astr_headers[n].header + ".Background.Color=" + STRING(astr.ListviewSeparator1)
NEXT

adw.Modify(ls_mod)

RETURN CRet.SUCCESS
end function

public function integer of_makedwlv (ref n_svc_mgr anv_svc, readonly u_dwlv adw, ref str_dwheader astr_headers[]);string ls_path, ls_filename
n_svc_mgr lnv_svc
n_svc_theme lnv_t
n_svc_string lnv_s
str_theme lstr
string ls_headerheight, ls_percenty, ls_liney, ls_sepheight

//make sure it's a tabular DW
IF of_GetDWStyle(adw) <> CDWProc.DEFAULT THEN RETURN CRet.FAILURE

string ls_mod, ls_cols[], lsw, lsx
long ll_count, n, llx, llw

IF adw.#FixedHeaderHeight THEN
   ls_headerheight = HEADER_HEIGHT
ELSE
   ls_headerheight = adw.Describe("Datawindow.Header.Height")
END IF

ls_mod = "Datawindow.Header.Height=" + ls_headerheight

ls_percenty = STRING(LONG(ls_headerheight) * .15, "#,##0")
ls_liney = STRING(PixelsToUnits( &
         UnitsToPixels(LONG(ls_headerheight), YUnitsToPixels!) - 3, &
         YPixelsToUnits!))

ls_sepheight = STRING(PixelsToUnits( &
         UnitsToPixels(LONG(ls_headerheight), YUnitsToPixels!) - 9, &
         YPixelsToUnits!))

//create lines, header
lnv_svc.of_LoadSvc(lnv_s, CSvc.STRING)

//normal line
/*
 1 = dwobjname
 2 = filename
 3 = x
 4 = yes
 5 = width
 6 = height
*/
ls_mod += " " + lnv_s.of_Format(NORMAL_LINE_SYNTAX, &
            {&
            of_GetLineNormalName(), &
            CString.EMPTY, &
            "0", &
            ls_liney, &
            "4", &
            STRING(PixelsToUnits(3, YPixelsToUnits!)) &
            })

//hot line
/*
 1 = dwobjname
 2 = filename
 3 = x
 4 = y
 5 = width
 6 = height
*/
ls_mod += " " + lnv_s.of_Format(HOT_LINE_SYNTAX, &
            {&
            of_GetLineHotName(), &
            CString.EMPTY, &
            "0", &
            ls_liney, &
            "4", &
            STRING(PixelsToUnits(3, YPixelsToUnits!)) &
            })

//header
/*
 1 - name
 2 - text
 3 - x
 4 - y
 5 - width
 6 - height
 7 - color
*/
ls_mod += " " + lnv_s.of_Format(HOT_BACKGROUND_SYNTAX, &
            {&
            HEADER, &
            CString.EMPTY, &
            "0", &
            "0", &
            "4", &
            ls_headerheight, &
            STRING(CColor.WHITE) &
            })


ll_count = of_GetVisibleColumns(anv_svc, adw, ls_cols, CDWBand.DETAIL, TRUE, TRUE)
FOR n = 1 to ll_count
   astr_headers[n].header = ls_cols[n] + "_t"
   astr_headers[n].column = ls_cols[n]
   //flatten and not bold
   ls_mod += " " + astr_headers[n].header + ".Border=0 " + astr_headers[n].header + ".Background.Mode=1 " + astr_headers[n].header + ".Font.Weight=400"
   ls_mod += " " + astr_headers[n].header + ".Y=" + //12"
   ls_mod += " " + astr_headers[n].header + ".Height=" + ls_headerheight
   //set positions
   lsw = adw.Describe(astr_headers[n].header + ".width")
   IF NOT ISNUMBER(lsw) THEN lsw = GAP    
   IF n = 1 THEN
      ls_mod += " " + astr_headers[n].header + ".X=" + GAP
      llx = LONG(GAP)
      ls_mod += " " + ls_cols[n] + ".X=" + STRING(LONG(GAP) / 2)
      llx += LONG(lsw)
      llw = LONG(lsw)// - (LONG(GAP) / 8)
      ls_mod += " " + ls_cols[n] + ".width=" + STRING(llw)
   ELSE
      //get previous header x location and width
      lsx = adw.Describe(astr_headers[n].header + ".X")
      llx += LONG(GAP)
      ls_mod += " " + astr_headers[n].header + ".X=" + STRING(llx)
      ls_mod += " " + ls_cols[n] + ".X=" + STRING(llx - (LONG(GAP) / 2))
      llx += LONG(lsw)
      llw = LONG(lsw)
      ls_mod += " " + ls_cols[n] + ".width=" + STRING(llw)
   END IF
   astr_headers[n].lgap = llx - size_tolerance
   astr_headers[n].rgap = llx + size_tolerance

   //header separators
   lsx = STRING(llx)
   ls_mod += " CREATE " + lnv_s.of_format(SEP, {GRAYSEP1 + astr_headers[n].header, "0", lsx, ls_sepheight})
   lsx = STRING(LONG(lsx) - 4)
   ls_mod += " CREATE " + lnv_s.of_format(SEP, {GRAYSEP2 + astr_headers[n].header, "0", lsx, ls_sepheight})
NEXT

ls_mod = adw.Modify(ls_mod)

//create theme elements
lnv_svc.of_LoadSvc(lnv_t, CSvc.THEME)
lstr = lnv_t.of_GetTheme()
of_SetTheme(anv_svc, adw, astr_headers, lstr)

//position z order
FOR n = 1 to ll_count
   adw.SetPosition(GRAYSEP1 + astr_headers[n].header, "header", TRUE)
   adw.SetPosition(GRAYSEP2 + astr_headers[n].header, "header", TRUE)
NEXT
adw.SetPosition(of_GetLineNormalName(), "header", TRUE)
adw.SetPosition(HEADER, "header", TRUE)
FOR n = 1 to ll_count
   adw.SetPosition(astr_headers[n].header, "header", TRUE)
NEXT
adw.SetPosition(of_GetLineHotName(), "header", TRUE)

of_ResizeLines(adw, astr_headers)

RETURN CRet.SUCCESS
end function

on n_svc_dwlv.create
call super::create
end on

on n_svc_dwlv.destroy
call super::destroy
end on