Makrá v OpenOffice.org – vkladanie NBSP priamo počas písania (2)

Július Pastierik  /  30. 06. 2010, 14:43

V minulom dieli sme si ukázali základné funkcie pre obsluhu dialógu, v ktorom môžete definovať slová, okolo ktorých chcete vkladať nezalomiteľné medzery. V dnešnom pokračovaní si ukážeme ostatné funkcie pre vlastné vkladanie nezalomiteľných medzier počas písania textu.

 

Po zadefinovaní reťazcov, ktoré sme si ukázali v minulom dieli seriálu o makrách nám nezostáva už nič iné, ako vytvoriť procedúry pre vlastnú obsluhu klávesnice s tým, že pokiaľ stlačíme medzeru, tak sa okolo posledného slova, podľa jeho jazyka a definície príslušných textov vloží nezalomiteľná medzera.

Pretože OpenOffice.org umožňuje vkladať aj pružnú nezalomiteľnú medzeru (znak WJ), umožnili sme definovať aj to, či budeme používať znak NBSP alebo WJ. Toto nastavenie nebudeme jazykovo lokalizovať a budeme predpokladať, že ho budeme používať rovnako, bez ohľadu na aktuálny jazyk dokumentu. Napokon, pokiaľ sa nám nepáči nastavenie, môžeme ho kedykoľvek počas práce zmeniť.

global JP_ObsluhaKlavesnice as object
global JP_AktualnyJazyk, JP_pred_vm, JP_pred_oprava, JP_pred_bez, JP_za_vm, JP_za_oprava, JP_za_bez as string
global JP_WJ as boolean

REM Funkcia pre načítanie reťazcov (pri ktorých budeme vkladať NBSP) zo súborov
function nacitaj_subor(nazov, jazyk as string) as string
 dim vysledok, riadok as string
 dim sf, inStream, inFile ' Pre čítanie z lokalizačného súboru
 
 kde=basiclibraries.getLibraryLinkURL("JP_on_line_NBSP") ' Adresár, kde je rozšírenie nainštalované
 nazov=left(kde,len(kde)-10)+nazov+"_"+jazyk+".txt" ' Súbor s príslušnými textami
 
 vysledok=""
 
 if fileexists(nazov) then ' Ak súbor existuje, tak načítame definície do premenných
  ' Namiesto postupu, v ktorom sa nedá definovať kódová stránka:
  ' subor = Freefile
  ' open nazov for Input as #subor
  ' While not eof(subor)
  ' ...
  ' close #subor
  ' Použijeme postup s definovaním kódovej stránky TXT súboru:
  sf = createUnoService("com.sun.star.ucb.SimpleFileAccess")
  inStream = sf.openFileRead(nazov)
  inFile = createUnoService("com.sun.star.io.TextInputStream")
  inFile.InputStream = inStream
  inFile.Encoding = "UTF-8" ' Súbor musí byť v UTF-8, inak nebude dobrá diakritika
  
  Do While not inFile.IsEOF
   riadok = inFile.readLine ' namiesto Line Input #subor, riadok
   vysledok=vysledok+riadok
  loop
  ' Zatvorenie definičného súboru – namiesto close #subor
  inStream.closeInput
  inFile.closeInput
  vysledok=" "+vysledok+" "
 end if
 nacitaj_subor=vysledok
end function

REM Procedúra pre zápis reťazcov (pri ktorých budeme vkladať NBSP) do súborov
sub zapis_subor(nazov, jazyk, retazec as string)
 dim sf, outStream, outFile ' Pre čítanie z lokalizačného súboru
 
 kde=basiclibraries.getLibraryLinkURL("JP_on_line_NBSP") ' Adresár, kde je rozšírenie nainštalované
 nazov=left(kde,len(kde)-10)+nazov+"_"+jazyk+".txt" ' Súbor s príslušnými textami

 sf = createUnoService("com.sun.star.ucb.SimpleFileAccess")
 outStream = sf.openFileWrite(nazov)
 outFile = createUnoService("com.sun.star.io.TextOutputStream")
 outFile.OutputStream = outStream
 outFile.Encoding = "UTF-8" ' Súbor bude v UTF-8 aby bola dobrá diakritika
 outStream.truncate() ' Vymazanie predchádzajúceho obsahu
 outFile.writeString(retazec)
 outStream.closeOutput
 outFile.closeOutput
