#
# <20180709.1524.49>
#
# This bit of code attempts to fix a few short commings in tcl/tk on windows
# wrt selection and cut/paste.

# There are two parts to the cut/paste stuff on MSW, the private or local part
# and the global part. When a selection is made it is put in the private part
# (which tcl/tk docs call PRIMARY). If the selection is to be made global it
# is copied to the global part (called CLIPBOARD). This, in MSW, is done when
# a copy request is made (usually Cntl-C). Likewise, on the comsumption side
# there are two possible sources for a "paste". Tcl/tk code, for the most part
# uses the PRIMARY or private source unless it is empty, in which case it uses
# the CLIPBOARD or global source. To eliminate confusion in filerunner with
# this system, we will use <2> (<Button-2>) to paste from PRIMARY and Cntl-v
# to paste from CLIPBOARD.
# 
#
# Problem 1: On X11 systems when a selection is made in another window it is
#            removed from the window that currently holds the selection, even
#            if the new selection is in another application, but certainly in
#            the same application. In the MSW version of tcl/tk the selection
#            highlights remain on all past selections. At the same time the
#            last selection is the PRYMARY selection. The native (fr) code
#            seems to properly handle Listboxes so we don't provide help
#            here. Uh, except, we need to re-direct copy requests from any of
#            the multi-listbox windows to the hidden window (.fupper.selectTex)
#
# Problem 2: We (i.e. Tom) would like MSW systems to behave like X11 systems
#            i.e., we want to promote selections to the CLIPBOARD as soon as
#            they are made. This will make two modes of operation (MSW's and
#            X11) which we will use a configure option to seperate.
#           

# Problem 1 Solution:
#
# First, it appears that the selection and clipboard routines keep track of the
# current owner, but do not de-select when a new one arrives. This seems to be
# due to a lack of part of the notify code, mainly that the (I think) built in
# code to remove selections is not called. Here we use the supplied notify
# capability to call our own remove selections code.

# Problem 2 Solution:
#
# When ever we clock in a selection, if the bit allows, generate a <<Cut>>
# Its a bit more complicated for the multiListbox. There we keep track of
# <<ListboxSelect>> (a simple count), then on <Leave> of "." if there was
# one or more <<ListboxSelect>> events and the multiSelWindow has the
# selection, we send a <<Cut>> to the multiListbox window.
#
# What we have yet to do is detect other processes doing <<Cut>>s.
proc load_now_fix_cut_paste {} {}

# On loading:
namespace eval  winFixSel {
  variable curWin {}
  variable multiSelWindow ".fupper.selectTex"
  variable listboxLeave 0
}
# This helps the multilevel listbox export
bind MultiListbox <<Copy>> "event generate $winFixSel::multiSelWindow <<Copy>>
                            break"
bind MultiListbox <<ListboxSelect>> {+incr winFixSel::listboxLeave}
bind .       <Leave>       [list +winFixSel::leaveDot]     
bind Entry   <Leave>       [list +winFixSel::leave %W E ]
# bind Text    <Leave>       [list +winFixSel::leave %W T ]
bind Text    <<Selection>> [list +winFixSel::selText %W ]

bind TkConsole <<Selection>> [list +winFixSel::sel %W ]
# bind TkConsole <Leave>       [list +winFixSel::leave %W T ]
# bind Toplevel <Leave> 

# The intent is to use the first <<Selection>> to grab the
# selection. We then use the <Leave> to reset for next time.

proc winFixSel::selText {w} {
  variable curWin
  if {![$w cget -exportselection] || [$w tag ranges sel] == {}} {return}
  selection own -command [list  winFixSel::lostSel $w T] $w
  catch {
    if {$::config(X-behave) && [selection get] != {}} {
      event generate $w <<Copy>>
    }
  }
  set curWin $w
}

proc winFixSel::leave {w type} {
  variable curWin
  # If this window now owns the selection, set that up
  # Only Entry "E" and Text "T" comes here
  # frputs w "[selection own -displayof $w] "
  if {$type == "E"} {
    if {![$w cget -exportselection] || ![$w selection present]} {return}
    selection own -command [list  winFixSel::lostSel $w $type] $w
  } elseif {$type == "T"} {
    if {$curWin == {}} {
    return
    }
     set curWin {}
  }
  catch {
    if {[selection own] == $w && $::config(X-behave) && [selection get] != {}} {
      event generate $w <<Copy>>
    }
  }
}
# leaveDot's only function is, if config(Xbehave) is true to issue a
# <<Copy>> if the current select owner is the multiSelWindow
# and there has been a <<Selection>> from the multiListbox code.
# The listboxLeave variable prevents doing this when the mouse
# visits the window but does not select any thing.

proc winFixSel::leaveDot {} {
  variable multiSelWindow
  variable listboxLeave
  # frputs listboxLeave
  catch {
    if {$listboxLeave != 0 && \
	    $::config(X-behave) && \
	    [selection own] == $multiSelWindow && \
	    [selection get] != {}} {
      event generate $multiSelWindow <<Copy>>
    }
  }
  set listboxLeave 0
}

proc winFixSel::lostSel {w type} {
  variable curWin
  # frputs w
  switch -glob $type {
    L* {$w selection clear 0 end}
    E* {$w selection clear} 
    T* {$w tag remove sel 1.0 end}
  }
  
}

