~ubuntu-branches/ubuntu/saucy/amsn/saucy

« back to all changes in this revision

Viewing changes to plugins/SpellCheck/SpellCheck.tcl

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2010-04-13 23:21:29 UTC
  • mfrom: (1.1.11 upstream) (3.1.8 sid)
  • Revision ID: james.westby@ubuntu.com-20100413232129-vgpx20brdd2qavs7
Tags: 0.98.3-0ubuntu1
* Merge from Debian unstable (LP: #449072), remaining Ubuntu changes:
  - add 08_use_aplay_for_sound.dpatch patch by Festor Wailon Dacoba to use
    aplay to play sounds
  + debian/control:
    - modify iceweasel to firefox | abrowser in amsn Suggests field
    - add xdg-utils and gstreamer0.10-nice to amsn Depends field
    - mofify sox to alsa-utils in amsn Suggests field as we are now using
      aplay
* New upstream release (LP: #562619), tarball repacked according to
  debian/README.source.
* Fix missing-debian-source-format lintian warning.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
##############################################
 
2
#   ::SpellCheck => Spell Checker for aMSN   #
 
3
#   ======================================   #
 
4
# SpellCheck requires aspell to be installed # 
 
5
# ------------------------------------------ #
 
6
#             By William Bowling             #
 
7
#            yadgor02@hotmail.com            #
 
8
##############################################
 
9
 
 
10
 
 
11
############################################
 
12
#I am not a Tcl programmer, so lots of this#
 
13
#code has been copied and modified slightly#
 
14
# for this plugin. Many methods have been  # 
 
15
#taken from the Nudge plugin.              #
 
16
# ---------------------------------------- #
 
17
#  The spell checker is based on a small   #   
 
18
#      script by Richard Suchenwirth       #
 
19
#          http://wiki.tcl.tk/88           #
 
20
############################################
 
21
namespace eval ::SpellCheck {
 
22
        variable config
 
23
        variable configlist
 
24
        
 
25
 
 
26
        ######################################
 
27
        #    ::SpellCheck::InitPlug (dir)    #
 
28
        #------------------------------------#
 
29
        #Register events and initialize      #
 
30
        ######################################
 
31
        proc InitPlugin { dir } {
 
32
                ::plugins::RegisterPlugin SpellCheck
 
33
                ::plugins::RegisterEvent SpellCheck chatwindowbutton checkspellbutton
 
34
                ::plugins::RegisterEvent SpellCheck chat_msg_send AutoCheck
 
35
                ::plugins::RegisterEvent SpellCheck Load pluginDidLoad
 
36
                
 
37
                ::SpellCheck::LoadLangFiles $dir
 
38
                
 
39
                
 
40
                
 
41
                #set default values
 
42
                array set ::SpellCheck::config {
 
43
                        location {Path to aspell}
 
44
                        foreground {}
 
45
                        background {red}
 
46
                        autocheck {0}
 
47
                        astyping {0}
 
48
                        language {en}
 
49
                        delay {2}
 
50
                        fontstyle {}
 
51
                        
 
52
                }
 
53
                
 
54
                set ::SpellCheck::configlist [list \
 
55
                        [list str "[trans aspell_location]" location] \
 
56
                        [list bool "[trans auto_check]" autocheck]  \
 
57
                        [list bool "[trans check_as_typing]" astyping]  \
 
58
                        [list frame ::SpellCheck::languageFrame ""] \
 
59
                        [list frame ::SpellCheck::tagFrame ""] \
 
60
                        [list ext "[trans removecols]" {resetCols}] \
 
61
                ]
 
62
                ::SpellCheck::LoadPixmaps $dir
 
63
                set ::SpellCheck::sendMsg 0
 
64
                
 
65
                
 
66
        }
 
67
 
 
68
 
 
69
        ######################################
 
70
        # ::SpellCheck::LoadLangFiles (dir)  #
 
71
        #------------------------------------#
 
72
        #       Load the language files      #
 
73
        ######################################
 
74
        proc LoadLangFiles { dir } {
 
75
                set langdir [file join $dir "lang"]
 
76
                set lang [::config::getGlobalKey language]
 
77
                load_lang en $langdir
 
78
                load_lang $lang $langdir
 
79
        }
 
80
        
 
81
        
 
82
        ###########################################
 
83
        # ::SpellCheck::pluginDidLoad event evpar #
 
84
        #-----------------------------------------#
 
85
        # If SpellCheck gets loaded, check for    #
 
86
        # aspell                                  #
 
87
        ###########################################
 
88
        proc pluginDidLoad {event evpar} {
 
89
                upvar 2 $evpar newvar
 
90
                if {$newvar(name)=="SpellCheck"} {
 
91
                        ::SpellCheck::checkForAspell
 
92
                }
 
93
        
 
94
        }
 
95
        
 
96
        
 
97
        ######################################
 
98
        #    ::SpellCheck::checkForAspell    #
 
99
        #------------------------------------#
 
100
        #     Check some paths for aspell    #
 
101
        ######################################
 
102
        proc checkForAspell { } {
 
103
                if {![catch {exec $::SpellCheck::config(location)}]} {
 
104
                        return
 
105
                } elseif {![catch {exec aspell -v}]} {
 
106
                        set ::SpellCheck::config(location) "aspell"
 
107
                } elseif {![catch {exec "c:/program files/aspell/bin/aspell.exe" -v}] && [OnWin]} {
 
108
                        set ::SpellCheck::config(location) "c:/program files/aspell/bin/aspell.exe"
 
109
                } elseif {![catch {exec /opt/local/bin/aspell -v}]} {
 
110
                        set ::SpellCheck::config(location) "/opt/local/bin/aspell"
 
111
                } elseif {![catch {exec /usr/bin/aspell -v}]} {
 
112
                        set ::SpellCheck::config(location) "/usr/bin/aspell"
 
113
                } elseif {![catch {exec /usr/local/bin/aspell -v}]} {
 
114
                        set ::SpellCheck::config(location) "/usr/local/bin/aspell"
 
115
                } elseif {![catch {exec /sw/bin/aspell -v}]} {
 
116
                        set ::SpellCheck::config(location) "/sw/bin/aspell"
 
117
                } else {
 
118
                        ::SpellCheck::aspellNotFound
 
119
                }
 
120
        }
 
121
        
 
122
        
 
123
        ######################################
 
124
        #   ::SpellCheck::languageFrame win  #
 
125
        #------------------------------------#
 
126
        #Drop down menu for choosing language#
 
127
        ######################################  
 
128
        proc languageFrame { win } {
 
129
                frame $win.lang
 
130
                label $win.lang.label -text "[trans lang_select]"
 
131
                combobox::combobox $win.lang.accounts -editable false -highlightthickness 0 -bg #FFFFFF -font splainf -textvariable ::SpellCheck::config(language)
 
132
                if {![catch {set dicts [exec $::SpellCheck::config(location) dicts]}]} {
 
133
                        foreach aLang [split $dicts \n] {
 
134
                                $win.lang.accounts list insert end $aLang
 
135
                        }
 
136
                } else {
 
137
                        $win.lang.accounts list insert end "[trans not_found]"
 
138
                }
 
139
                
 
140
                pack $win.lang.label -side left -anchor w
 
141
                pack $win.lang.accounts -side left -anchor w
 
142
                pack $win.lang -anchor w -padx 20
 
143
        }
 
144
        
 
145
                
 
146
        ######################################
 
147
        #     ::SpellCheck::tagFrame win     #
 
148
        #------------------------------------#
 
149
        #set up the frame for configuring the# 
 
150
        #incorrect spelling tag              #
 
151
        ######################################          
 
152
        proc tagFrame { win } {
 
153
                frame $win.tag
 
154
 
 
155
                label $win.tag.label -text "[trans showincorrect]"
 
156
                
 
157
                combobox::combobox $win.tag.options -editable false -highlightthickness 0 -bg #FFFFFF -font splainf -command ::SpellCheck::setTagOption
 
158
                
 
159
                #set up options
 
160
                $win.tag.options list insert end "[trans background]"
 
161
                $win.tag.options list insert end "[trans foreground]"
 
162
                $win.tag.options list insert end "[trans fontstyle]"
 
163
                
 
164
                #show what the incorect tag will look like
 
165
                label $win.tag.value -text "[trans example]" -highlightthickness 0  -font [regsub -all {\s} "[lindex [::config::getKey mychatfont] 0]" "\\ "] 
 
166
                
 
167
                #if no background colour has been set, use skin defined one
 
168
                if {$::SpellCheck::config(background) != {} } {
 
169
                        $win.tag.value configure -background $::SpellCheck::config(background)
 
170
                } else {
 
171
                        $win.tag.value configure -background [::skin::getKey chat_input_back_color]
 
172
                }
 
173
                
 
174
                #if no foreground colour has been set, use the users font colour
 
175
                if {$::SpellCheck::config(foreground) != {} } {
 
176
                        $win.tag.value configure -foreground $::SpellCheck::config(foreground)
 
177
                } else {
 
178
                        $win.tag.value configure -foreground "#[lindex [::config::getKey mychatfont] 2]"
 
179
                }
 
180
                if { $::SpellCheck::config(fontstyle) != {} } {
 
181
                        $win.tag.value configure -font $::SpellCheck::config(fontstyle)
 
182
                }
 
183
                
 
184
                combobox::combobox $win.tag.font -editable false -highlightthickness 0 -bg #FFFFFF -font splainf -command ::SpellCheck::updateFontStyle
 
185
                $win.tag.font configure -value ""
 
186
                
 
187
                pack $win.tag.label -side left -anchor w
 
188
                pack $win.tag.options -side left -anchor w
 
189
                pack $win.tag.font -side left -anchor w
 
190
                pack $win.tag.value -side left -anchor w
 
191
        
 
192
                pack $win.tag -anchor w -padx 20
 
193
        
 
194
                
 
195
        }
 
196
        
 
197
        proc updateFontStyle { widget value } {
 
198
                set w [string replace $widget end-4 end ""]
 
199
                
 
200
                if { $value != {} } {
 
201
                        set ::SpellCheck::config(fontstyle) $value
 
202
                        $w.value configure -font $::SpellCheck::config(fontstyle)
 
203
                }
 
204
                update idletasks
 
205
        }
 
206
        
 
207
        ###########################################
 
208
        # ::SpellCheck::setTagOption widget value #
 
209
        #-----------------------------------------#
 
210
        # if the user selects background or       #
 
211
        # foreground, show the colour picker. Show#
 
212
        # a list of they select fontstyle         #
 
213
        ###########################################     
 
214
        proc setTagOption { widget value } {
 
215
                set w [string replace $widget end-7 end ""]
 
216
                
 
217
                switch -- $value {
 
218
                        background {
 
219
                                
 
220
                                #hide other list if it is shown
 
221
                                $w.font list delete 0 end
 
222
                                $w.font configure -value ""
 
223
                                #if a colour is already set, use it as the initial colour
 
224
                                if {$::SpellCheck::config(background) != {} } {
 
225
                                        set theCol [tk_chooseColor -initialcolor $::SpellCheck::config(background)]
 
226
                                } else {
 
227
                                        set theCol [tk_chooseColor]
 
228
                                }
 
229
                                
 
230
                                #if a new colour is chosen, set the config.
 
231
                                if { $theCol != "" } {
 
232
                                        set ::SpellCheck::config(background) $theCol
 
233
                                        $w.value configure -bg $::SpellCheck::config(background)
 
234
                                }
 
235
                        }
 
236
                        foreground {
 
237
                                #same as above
 
238
                                $w.font list delete 0 end
 
239
                                $w.font configure -value ""
 
240
                                if {$::SpellCheck::config(foreground) != {} } {
 
241
                                        set theCol [tk_chooseColor -initialcolor $::SpellCheck::config(foreground)]
 
242
                                } else {
 
243
                                        set theCol [tk_chooseColor]
 
244
                                }
 
245
                                if { $theCol != "" } {
 
246
                                        set ::SpellCheck::config(foreground) $theCol
 
247
                                        $w.value configure -fg $::SpellCheck::config(foreground)
 
248
                                }
 
249
                                #pack $w.value -side left -anchor w
 
250
                        }
 
251
                        fontstyle {
 
252
                                if { [$w.font list get 0] == {} } {
 
253
                                        foreach aFont [split [font names] " "] {
 
254
                                                $w.font list insert end $aFont
 
255
                                        }
 
256
                                }
 
257
                                if { $::SpellCheck::config(fontstyle) != {} } {
 
258
                                        $w.font configure -value $::SpellCheck::config(fontstyle)
 
259
                                }
 
260
                                pack $w.font
 
261
                        }
 
262
                        
 
263
                }
 
264
                update idletasks
 
265
        }
 
266
        
 
267
        
 
268
        ######################################
 
269
        #      ::SpellCheck::resetCols       #
 
270
        #------------------------------------#
 
271
        # Removes all the set colours so that#
 
272
        # the incorrect tags will use the    #
 
273
        # skin background and users font.    #
 
274
        ######################################
 
275
        proc resetCols { } {
 
276
                set ::SpellCheck::config(background) {}
 
277
                set ::SpellCheck::config(foreground) {}
 
278
                set ::SpellCheck::config(fontstyle) {}
 
279
                
 
280
                #not sure how to get this value yet...
 
281
                set widget ".plugin_selector.winconf_SpellCheck.area.5.tag.value"
 
282
                
 
283
                $widget configure -background [::skin::getKey chat_input_back_color]
 
284
                $widget configure -foreground "#[lindex [::config::getKey mychatfont] 2]"
 
285
                $widget configure -font [regsub -all {\s} "[lindex [::config::getKey mychatfont] 0]" "\\ "]
 
286
                tk_messageBox -message "[trans tagwarning]" -type ok -icon warning
 
287
        }
 
288
 
 
289
 
 
290
        ###########################################
 
291
        # ::SpellCheck::languageFrame event evpar #
 
292
        #-----------------------------------------#
 
293
        #Stop the message being sent if there are #
 
294
        #errors in the text. If you send it again #
 
295
        #before the delay is up, it will send with#
 
296
        #the errors                               #
 
297
        ###########################################
 
298
        proc AutoCheck {event evpar} {
 
299
                upvar 2 msg msg
 
300
                upvar 2 win_name win_name
 
301
        if { $::SpellCheck::config(autocheck) } {
 
302
                if {$::SpellCheck::sendMsg==1} {
 
303
                        set ::SpellCheck::sendMsg 0
 
304
                        [::ChatWindow::GetInputText $win_name] delete 0.0 end
 
305
                        return $msg
 
306
                } else {
 
307
                                set theInput [::ChatWindow::GetInputText $win_name]
 
308
                                catch {menu $win_name.aMenu}
 
309
                        ::SpellCheck::parseText $theInput $win_name.aMenu $win_name $msg
 
310
                        if {$::SpellCheck::numOfErrors==0} {
 
311
                                [::ChatWindow::GetInputText $win_name] delete 0.0 end
 
312
                                return $msg
 
313
                        } else {
 
314
                                set ::SpellCheck::sendMsg 1
 
315
                                set theTime [expr {int($::SpellCheck::config(delay)*1000)}]
 
316
                                after $theTime set ::SpellCheck::sendMsg 0
 
317
                                set msg ""
 
318
                                return $msg
 
319
                        }
 
320
                }
 
321
        }
 
322
        }
 
323
        
 
324
        
 
325
        
 
326
        ######################################
 
327
        #  ::SpellCheck::LoadPixmaps (dir)   #
 
328
        #------------------------------------#
 
329
        #Load the button images                          #
 
330
        ######################################
 
331
        proc LoadPixmaps {dir} {
 
332
                ::skin::setPixmap spellCheck checkSpelling.png pixmaps [file join $dir pixmaps]
 
333
                ::skin::setPixmap spellCheck_Hover checkSpelling_hover.png pixmaps [file join $dir pixmaps]
 
334
        }
 
335
 
 
336
 
 
337
 
 
338
        ########################################
 
339
        # ::SpellCheck::changeLang x y winName #
 
340
        #--------------------------------------#
 
341
        #Allow the user to select a custom     #
 
342
        #language for certain users. If none   #
 
343
        #has been set for the user, the config #
 
344
        #one is used                           #
 
345
        ########################################
 
346
        proc changeLang { x y winName} {
 
347
                set theUser [::ChatWindow::Name $winName]               
 
348
                catch {menu .changLangPopup}
 
349
                .changLangPopup delete 0 end
 
350
                
 
351
                if {![catch {set dicts [exec $::SpellCheck::config(location) dicts]}]} {
 
352
                        foreach aLang [split $dicts \n] {
 
353
                                .changLangPopup add command -label $aLang -command "set ::SpellCheck::config($theUser) $aLang"
 
354
                        }
 
355
                } else {
 
356
                        .changLangPopup add command -label [trans not_found]
 
357
                }
 
358
                tk_popup .changLangPopup $x $y
 
359
        }
 
360
 
 
361
 
 
362
 
 
363
        ##############################################
 
364
        # ::SpellCheck::checkspellbutton event evpar #
 
365
        #--------------------------------------------#
 
366
        #Taken straight from the Nudge plugin.       #
 
367
        #Adds a button to the ChatWindow                 #
 
368
        ##############################################
 
369
        proc checkspellbutton { event evpar } {
 
370
                upvar 2 $evpar newvar
 
371
                set winName $newvar(window_name)
 
372
                set spellCheckButton $newvar(bottom).checkSpelling
 
373
                set theInput [::ChatWindow::GetInputText $newvar(window_name)]
 
374
                menu $newvar(window_name).aMenu
 
375
                
 
376
 
 
377
                label $spellCheckButton -image [::skin::loadPixmap spellCheck] -relief flat -padx 0 \
 
378
                -background [::skin::getKey buttonbarbg] -highlightthickness 0 -borderwidth 0 \
 
379
                -highlightbackground [::skin::getKey buttonbarbg] -activebackground [::skin::getKey buttonbarbg] \
 
380
                
 
381
                bind $spellCheckButton <<Button1>> "::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
382
                bind $spellCheckButton <<Button3>> "::SpellCheck::changeLang %X %Y $winName"
 
383
                bind $spellCheckButton <Enter> "$spellCheckButton configure -image [::skin::loadPixmap spellCheck_Hover]"
 
384
                bind $spellCheckButton <Leave> "$spellCheckButton configure -image [::skin::loadPixmap spellCheck]"
 
385
 
 
386
                set_balloon $spellCheckButton "[trans ballon_text]"
 
387
 
 
388
                pack $spellCheckButton -side right
 
389
                
 
390
                #add the binds to check as the user is typing
 
391
                #after 0 so that the pressed key will be entered before the check happens
 
392
                if {$::SpellCheck::config(astyping)} {
 
393
                        bind $theInput <Key-space> "after 0 ::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
394
                        bind $theInput <.> "after 0 ::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
395
                        bind $theInput <?> "after 0 ::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
396
                        bind $theInput <!> "after 0 ::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
397
                        bind $theInput <(> "after 0 ::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
398
                        bind $theInput <)> "after 0 ::SpellCheck::parseText $theInput $newvar(window_name).aMenu $newvar(window_name) zzButtonWasPressed"
 
399
                }
 
400
        }
 
401
 
 
402
 
 
403
 
 
404
        ###################################################
 
405
        # ::SpellCheck::parseText textField aMenu win msg #
 
406
        #-------------------------------------------------#
 
407
        #       Based on Suchenwirth's spell checker.     #
 
408
        #-------------------------------------------------#
 
409
        #  Takes the text from the input, splits it into  #
 
410
        #  lines and then runs is through aspell. Then    #
 
411
        #  spiltsthe input into words and highlights any  #
 
412
        #  that aspell finds to be incorrect              #           
 
413
        ###################################################
 
414
        proc parseText { textField aMenu win msg } {
 
415
                #if autochecking, put the text back in the textfield
 
416
                if {$msg!="zzButtonWasPressed"} {
 
417
                        $textField insert 0.0 $msg
 
418
                }
 
419
                set ::SpellCheck::numOfErrors 0
 
420
                set lineno 1
 
421
                
 
422
                #remove any existing tags
 
423
                foreach aTag [$textField tag name] {$textField tag delete $aTag}
 
424
                
 
425
                #make sure invalid tag is not invisible
 
426
                if { $::SpellCheck::config(foreground)=={} && \
 
427
                         $::SpellCheck::config(background)=={} && \
 
428
                         $::SpellCheck::config(fontstyle)=={} } {
 
429
                         
 
430
                                tk_messageBox -message "[trans tagwarning]" -type ok -icon warning
 
431
                }
 
432
                
 
433
                
 
434
                #set up the highlight tag
 
435
                if { $::SpellCheck::config(background) != {} } {
 
436
                        $textField tag configure spelling -background $::SpellCheck::config(background)
 
437
                } else {
 
438
                        $textField tag configure spelling -background [::skin::getKey chat_input_back_color]
 
439
                }
 
440
                
 
441
                if { $::SpellCheck::config(foreground) != {} } {
 
442
                        $textField tag configure spelling -foreground $::SpellCheck::config(foreground)
 
443
                } else {
 
444
                        $textField tag configure spelling -foreground "#[lindex [::config::getKey mychatfont] 2]"
 
445
                }
 
446
                if { $::SpellCheck::config(fontstyle) != {} } {
 
447
                        $textField tag configure spelling -font $::SpellCheck::config(fontstyle)
 
448
                } else {
 
449
                        $textField tag configure spelling -font {}
 
450
                }
 
451
                
 
452
 
 
453
                foreach line [split [$textField get 1.0 end-1c] \n] {
 
454
                        set theCheck [runAspell $line $win]
 
455
                        
 
456
                        #start the counter at 1 to ignore first aspell output
 
457
                        set counter 1
 
458
                        
 
459
                        foreach {from to} [getWordIndexes $line] {
 
460
                                set word [string range $line $from [expr $to-1]]
 
461
                                        
 
462
                                        if { [lindex $theCheck $counter]=="#" || [lindex $theCheck $counter]=="?" || [lindex $theCheck $counter]=="&"} {
 
463
                                                incr ::SpellCheck::numOfErrors
 
464
                                                
 
465
                                                #when you click on a word, set up and show the suggestions
 
466
                                                $textField tag bind $word <<Button1>> "::SpellCheck::setUpMenu $textField $word $aMenu %X %Y $win"
 
467
                                                #add highlight tag
 
468
                                                $textField tag add spelling $lineno.$from $lineno.$to
 
469
                                                
 
470
                                                #add menu tag
 
471
                                                $textField tag add $word $lineno.$from $lineno.$to
 
472
                                                update idletasks
 
473
                                                
 
474
                                        }
 
475
                                        incr counter
 
476
                                }
 
477
                        incr lineno
 
478
                }
 
479
        }
 
480
 
 
481
 
 
482
 
 
483
        #####################################################
 
484
        # ::SpellCheck::addWord textField theWord win aMenu #
 
485
        #---------------------------------------------------#
 
486
        # adds the clicked word to the personal dictionary  #
 
487
        # for aspell. Language specific, so words will be   #
 
488
        # added to a custom en dictionary for english, fr   #
 
489
        # for french etc                                    #
 
490
        #####################################################
 
491
        proc addWord { textField theWord win aMenu} {
 
492
                
 
493
 
 
494
                
 
495
                set theUser [::ChatWindow::Name $win]
 
496
                if {[catch {list $::SpellCheck::config($theUser)}]} {
 
497
                        set theLang $::SpellCheck::config(language)
 
498
                } else {
 
499
                        set theLang $::SpellCheck::config($theUser)
 
500
                }
 
501
                
 
502
                if { [OnWin] } {
 
503
                        set loc $::SpellCheck::config(location)
 
504
                        set loc [regsub -all {\s} $loc "\\\\ "]
 
505
                        if {[catch {set pipe [open "| $loc  -a" WRONLY]}]} {
 
506
                                ::SpellCheck::aspellNotFound
 
507
                                return
 
508
                        }       
 
509
                        fconfigure $pipe -buffering line -blocking 0
 
510
                        puts $pipe *$theWord
 
511
                        puts $pipe #
 
512
                        close $pipe
 
513
                } else {
 
514
                        set theWord "*$theWord\n#"
 
515
                        if {[catch {exec echo $theWord | $::SpellCheck::config(location) -a --lang=$theLang}]} {
 
516
                                ::SpellCheck::aspellNotFound
 
517
                                return
 
518
                        }
 
519
                }
 
520
                $textField tag remove $theWord 1.0 end
 
521
                after 200 ::SpellCheck::parseText $textField $aMenu $win zzButtonWasPressed
 
522
        }
 
523
 
 
524
 
 
525
 
 
526
        ####################################
 
527
        #    ::SpellCheck::aspellNotFound  #
 
528
        #----------------------------------#
 
529
        #   Alert if aspell is not found   #
 
530
        #################################### 
 
531
        proc aspellNotFound { } {
 
532
                set answer [tk_messageBox -type yesno -default yes -icon question -message [trans aspell_not_found]]
 
533
                switch -- $answer { 
 
534
                        yes { 
 
535
                                ::plugins::PluginGui
 
536
                                
 
537
                                #catch for amsn v0.95
 
538
                                if {![catch {set ::plugins::selection SpellCheck}]} {
 
539
                                        ::plugins::GUI_Config
 
540
                                }
 
541
                        }
 
542
                }
 
543
        }
 
544
        
 
545
        
 
546
        
 
547
        ############################################
 
548
        #   ::SpellCheck::runAspell theWords win   #
 
549
        #------------------------------------------#
 
550
        #Send the line of text to aspell and return#
 
551
        #     a single character for each word     #
 
552
        #------------------------------------------#
 
553
        #       *    means word correct            #
 
554
        #    ? or #  means word incorrect          #
 
555
        ############################################
 
556
        proc runAspell { theWords win } {
 
557
                
 
558
                set formattedResults {}
 
559
 
 
560
                set theUser [::ChatWindow::Name $win]
 
561
                                #does the user have a custom language set?
 
562
                if {[catch {list $::SpellCheck::config($theUser)}]} {
 
563
                        set theLang $::SpellCheck::config(language)
 
564
                } else {
 
565
                        set theLang $::SpellCheck::config($theUser)
 
566
                }
 
567
                
 
568
                #aspell removes all numbers from the input
 
569
                #replace with "a" so they always return correct
 
570
                set theWords [regsub -all {[0-9_]+} $theWords " "]
 
571
                
 
572
                set theWords [regsub -all {[(\<\>\@\|\*\#\&)]} $theWords "\\\\&"]
 
573
                
 
574
                #get aspell results
 
575
                if { [OnWin]} {
 
576
                        if {[catch {set aspellResult [exec cmd /c echo $theWords | $::SpellCheck::config(location) -a --lang=$theLang]}]} {
 
577
                                ::SpellCheck::aspellNotFound
 
578
                                return
 
579
                        }
 
580
                } else {
 
581
                        if {[catch {set aspellResult [exec echo $theWords | $::SpellCheck::config(location) -a --lang=$theLang]}]} {
 
582
                                ::SpellCheck::aspellNotFound
 
583
                                return
 
584
                        }
 
585
                }
 
586
                #fix a bug that displays 2 results on the same line occasionally
 
587
                set aspellResult [regsub -all {(\w)([\*\?\#])(\n)} $aspellResult {\1\3\2\3}]
 
588
                foreach line [split $aspellResult \n] {
 
589
                        lappend formattedResults [string range $line 0 0]
 
590
                }
 
591
                
 
592
                return $formattedResults
 
593
        }
 
594
 
 
595
 
 
596
 
 
597
        ##########################################
 
598
        #     ::SpellCheck::getWordIndexes s     #
 
599
        #----------------------------------------#
 
600
        #  Based on Suchenwirth's spell checker  #
 
601
        #----------------------------------------#
 
602
        # Returns the start and end index of the #
 
603
        #  words, doesn't count non-alphanumeric #
 
604
        # characters to be consistent with aspell#
 
605
        ##########################################
 
606
        proc getWordIndexes s {
 
607
                set i 0
 
608
                set res {}
 
609
                set s [string tolower $s]
 
610
                
 
611
                #replace all ' so the right words get highlighted
 
612
                set s [regsub -all {'} $s "a"]
 
613
                set s [regsub -all {[0-9_]} $s " "]
 
614
                foreach c [split $s ""] {
 
615
                        if {$c ne " " && $i eq [string wordstart $s $i] } {
 
616
                        
 
617
                                #tcl counts punctuation as words and aspell doesnt,
 
618
                                #so only count alphanumeric characters as words
 
619
                                if {![regexp {[^a-z\s]} $c]} {
 
620
                                        lappend res $i [string wordend $s $i]
 
621
                                        
 
622
                                }
 
623
                        }
 
624
                        incr i
 
625
                }
 
626
                set res
 
627
        }
 
628
 
 
629
 
 
630
 
 
631
        #################################################
 
632
        # ::SpellCheck::setUpMenu w aWord aMenu x y win #
 
633
        #-----------------------------------------------#
 
634
        #Called when a user clicks on a highlighted     word#
 
635
        #It gets a list of suggestions from   aspell,   #
 
636
        #create a popup menu with the items. When the   #
 
637
        #user selects a word, delete the incorrect word #
 
638
        #and replace it with the new one.               #                       
 
639
        #################################################
 
640
        proc setUpMenu {input aWord aMenu x y win} {
 
641
                
 
642
                #delete old popup menu items
 
643
                $aMenu delete 0 end
 
644
                
 
645
                set tempListOfWords {}
 
646
                set theList {}
 
647
                set theUser [::ChatWindow::Name $win]
 
648
                
 
649
                #use the user's language if set
 
650
                if {[catch {list $::SpellCheck::config($theUser)}]} {
 
651
                        set theLang $::SpellCheck::config(language)
 
652
                } else {
 
653
                        set theLang $::SpellCheck::config($theUser)
 
654
                }
 
655
                
 
656
                if { [OnWin] } {
 
657
                        if {[catch {set suggestions [exec cmd /c echo $aWord | $::SpellCheck::config(location) --lang=$theLang -a]}]} {
 
658
                                ::SpellCheck::aspellNotFound
 
659
                                return
 
660
                        }
 
661
                } else {
 
662
                        if {[catch {set suggestions [exec echo $aWord | $::SpellCheck::config(location) --lang=$theLang -a]}]} {
 
663
                                ::SpellCheck::aspellNotFound
 
664
                                return
 
665
                        }
 
666
                }
 
667
                foreach line [split $suggestions \n] {
 
668
                        lappend tempListOfWords $line
 
669
                }
 
670
                
 
671
                #discard first information line
 
672
                foreach word [split [lindex $tempListOfWords 1] ", "] {
 
673
                        if {$word != "" } {
 
674
                                lappend theList $word
 
675
                        }
 
676
                }
 
677
                
 
678
                #remove the incorrect word and unneeded values
 
679
                set theList [lreplace $theList 0 3]
 
680
                
 
681
                foreach changeWord $theList {
 
682
                        $aMenu add command -label $changeWord -command "::SpellCheck::replaceWord $input $changeWord $aWord"
 
683
                }
 
684
                $aMenu add command -label "[trans addword]" -command "::SpellCheck::addWord $input $aWord $win $aMenu"
 
685
                tk_popup $aMenu $x $y
 
686
        }
 
687
 
 
688
 
 
689
 
 
690
        #########################################################
 
691
        # ::SpellCheck::replaceWord w replaceWith wordToReplace #
 
692
        #-------------------------------------------------------#
 
693
        #When the user chooses a word from the menu, replace the#
 
694
        #incorrect word with the new one                        #
 
695
        #########################################################
 
696
        proc replaceWord { w replaceWith wordToReplace } {
 
697
                foreach {start end} [$w tag ranges $wordToReplace] {
 
698
                        $w delete $start $end
 
699
                        
 
700
                        #amsn was doing some weird random selecting so:
 
701
                        $w tag remove sel 0.0 end
 
702
                        
 
703
                        #reposition the insert marker
 
704
                        $w mark set insert $start
 
705
                        $w insert insert $replaceWith
 
706
                        
 
707
                        #decrease the number of incorrect words
 
708
                        incr ::SpellCheck::numOfErrors -1
 
709
                        
 
710
                        #only do one occurrence of the word because it wont replace the
 
711
                        #right spot if the chosen word is a different length
 
712
                        break
 
713
                }
 
714
        }
 
715
}
 
716