end sub

REM Procedúra pre načítanie konkrétnych reťazcov (za, pred ...)
sub nastav_texty(jazyk as string)
 if jazyk<>JP_AktualnyJazyk then ' Ak nemáme nastavené texty podľa odpamätaného jazyka, nastavíme ich
  JP_pred_vm=nacitaj_subor("JP_pred_vm",jazyk)
  JP_pred_oprava=nacitaj_subor("JP_pred_oprava",jazyk)
  JP_pred_bez=nacitaj_subor("JP_pred_bez",jazyk)
  JP_za_vm=nacitaj_subor("JP_za_vm",jazyk)
  JP_za_oprava=nacitaj_subor("JP_za_oprava",jazyk)
  JP_za_bez=nacitaj_subor("JP_za_bez",jazyk)
  JP_AktualnyJazyk=jazyk
  Set_NBSP_WJ
 endif
end sub

REM Procedúra, ktorá spustí vlastnú obsluhu klávesnice
sub SpustiObsluhuKlavesnice
 dim ObsluhaDokumentu
 on error goto next
 ' Obsluhu klávesnice spustíme iba vtedy, ak vôbec povolili zámenu predložiek
 ' a zároveň chceme túto zámenu robiť ON-line
 if ThisComponent.supportsService("com.sun.star.text.TextDocument") then
  ' Sme v textovom dokumente, kde chceme nahrádzať medzery
  UkonciObsluhuKlavesnice ' Ak už je spustená obsluha, viedlo by to k násobnému vkladaniu – preto ju preventívne zrušíme
  ObsluhaDokumentu = ThisComponent.getCurrentController
  if isnull(JP_ObsluhaKlavesnice) then JP_ObsluhaKlavesnice = createUnoListener("Klavesnica_","com.sun.star.awt.XKeyHandler") ' Ak nie je, pripravíme odkaz na obsluhu klávesnice
  ObsluhaDokumentu.addKeyHandler(JP_ObsluhaKlavesnice) ' Spojenie našej obsluhy klávesnice so štandardnou
 endif
end sub

REM Procedúra, ktorá ukončí vlastnú obsluhu klávesnice
sub UkonciObsluhuKlavesnice
 dim ObsluhaDokumentu
 on error goto next
 if ThisComponent.supportsService("com.sun.star.text.TextDocument") then
  ObsluhaDokumentu = ThisComponent.getCurrentController
  ' Sme v textovom dokumente a chceme ukončiť obsluhu klávesnice
  if not isnull(JP_ObsluhaKlavesnice) then ObsluhaDokumentu.removeKeyHandler(JP_ObsluhaKlavesnice)
 endif
end sub

