Page 1 of 1

Unicode Character entry in Writer

PostPosted: Thu Nov 26, 2020 2:28 pm
by JeJe
Put the code in a module in MyMacros, set a shortcut to the macro NumberToUnicode

_____If no text has been selected_____
If the cursor follows a hex number the number will be converted to the Unicode character.

Otherwise a menu with a list of the Unicode characters already used (if any) will be shown for insertion. There is an option to add the previous character in the document to the menu.

_____If text has been selected_____
If a single character the character will be converted to its Unicode number

If a hex number the number will be converted to the Unicode character.

If two hex numbers with something-in-between (e.g. 2672, 2680)
It will be converted into a sequence of characters
♲, ♳, ♴, ♵, ♶, ♷, ♸, ♹, ♺, ♻, ♼, ♽, ♾, ♿, ⚀

If two character with something-in-between (e.g. F-A)
It will be converted into a sequence of characters
F-E-D-C-B-A



Code: Select all   Expand viewCollapse view

global PrevunicodeChars as string

Sub NumberToUnicode()
   dim vc

   vc = thiscomponent.currentcontroller.viewcursor

   select case len(vc.string)
   case 0
      if NumerToUnicodeIP<2 then ShowUniMenu

   case 1
      getUnicodeHexNumber

   case >1
      if NumerToUnicodeSel = false then UnicodeNumberSequence
   end select

End Sub


function ishexnumeric(st as string) as boolean
   select case asc(st)
   case 48 to 57,65 to 70, 97 to 102
      ishexnumeric=true
   end select
end function


function ishexnumericstring(st as string) as boolean
   ishexnumericstring=true
   for i =1 to len(st)
      if ishexnumeric(mid(st,i,1)) = false then
         ishexnumericstring=false
         exit for
      end if
   next
end function

sub getUnicodeHexNumber()
   dim st as string,vc
   vc = thiscomponent.currentcontroller.viewcursor
   st = vc.string
   vc.string= hex(asc(st))
end sub

function NumerToUnicodeIP() as long

   dim nlen as long,i as long,st as string

   vc = thiscomponent.currentcontroller.viewcursor

   tc = vc.text.createtextcursorbyrange(vc.end)

   for i = 0 to 3
      tc.goleft(1,true)

      if ishexNumeric(tc.string) = true then
         nlen = nlen+1
         tc.collapsetostart
      else
         exit for
      end if
   next

   NumerToUnicodeIP = nlen
   if nlen >=2 then
      vc.collapsetoend
      vc.goleft(nlen,true)
      st = chr("&H" & vc.string)
      AddtoPrevunicodeChars(st)
      vc.string =st
      vc.collapsetoend
   end if

end function

function NumerToUnicodeSel() as boolean

   dim nlen as long,i as long,st as string

   vc = thiscomponent.currentcontroller.viewcursor

   st = vc.string

   if len(st) <= 4 then
      for i = 1 to len(st)
         if ishexNumeric(mid(st,i,1)) = true then
            nlen = nlen+1
         else
            exit function
         end if
      next
   
   NumerToUnicodeSel =true
   vc.collapsetoend
   vc.goleft(nlen,true)
   st =chr("&H" & st)
   vc.string=st
   AddtoPrevunicodeChars(st)
   vc.collapsetoend
   end if
end function


sub ShowUniMenu()
   window = thiscomponent.currentcontroller.frame.componentwindow

   if PrevunicodeChars<>"" then st =prevunicodeChars & chr(0) & "_" & chr(0)
   st =st & "Add to menu"


   res = showpopup4(window,st,0,0,chr(0))


   select case res
   case "Add to menu"
      vc = thiscomponent.currentcontroller.viewcursor
      tc = vc.text.createtextcursorbyrange(vc)
      tc.goleft(1,true)
      st = tc.string
      if st<>"" then AddtoPrevunicodeChars(st)
   case else
      vc = thiscomponent.currentcontroller.viewcursor
      vc.string = res
      vc.collapsetoend
   end select
end sub


sub AddtoPrevunicodeChars(st)

   if instr(1,PrevunicodeChars,st)=0 then
      if PrevunicodeChars <>"" then PrevunicodeChars =PrevunicodeChars & chr(0)
      PrevunicodeChars =  PrevunicodeChars & st
   end if
end sub

sub UnicodeNumberSequence
   dim ano as string,bno as string,nst as string,i as long,st as string,vc,bst as string,ast as string

   vc = thiscomponent.currentcontroller.viewcursor
   st = vc.string
   lenst = len(st)
   '   if ishexnumeric(left(st,1)) and ishexnumeric(right(st,1)) then

   if len(st) >= 8 then
      ano= left(st,4)
      bno = right(st,4)
      if ishexnumericstring(ano) and ishexnumericstring(bno) then

         midbit = mid(st, len(ano)+1,len(st) - len(ano) - len(bno))
         if val("&H" & ano) <=  val("&H" & bno) then
            for i = val("&H" & ano) to  val("&H" & bno) step 1
               if nst<>"" then nst = nst & midbit
               nst = nst & chr(i)
            next
         else
            for i =   val("&H" & ano) to val("&H" & bno) step -1
               if nst<>"" then nst = nst & midbit
               nst = nst & chr(i)
            next
         end if
         vc.string = nst
         exit sub
      end if
   end if

   '   else 'character sequence
   ast = left(st,1)
   bst = right(st,1)
   a = asc(ast)
   b = asc(bst)
   midbit = mid(st,2,len(st)-2)
   if a<=b then
      for i = a to b
         if nst<>"" then nst = nst & midbit
         nst = nst & chr(i)
      next
   else
      for i = a to b step -1
         if nst<>"" then nst = nst & midbit
         nst = nst & chr(i)
      next
   end if

   vc.string = nst
end sub


'*****************helper menu function
function showpopup4(window,st as string,x,y,delimeter) as string
   'split by delimeter
   'separator_
   'note ~ identifies accelerator
   dim sts() as string,c as long
   aRect = CreateUnoStruct("com.sun.star.awt.Rectangle")
   arect.x = x
   arect.y =y

   oPopup = CreateUnoService("stardiv.vcl.PopupMenu")'"com.sun.star.awt.PopupMenu")

   sts = split(st,delimeter)

   for i = 0 to ubound(sts)
      c =c+1
      if sts(i) ="_" then
         oPopup.insertSeparator(c)
      else

         if mid(sts(i),1,1) ="!" then isdefault = true else isdefault = false

         if isdefault then
            mid(sts(i),1,1) =""
            oPopup.insertItem(c, sts(i),0, c)
            opopup.setDefaultItem c
         else
            oPopup.insertItem(c, sts(i),0, c)
            oPopup.setCommand(c, sts(i))
         end if
      end if
   next
   n = oPopup.execute( window, aRect, com.sun.star.awt.PopupMenuDirection.EXECUTE_DEFAULT)
   If n > 0 Then
      showpopup4 = oPopup.getCommand(n)
   end if

End function