REM Funkcia pre vloženie NBSP okolo reťazca
REM Funkcia sa volá pri stlačení medzery, teda sme na konci práve vloženého slova
function VlozZnak as boolean
 dim ViditelnyKurzor, AktualnyText, AktualnyKurzor as object
 dim vlozit as long

 if JP_WJ then
  Retazec=chr$(&H2060)+" " ' Word Joiner + medzera
 else
  retazec=chr$(&HA0) ' No Break Space
 endif
  
 ViditelnyKurzor = ThisComponent.getCurrentController().getViewCursor() ' Aktuálna pozícia kurzoru v texte
 nastav_texty(ViditelnyKurzor.CharLocale.Language) ' Nastavenie testovaných slov podľa aktuálneho jazyka znaku (sk, cs, ...)
 AktualnyText = ThisComponent.getText()
 AktualnyKurzor = AktualnyText.createTextCursorByRange(ViditelnyKurzor.getStart() ) ' Vytvorenie pomocného kurzoru na označenie a zistenie posledného slova
 
 AktualnyKurzor.gotoStartOfWord(false) ' Označíme posledné slovo
 AktualnyKurzor.goLeft(1, false) ' Označíme s jedným znakom pred
 AktualnyKurzor.gotoRange(ViditelnyKurzor.getStart(), true )
 
 Vlozit=instr(1,JP_pred_vm,AktualnyKurzor.string+" ",0) ' Zistíme, či treba vložiť pred s rozoznávaním veľkosti písma
 if Vlozit=0 then Vlozit=instr(1,JP_pred_bez,AktualnyKurzor.string+" ",1) ' Zistíme, či treba vložiť pred bez ohľadu na veľkosť písma
 if Vlozit<>0 then ' Ak áno, nahradíme medzeru pred
  AktualnyKurzor.setstring(Retazec+(right(AktualnyKurzor.string,len(AktualnyKurzor.string)-1))
 else
  Vlozit=instr(1,JP_pred_oprava,AktualnyKurzor.string+" ",1) ' Zistíme, či treba vložiť pred s opravou (nerozoznávame pri hľadaní malé a veľké písmená)
  if Vlozit<>0 then ' Ak áno, nahradíme medzeru pred plus opravíme text
   spom=mid(JP_pred_oprava,Vlozit+1,len(AktualnyKurzor.string)-1)
   AktualnyKurzor.setstring(Retazec+spom)
  endif
 endif
 
 AktualnyKurzor.collapseToEnd() ' Zrušíme označenie
 AktualnyKurzor.gotoStartOfWord(false) ' Označíme posledné slovo
 AktualnyKurzor.gotoRange(ViditelnyKurzor.getStart(), true )
 
 Vlozit=instr(1,JP_za_vm," "+AktualnyKurzor.string+" ",0) ' Zistíme, či treba vložiť za s rozoznávaním veľkosti písma
 if Vlozit=0 then Vlozit=instr(1,JP_za_bez," "+AktualnyKurzor.string+" ",1) ' Zistíme, či treba vložiť za bez ohľadu na veľkosť písma
 if Vlozit<>0 then ' Ak áno, nahradíme medzeru za
  AktualnyKurzor.setstring(AktualnyKurzor.string+Retazec)
 else
  Vlozit=instr(1,JP_za_oprava," "+AktualnyKurzor.string+" ",1) ' Zistíme, či treba vložiť za s opravou (nerozoznávame pri hľadaní malé a veľké písmená)
  if Vlozit<>0 then ' Ak áno, nahradíme medzeru za plus opravíme text
   spom=mid(JP_za_oprava,Vlozit+1,len(AktualnyKurzor.string))
   AktualnyKurzor.setstring(spom+Retazec)
  endif
 endif

 AktualnyKurzor.collapseToEnd() ' Zrušíme označenie
 if Vlozit<>0 then AktualnyText.insertString(AktualnyKurzor.getStart(), "", true)
 VlozZnak=Vlozit<>0
end function

REM Funkcia, ktorá sa volá pri stlačení ľubovoľnej klávesy
function Klavesnica_KeyPressed(StlacenaKlavesa) as boolean
' Obsluha stlačenej klávesy
 dim Obsluzena as boolean
 'Predpokláme, že sme nič nevložili
 Obsluzena=False
 if StlacenaKlavesa.KeyChar=" " then ' Stlačili sme medzeru
  Obsluzena=VlozZnak ' test posledného slova a vloženie príslušnej medzery
 endif
 Klavesnica_KeyPressed=Obsluzena ' Ak je návratová hodnota FALSE, OO.o zavolá štandardný program pre obsluhu stlačenej klávesy, inak ho nevolá
end function

REM Funkcia, ktorá sa volá pri pustení ľubovoľnej klávesy
function Klavesnica_KeyReleased(StlacenaKlavesa) as boolean
 ' Obsluha pustenej klávesy
 Klavesnica_KeyReleased = False ' Návratová hodnota je FALSE, OO.o zavolá štandardný program pre obsluhu pustenej klávesy
end function

 

Neprehliadnite: