multisplit
[iramuteq] / elcategorizator.py
1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3 #Copyright (c) 2022 Pierre Ratinaud
4 #License: GNU/GPL
5
6 import os
7 import wx
8 import wx.xrc
9 from wx.lib.splitter import MultiSplitterWindow
10 from listlex import *
11 import pickle
12 import json
13
14
15
16 class CategoDict :
17     def __init__(self, pathout = None):
18         self.pathout = pathout
19         self.cate = self.readjson()
20         self.lenwords = len(self.cate['TOCATE']) + len([word for categorie in self.cate['CATE'] for word in self.cate['CATE'][categorie][1]])
21
22     def readjson(self):
23         if self.pathout is not None :
24             with open(self.pathout['cate.json'], 'r', encoding='utf8') as f :
25                 cate = json.load(f)
26         else :
27             cate = {'TOCATE' : {'word1': 3, 'word2' : 2, 'word3' : 5}, 'CATE': {'cat1' : [34,{'word6':30, 'word7':4}], 'cat2' : [20,{'word20':20}]}}
28         return cate
29
30     def save(self) :
31         with open(self.pathout['cate.json'], 'w', encoding='utf8') as f :
32             f.write(json.dumps(self.cate, indent=4))
33         print("json saved!")
34
35     def exportdict(self):
36         pass
37
38     def getcate(self) :
39         cate = []
40         i = 0
41         for val in self.cate['CATE'] :
42             cate.append([i, [val, self.cate['CATE'][val][0]]])
43             i += 1
44         return dict(cate)
45
46     def getwordstocate(self) :
47         words = []
48         i = 0
49         for val in self.cate['TOCATE'] :
50             words.append([i, [val, self.cate['TOCATE'][val]]])
51             i+= 1
52         return dict(words)
53
54     def getcatewords(self, cat) :
55         catewords = []
56         i = 0
57         if cat not in self.cate['CATE'] :
58             return {}
59         for val in self.cate['CATE'][cat][1] :
60             catewords.append([i, [val, self.cate['CATE'][cat][1][val]]])
61             i += 1
62         return dict(catewords)
63
64     def getwordscate(self) :
65         wc = {}
66         for word in self.cate['TOCATE'] :
67             wc[word] = word
68         for categorie in self.cate['CATE'] :
69             for word in self.cate['CATE'][categorie][1] :
70                 wc[word] = categorie
71         return wc
72
73     def addwordincate(self, categorie, word, eff) :
74         self.cate['CATE'][categorie][1][word] = eff
75         self.cate['CATE'][categorie][0] += eff
76         del(self.cate['TOCATE'][word])
77
78     def addwordinwords(self, categorie, word, eff) :
79         print(categorie, word, eff)
80         self.cate['TOCATE'][word] = eff
81         self.cate['CATE'][categorie][0] -= eff
82         del(self.cate['CATE'][categorie][1][word])
83         if self.cate['CATE'][categorie][0] == 0 :
84             del(self.cate['CATE'][categorie])
85
86     def findcatefromword(self, word) :
87         for categorie in self.cate['CATE'] :
88             if word in self.cate['CATE'][categorie][1] :
89                 return categorie
90         return None
91
92     def changewordcate(self, newcate, word, eff) :
93         oldcat = self.findcatefromword(word)
94         del(self.cate['CATE'][oldcat][1][word])
95         self.cate['CATE'][oldcat][0] -= eff
96         self.cate['CATE'][newcate][1][word] = eff
97         self.cate['CATE'][newcate][0] += eff
98         if self.cate['CATE'][oldcat][0] == 0 :
99             del(self.cate['CATE'][oldcat])
100
101     def addcatefromwordtocate(self, word, eff) :
102         if word in self.cate['CATE'] :
103             return False
104         else :
105             self.cate['CATE'][word]=[eff,{word:eff}]
106             del(self.cate['TOCATE'][word])
107             return True
108
109     def addcatefromscratch(self) :
110         i = 0
111         while "NewCategory_%i" %i in self.cate['CATE'] :
112             i += 1
113         newcate = "NewCategory_%i" %i
114         self.cate['CATE'][newcate] = [0, {}]
115
116     def addcatefromwordcate(self, word, eff) :
117         if word in self.cate['CATE'] :
118             return False
119         else :
120             oldcat = self.findcatefromword(word)
121             self.cate['CATE'][word]=[eff,{word:eff}]
122             del(self.cate['CATE'][oldcat][1][word])
123             self.cate['CATE'][oldcat][0] -= eff
124             if self.cate['CATE'][oldcat][0] == 0 :
125                 del(self.cate['CATE'][oldcat])
126             return True
127
128     def delcate(self, categorie) :
129         for word in self.cate['CATE'][categorie][1] :
130             self.cate['TOCATE'][word] = self.cate['CATE'][categorie][1][word]
131         del(self.cate['CATE'][categorie])
132
133     def loadcate(self, infile) :
134         if self.cate['CATE'] != {} :
135             print("Categories should be empty")
136             return False
137         with open(infile, 'r', encoding='utf8') as f :
138             newcate = json.load(f)
139         for categorie in newcate['CATE'] :
140             self.cate['CATE'][categorie] = [0,{}]
141             for word in newcate['CATE'][categorie][1] :
142                 if word in self.cate['TOCATE'] :
143                     self.cate['CATE'][categorie][1][word] = self.cate['TOCATE'][word]
144                     self.cate['CATE'][categorie][0] += self.cate['TOCATE'][word]
145                     del(self.cate['TOCATE'][word])
146
147     def makestat(self) :
148         totocat = sum([self.cate['TOCATE'][word] for word in self.cate['TOCATE']])
149         nbtocat = len(self.cate['TOCATE'])
150         nbcate = len(self.cate['CATE'])
151         totcate = sum([self.cate['CATE'][categorie][0] for categorie in self.cate['CATE']])
152         lenwordincate = len([word for categorie in self.cate['CATE'] for word in self.cate['CATE'][categorie][1]])
153         return nbtocat, totocat, nbcate, totcate, lenwordincate
154
155
156 #cate = CategoDict()
157
158
159 #class ElCategorizator ( wx.Panel ):
160 #
161 #    def __init__( self, parent, pathout, tableau, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ):
162 #        wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name )
163 #        self.pathout = pathout
164 #        self.parent = parent
165 #        self.tableau = tableau
166 #
167 #        self.cate = CategoDict(self.pathout)
168 #        gsizer =  wx.BoxSizer( wx.VERTICAL )
169 #
170 #        bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
171 #
172 #        self.m_listToCate = ListForWords(self, dlist = self.cate, first = ['eff'])
173 #        bSizer1.Add( self.m_listToCate, 2, wx.ALL|wx.EXPAND, 5 )
174 #
175 #        self.m_listCate = ListForCate(self, dlist = self.cate, first = ['eff'])
176 #        bSizer1.Add( self.m_listCate, 1, wx.ALL|wx.EXPAND, 5 )
177 #
178 #        self.m_listCateWords = ListForCateWords(self, dlist = self.cate, first = ['eff'])
179 #        bSizer1.Add( self.m_listCateWords, 1, wx.ALL|wx.EXPAND, 5 )
180 #
181 #        bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
182 #
183 #        self.butsave = wx.Button( self, wx.ID_SAVE, u"Save", wx.DefaultPosition, wx.DefaultSize, 0 )
184 #        bSizer2.Add( self.butsave, 0, wx.ALL, 5 )
185 #
186 #        self.butcsv = wx.Button( self, wx.ID_ANY, u"Export Columns", wx.DefaultPosition, wx.DefaultSize, 0 )
187 #        bSizer2.Add( self.butcsv, 0, wx.ALL, 5 )
188 #
189 #        self.butdict = wx.Button( self, wx.ID_ANY, u"Export dictonary", wx.DefaultPosition, wx.DefaultSize, 0 )
190 #        bSizer2.Add( self.butdict, 0, wx.ALL, 5 )
191 #
192 #        self.butload = wx.Button( self, wx.ID_ANY, u"Load a categorization", wx.DefaultPosition, wx.DefaultSize, 0 )
193 #        bSizer2.Add( self.butload, 0, wx.ALL, 5 )
194 #
195 #        self.butaddcate = wx.Button( self, wx.ID_ANY, u"Add a category", wx.DefaultPosition, wx.DefaultSize, 0 )
196 #        bSizer2.Add( self.butaddcate, 0, wx.ALL, 5 )
197 #
198 #
199 #        bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
200 #
201 #        self.nbword = """Words : {:d} ({:d}) | """
202 #
203 #        self.stat = """ Words to categorize : {:d} ({}%) - {:d} ({}%) -- Categories : {:d} - {:d} ({}%) - {:d} ({}%)"""
204 ##        nbtocat, totocat, nbcate, totcate = self.cate.makestat()
205 ##        lenwords = self.cate.lenwords
206 ##        totwords = totocat + totcate
207 ##        prtocat = repr(nbtocat/lenwords)
208 ##        prtotocat = repr(totocat/totwords)
209 ##        prcate = repr(totcate/totwords)
210 #        self.wordtxt = wx.StaticText(self, -1, "")
211 #        bSizer3.Add( self.wordtxt, 0, wx.ALL, 5 )
212 #        self.stattxt = wx.StaticText(self, -1, "")
213 #        bSizer3.Add( self.stattxt, 0, wx.ALL, 5 )
214 #
215 #
216 #        gsizer.Add( bSizer2, 0, wx.EXPAND, 5 )
217 #        gsizer.Add( bSizer1, 2, wx.EXPAND, 5 )
218 #        gsizer.Add( bSizer3, 0, wx.EXPAND, 5 )
219 #
220 #        self.butsave.Bind(wx.EVT_BUTTON, self.OnSave)
221 #        self.butcsv.Bind(wx.EVT_BUTTON, self.OnCSV)
222 #        self.butdict.Bind(wx.EVT_BUTTON, self.OnDict)
223 #        self.butsave.SetBackgroundColour((14, 242, 14, 255))
224 #        self.butload.Bind(wx.EVT_BUTTON, self.OnLoad)
225 #        self.butaddcate.Bind(wx.EVT_BUTTON, self.OnAddCate)
226 #        self.OnStat()
227 #        self.SetSizer( gsizer )
228 #        self.Layout()
229 #
230 #    def __del__( self ):
231 #        pass
232 #
233 #
234 #    def OnLoad(self, event) :
235 #        if len(self.cate.cate['CATE']) != 0 :
236 #            message = wx.MessageDialog(self, _("Categories must be empty to load a categorization."), _("Information"), wx.OK|wx.ICON_WARNING)
237 #            message.ShowModal()
238 #            message.Destroy()
239 #            return
240 #        wildcard = "json|*.json|" \
241 #                   "All file|*.*"
242 #        dlg = wx.FileDialog(
243 #             self, message="Choose a file",
244 #             defaultDir=self.pathout.dirout,
245 #             defaultFile="",
246 #             wildcard=wildcard,
247 #             style=wx.FD_OPEN |
248 #                   wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST |
249 #                   wx.FD_PREVIEW
250 #             )
251 #
252 #        if dlg.ShowModal() == wx.ID_OK:
253 #            paths = dlg.GetPaths()
254 #            path = paths[0]
255 #            self.cate.loadcate(path)
256 #            self.m_listCate.RefreshData(self.cate.getcate())
257 #            self.m_listToCate.RefreshData(self.cate.getwordstocate())
258 #        dlg.Destroy()
259 #
260 #    def OnSave(self, event) :
261 #        self.cate.save()
262 #        self.butsave.SetBackgroundColour((14, 242, 14, 255))
263 #
264 #    def OnCSV(self, event) :
265 #        wordscate = self.cate.getwordscate()
266 #        newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
267 #        for line in self.tableau.select_col(self.tableau.selected_col):
268 #            newline = []
269 #            for word in line :
270 #                newline.append(wordscate.get(word,word))
271 #            newtab.append(newline)
272 #        with open(self.pathout['tableout.csv'], 'w', encoding='utf8') as f :
273 #            f.write('\n'.join(['\t'.join(line) for line in newtab]))
274 #        message = wx.MessageDialog(self, _("Export successful\n%s" % self.pathout['tableout.csv']), _("Information"), wx.OK|wx.ICON_INFORMATION)
275 #        message.ShowModal()
276 #        message.Destroy()
277 #
278 #    def OnDict(self, event):
279 #        with open(self.pathout['dictionnary.txt'], 'w', encoding='utf8') as f :
280 #            for categorie in self.cate.cate['CATE'] :
281 #                f.write(categorie + ': \t' + repr(self.cate.cate['CATE'][categorie][0]) + '\n')
282 #                for word in self.cate.cate['CATE'][categorie][1] :
283 #                    f.write('\t' + word + ': \t' + repr(self.cate.cate['CATE'][categorie][1][word]) + '\n')
284 #            for word in self.cate.cate['TOCATE'] :
285 #                f.write(word + ':\t' + repr(self.cate.cate['TOCATE'][word]) + '\n')
286 #        message = wx.MessageDialog(self, _("Export successful\n%s" % self.pathout['dictionnary.txt']), _("Information"), wx.OK|wx.ICON_INFORMATION)
287 #        message.ShowModal()
288 #        message.Destroy()
289 #
290 #    def OnStat(self) :
291 #        nbtocat, totocat, nbcate, totcate, lenwordincate = self.cate.makestat()
292 #        totwords = totocat + totcate
293 #        prtocat = repr(round((nbtocat/self.cate.lenwords) * 100 ,2))
294 #        prtotocat = repr(round((totocat/totwords) * 100, 2))
295 #        prcate = repr(round((totcate/totwords)*100, 2))
296 #        prwordincate = repr(round((lenwordincate/self.cate.lenwords)*100, 2))
297 #        self.stattxt.SetLabel(self.stat.format(nbtocat, prtocat, totocat, prtotocat, nbcate, lenwordincate, prwordincate, totcate, prcate))
298 #
299 #    def OnAddToTable(self) :
300 #        wordscate = self.cate.getwordscate()
301 #        newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
302 #        for line in self.tableau.select_col(self.tableau.selected_col):
303 #            newline = []
304 #            for word in line :
305 #                newline.append(wordscate.get(word,word))
306 #            newtab.append(newline)
307 #
308 #    def OnAddCate(self, evt) :
309 #        print('add a category')
310 #        print(self.m_listCate.GetItemCount())
311 #        self.cate.addcatefromscratch()
312 #        self.m_listCate.dlist = self.cate.getcate()
313 #        self.m_listCate.RefreshData(self.m_listCate.dlist)
314 #        self.m_listCate.SetSelection(self.m_listCate.GetItemCount() - 1)
315
316
317
318 class ListPanel(wx.Panel) :
319      def __init__(self, parent, gparent, List):
320         wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN)
321         self.parent = parent
322         self.gparent = gparent
323         self.cate = gparent.cate
324         gsizer =  wx.BoxSizer( wx.HORIZONTAL )
325         self.list = List(self, dlist = gparent.cate, first = ['eff'])
326         gsizer.Add(self.list, 5, wx.EXPAND, 5 )
327         self.SetSizer( gsizer )
328         self.Layout()
329
330
331      def OnStat(self) :
332         self.gparent.OnStat()
333
334 class ElCategorizator ( wx.Panel ):
335
336     def __init__( self, parent, pathout, tableau, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.TAB_TRAVERSAL, name = wx.EmptyString ):
337         wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name )
338         self.pathout = pathout
339         self.parent = parent
340         self.tableau = tableau
341
342         self.cate = CategoDict(self.pathout)
343         gsizer =  wx.BoxSizer( wx.VERTICAL )
344
345         bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
346         splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
347         self.splitter = splitter
348         #sizer = wx.BoxSizer(wx.HORIZONTAL)
349         #sizer.Add(splitter, 1, wx.EXPAND)
350         #self.SetSizer(sizer)
351         W,H = wx.GetTopLevelParent(self).GetSize()
352         print(W)
353         W = W - 200
354         if W < 300 :
355             W = 300
356         splitsize = int(W/3)
357         print(W)
358         print(H)
359         print(splitsize)
360
361         panelwords = ListPanel(splitter, self, ListForWords)
362         splitter.AppendWindow(panelwords, splitsize)
363         panelcate = ListPanel(splitter, self, ListForCate)
364         splitter.AppendWindow(panelcate, splitsize)
365         panelwordscate = ListPanel(splitter, self, ListForCateWords)
366         splitter.AppendWindow(panelwordscate, splitsize)
367         self.m_listToCate = panelwords.list
368         self.m_listCate = panelcate.list
369         self.m_listCateWords = panelwordscate.list
370
371
372         bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
373
374         self.butsave = wx.Button( self, wx.ID_SAVE, u"Save", wx.DefaultPosition, wx.DefaultSize, 0 )
375         bSizer2.Add( self.butsave, 0, wx.ALL, 5 )
376
377         self.butcsv = wx.Button( self, wx.ID_ANY, u"Export Columns", wx.DefaultPosition, wx.DefaultSize, 0 )
378         bSizer2.Add( self.butcsv, 0, wx.ALL, 5 )
379
380         self.butdict = wx.Button( self, wx.ID_ANY, u"Export dictonary", wx.DefaultPosition, wx.DefaultSize, 0 )
381         bSizer2.Add( self.butdict, 0, wx.ALL, 5 )
382
383         self.butload = wx.Button( self, wx.ID_ANY, u"Load a categorization", wx.DefaultPosition, wx.DefaultSize, 0 )
384         bSizer2.Add( self.butload, 0, wx.ALL, 5 )
385
386         self.butaddcate = wx.Button( self, wx.ID_ANY, u"Add a category", wx.DefaultPosition, wx.DefaultSize, 0 )
387         bSizer2.Add( self.butaddcate, 0, wx.ALL, 5 )
388
389
390         bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
391
392         self.nbword = """Words : {:d} ({:d}) | """
393
394         self.stat = """ Words to categorize : {:d} ({}%) - {:d} ({}%) -- Categories : {:d} - {:d} ({}%) - {:d} ({}%)"""
395         for panel in [panelwords, panelcate, panelwordscate] :
396             panel.m_listToCate = self.m_listToCate
397             panel.m_listCate = self.m_listCate
398             panel.m_listCateWords = self.m_listCateWords
399             panel.butsave = self.butsave
400
401 #        nbtocat, totocat, nbcate, totcate = self.cate.makestat()
402 #        lenwords = self.cate.lenwords
403 #        totwords = totocat + totcate
404 #        prtocat = repr(nbtocat/lenwords)
405 #        prtotocat = repr(totocat/totwords)
406 #        prcate = repr(totcate/totwords)
407         self.wordtxt = wx.StaticText(self, -1, "")
408         bSizer3.Add( self.wordtxt, 0, wx.ALL, 5 )
409         self.stattxt = wx.StaticText(self, -1, "")
410         bSizer3.Add( self.stattxt, 0, wx.ALL, 5 )
411
412
413         gsizer.Add( bSizer2, 0, wx.EXPAND, 5 )
414         gsizer.Add( splitter, 2, wx.EXPAND, 5 )
415         gsizer.Add( bSizer3, 0, wx.EXPAND, 5 )
416
417         self.butsave.Bind(wx.EVT_BUTTON, self.OnSave)
418         self.butcsv.Bind(wx.EVT_BUTTON, self.OnCSV)
419         self.butdict.Bind(wx.EVT_BUTTON, self.OnDict)
420         self.butsave.SetBackgroundColour((14, 242, 14, 255))
421         self.butload.Bind(wx.EVT_BUTTON, self.OnLoad)
422         self.butaddcate.Bind(wx.EVT_BUTTON, self.OnAddCate)
423         self.OnStat()
424         self.SetSizer( gsizer )
425         self.Layout()
426
427
428
429     def __del__( self ):
430         pass
431
432     def OnLoad(self, event) :
433         if len(self.cate.cate['CATE']) != 0 :
434             message = wx.MessageDialog(self, _("Categories must be empty to load a categorization."), _("Information"), wx.OK|wx.ICON_WARNING)
435             message.ShowModal()
436             message.Destroy()
437             return
438         wildcard = "json|*.json|" \
439                    "All file|*.*"
440         dlg = wx.FileDialog(
441              self, message="Choose a file",
442              defaultDir=self.pathout.dirout,
443              defaultFile="",
444              wildcard=wildcard,
445              style=wx.FD_OPEN |
446                    wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST |
447                    wx.FD_PREVIEW
448              )
449
450         if dlg.ShowModal() == wx.ID_OK:
451             paths = dlg.GetPaths()
452             path = paths[0]
453             self.cate.loadcate(path)
454             self.m_listCate.RefreshData(self.cate.getcate())
455             self.m_listToCate.RefreshData(self.cate.getwordstocate())
456         dlg.Destroy()
457
458     def OnSave(self, event) :
459         self.cate.save()
460         self.butsave.SetBackgroundColour((14, 242, 14, 255))
461
462     def OnCSV(self, event) :
463         wordscate = self.cate.getwordscate()
464         newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
465         for line in self.tableau.select_col(self.tableau.selected_col):
466             newline = []
467             for word in line :
468                 newline.append(wordscate.get(word,word))
469             newtab.append(newline)
470         with open(self.pathout['tableout.csv'], 'w', encoding='utf8') as f :
471             f.write('\n'.join(['\t'.join(line) for line in newtab]))
472         message = wx.MessageDialog(self, _("Export successful\n%s" % self.pathout['tableout.csv']), _("Information"), wx.OK|wx.ICON_INFORMATION)
473         message.ShowModal()
474         message.Destroy()
475
476     def OnDict(self, event):
477         with open(self.pathout['dictionnary.txt'], 'w', encoding='utf8') as f :
478             for categorie in self.cate.cate['CATE'] :
479                 f.write(categorie + ': \t' + repr(self.cate.cate['CATE'][categorie][0]) + '\n')
480                 for word in self.cate.cate['CATE'][categorie][1] :
481                     f.write('\t' + word + ': \t' + repr(self.cate.cate['CATE'][categorie][1][word]) + '\n')
482             for word in self.cate.cate['TOCATE'] :
483                 f.write(word + ':\t' + repr(self.cate.cate['TOCATE'][word]) + '\n')
484         message = wx.MessageDialog(self, _("Export successful\n%s" % self.pathout['dictionnary.txt']), _("Information"), wx.OK|wx.ICON_INFORMATION)
485         message.ShowModal()
486         message.Destroy()
487
488     def OnStat(self) :
489         nbtocat, totocat, nbcate, totcate, lenwordincate = self.cate.makestat()
490         totwords = totocat + totcate
491         prtocat = repr(round((nbtocat/self.cate.lenwords) * 100 ,2))
492         prtotocat = repr(round((totocat/totwords) * 100, 2))
493         prcate = repr(round((totcate/totwords)*100, 2))
494         prwordincate = repr(round((lenwordincate/self.cate.lenwords)*100, 2))
495         self.stattxt.SetLabel(self.stat.format(nbtocat, prtocat, totocat, prtotocat, nbcate, lenwordincate, prwordincate, totcate, prcate))
496
497
498     def OnAddToTable(self) :
499         wordscate = self.cate.getwordscate()
500         newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
501         for line in self.tableau.select_col(self.tableau.selected_col):
502             newline = []
503             for word in line :
504                 newline.append(wordscate.get(word,word))
505             newtab.append(newline)
506
507     def OnAddCate(self, evt) :
508         print('add a category')
509         print(self.m_listCate.GetItemCount())
510         self.cate.addcatefromscratch()
511         self.m_listCate.dlist = self.cate.getcate()
512         self.m_listCate.RefreshData(self.m_listCate.dlist)
513         self.m_listCate.SetSelection(self.m_listCate.GetItemCount() - 1)
514
515
516 class ListForCate(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
517
518     def __init__(self, parent, dlist = {}, first = [], usefirst = False, menu = True):
519         wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES|wx.LC_EDIT_LABELS|wx.LC_SINGLE_SEL)
520         self.parent=parent
521         self.cate = self.parent.cate
522         self.dlist= self.cate.getcate()
523         self.first = first
524         self.il = wx.ImageList(20, 20)
525         a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION", "p_idx":"PLUS"}
526         for k,v in list(a.items()):
527             s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(20,20)))" % (k,v)
528             exec(s)
529         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
530         self.attr1 = wx.ListItemAttr()
531         self.attr1.SetBackgroundColour((230, 230, 230))
532         self.attr2 = wx.ListItemAttr()
533         self.attr2.SetBackgroundColour("light blue")
534         #self.attrselected = wx.ListItemAttr()
535         #self.attrselected.SetBackgroundColour("red")
536         self.SetListFont()
537         self.selected = {}
538         i = 0
539         for name in ['Categories'] + self.first :
540             self.InsertColumn(i,name,wx.LIST_FORMAT_LEFT)
541             i += 1
542         self.itemDataMap = self.dlist
543         self.itemIndexMap = list(self.dlist.keys())
544         self.SetItemCount(len(self.dlist))
545         listmix.ListCtrlAutoWidthMixin.__init__(self)
546         listmix.ColumnSorterMixin.__init__(self, len(self.first) + 1)
547
548         #self.SortListItems(1, False)
549         self.SetColumnWidth(0, 300)
550         self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
551
552         self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
553         self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.ShowWords)
554         self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnBeginEdit)
555         self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit)
556         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
557         self.Bind(wx.EVT_LIST_COL_CLICK, self.OnSortColumn)
558
559         if self.GetItemCount() != 0 :
560             #self.SetItemState(0, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
561             self.Select(0, on=1)
562
563         dt = MyListDropCate(self)
564         self.SetDropTarget(dt)
565
566     def OnSortColumn(self, evt) :
567         print(self.currentItem)
568         evt.Skip()
569
570     def SetListFont(self) :
571         self.SetFont(wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
572
573     def OnGetItemImage(self, item):
574         return self.p_idx
575
576     def OnBeginEdit(self, event) :
577         self.EditLabel(event.GetIndex())
578         event.Skip()
579
580     def OnEndEdit(self, event) :
581         newlabel = event.GetLabel()
582         idx = event.GetIndex()
583         oldlabel = self.GetItemText(idx)
584         if newlabel not in self.cate.cate['CATE'] :
585             self.cate.cate['CATE'][newlabel] = self.cate.cate['CATE'][oldlabel]
586             del(self.cate.cate['CATE'][oldlabel])
587         self.RefreshData(self.cate.getcate())
588
589     def ShowWords(self, event) :
590         index = event.GetIndex()
591         try :
592             data = self.cate.getcatewords(self.GetItemText(index))
593             self.parent.m_listCateWords.RefreshData(data)
594             self.parent.m_listCateWords.SetSelection(0)
595         except :
596             pass
597         event.Skip()
598
599     def RefreshData(self, data):
600         try :
601             item = self.currentItem
602         except :
603             item = 0
604         self.itemDataMap = data
605         self.itemIndexMap = list(data.keys())
606         self.SetItemCount(len(data))
607         order = self._colSortFlag[self._col]
608         self.SortListItems(self._col, order)
609         #self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
610         #self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
611         #self.SetColumnWidth(0,300)
612         self.parent.OnStat()
613         self.Refresh()
614         try :
615             self.SetSelection(item)
616             self.Focus(item)
617         except :
618             pass
619
620     def GetListCtrl(self):
621         return self
622
623     def GetSortImages(self):
624         return (self.sm_dn, self.sm_up)
625
626     def SortItems(self, sorter=None):
627         try :
628             select = self.currentItem
629             word = self.GetItemData(select)[0]
630         except Exception as e: print('word',e)
631
632         listTemp = sorted(self.itemDataMap.items(),
633             key=lambda x:x[1][self._col], reverse= (self._colSortFlag[self._col]!=True))
634         dlist = dict([[line[0],line[1]] for line in listTemp])
635         self.itemDataMap = dlist
636         self.itemIndexMap = list(dlist.keys())
637         self.Refresh() # redraw the list
638         try :
639             formes = [self.getColumnText(i, 0) for i in range(self.GetItemCount())]
640             idx = [i for i, val in enumerate(formes) if val == word][0]
641             self.SetSelection(idx)
642             self.Focus(idx)
643         except Exception as e: print(e)
644
645     def OnGetItemText(self, item, col):
646         index=self.itemIndexMap[item]
647         s = self.itemDataMap[index][col]
648         if isinstance(s, (int, float)):
649             return str(s)
650         else:
651             return s #modification pour python 3
652
653     def OnGetItemAttr(self, item):
654 #        if self.IsSelected(index) == True :
655 #            print('selected', index)
656         index=self.itemIndexMap[item]
657         if item % 2 :
658            return self.attr1
659         else :
660            return self.attr2
661
662     def getselectedwords(self) :
663         words = [self.getColumnText(self.GetFirstSelected(), 0)]
664         last = self.GetFirstSelected()
665         while self.GetNextSelected(last) != -1:
666             last = self.GetNextSelected(last)
667             words.append(self.getColumnText(last, 0))
668         return words
669
670     def GetString(self):
671         return self.getselectedwords()[0]
672
673     def GetSelections(self):
674         return self.getselectedwords()
675
676     def getColumnText(self, index, col):
677         item = self.GetItem(index, col)
678         return item.GetText()
679
680     def GetItemData(self, item) :
681         index=self.itemIndexMap[item]
682         s = self.itemDataMap[index]
683         return s
684
685     def OnItemSelected(self, event):
686         self.currentItem = event.GetIndex() #event.m_itemIndex
687         event.Skip()
688
689     def SetSelection(self, index) :
690         for i in range(0, self.GetItemCount(), 1) :
691             self.Select(i, on=0)
692         self.Select(index, on=1)
693
694     def GetItemInfo(self, idx):
695         """
696         Collect all relevant data of a listitem, and put it in a list.
697         """
698
699         l = []
700         l.append(idx) # We need the original index, so it is easier to eventualy delete it.
701         l.append(self.GetItemData(idx)) # Itemdata.
702         l.append(self.GetItemText(idx)) # Text first column.
703         for i in range(1, self.GetColumnCount()): # Possible extra columns.
704             l.append(self.GetItem(idx, i).GetText())
705         l.append('cate')
706         return l
707
708
709     def StartDrag(self, event):
710         """
711         Put together a data object for drag-and-drop _from_ this list.
712         """
713
714         l = []
715         idx = -1
716         while True: # Find all the selected items and put them in a list.
717             idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
718             if idx == -1:
719                 break
720             l.append(self.GetItemInfo(idx))
721
722         # Pickle the items list.
723         itemdata = pickle.dumps(l, 1)
724         # Create our own data format and use it
725         # in a Custom data object.
726         ldata = wx.CustomDataObject("ListCtrlItems")
727         ldata.SetData(itemdata)
728         # Now make a data object for the  item list.
729         data = wx.DataObjectComposite()
730         data.Add(ldata)
731
732         # Create drop source and begin drag-and-drop.
733         dropSource = wx.DropSource(self)
734         dropSource.SetData(data)
735         res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
736
737         # If move, we want to remove the item from this list.
738         if res == wx.DragMove and l[0][-1] != 'cate' :
739             # It's possible we are dragging/dropping from this list to this list.
740             # In which case, the index we are removing may have changed...
741
742             # Find correct position.
743             l.reverse() # Delete all the items, starting with the last item.
744             for i in l:
745                 pos = self.FindItem(i[0], i[2])
746                 self.DeleteItem(pos)
747
748
749     def Insert(self, x, y, seq):
750         """
751         Insert text at given x, y coordinates --- used with drag-and-drop.
752         """
753
754         # Find insertion point.
755         index, flags = self.HitTest((x, y))
756
757         if index == wx.NOT_FOUND: # Not clicked on an item.
758             if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
759                 index = self.GetItemCount() # Append to end of list.
760             elif self.GetItemCount() > 0:
761                 if y <= self.GetItemRect(0).y: # Clicked just above first item.
762                     index = -1 # Append to top of list.
763                 else:
764                     index = self.GetItemCount() + 1 # Append to end of list.
765         else: # Clicked on an item.
766             # Get bounding rectangle for the item the user is dropping over.
767             rect = self.GetItemRect(index)
768
769             # If the user is dropping into the lower half of the rect,
770             # we want to insert _after_ this item.
771             # Correct for the fact that there may be a heading involved.
772             #if y > rect.y - self.GetItemRect(0).y + rect.height/2:
773             #    index += 1
774         print('Insert de ListForCate', index, flags)
775         word, eff = seq[0][1]
776         if seq[0][-1] == 'words' :
777             if index < self.GetItemCount() and index != -1 :
778                 for val in seq :
779                     word, eff = val[1]
780                     self.cate.addwordincate(self.GetItemData(index)[0], word, eff)
781             else :
782                 index = self.GetItemCount()
783                 if self.cate.addcatefromwordtocate(word, eff) :
784                     pass
785                 else :
786                     dial = wx.MessageDialog(self, "This category name is already used", style=wx.OK|wx.CENTRE).ShowModal()
787                     dial.Destroy()
788             self.dlist = self.cate.getcate()
789             self.RefreshData(self.dlist)
790             self.parent.m_listToCate.RefreshData(self.cate.getwordstocate())
791             self.parent.m_listCateWords.RefreshData(self.parent.cate.getcatewords(self.GetItemData(index)[0]))
792             for i in range(0, self.GetItemCount(), 1):
793                 self.Select(i, on=0)
794             self.Select(index, on=1)
795             self.parent.butsave.SetBackgroundColour((255,0,0,255))
796         if seq[0][-1] == 'catewords' :
797             if index < self.GetItemCount() and index != -1 :
798                 for val in seq :
799                     word, eff = val[1]
800                     if word not in self.cate.cate['CATE'][self.GetItemData(index)[0]][1] :
801                         self.cate.changewordcate(self.GetItemData(index)[0], word, eff)
802                         self.parent.butsave.SetBackgroundColour((255,0,0,255))
803             else :
804                 index = self.GetItemCount()
805                 if self.cate.addcatefromwordcate(word, eff) :
806                     self.parent.butsave.SetBackgroundColour((255,0,0,255))
807                 else :
808                     dial = wx.MessageDialog(self, "This category name is already used", style=wx.OK|wx.CENTRE).ShowModal()
809                 #self.cate.addwordincate(self.GetItemData(index)[0], word, eff)
810             self.dlist = self.cate.getcate()
811             self.RefreshData(self.dlist)
812             self.parent.m_listToCate.RefreshData(self.cate.getwordstocate())
813             #self.parent.m_listCateWords.RefreshData(self.parent.cate.getcatewords(self.GetItemData(index)[0]))
814             self.parent.m_listCateWords.RefreshData(self.parent.cate.getcatewords(self.GetItemData(self.currentItem)[0]))
815             #self.SetSelection(index)
816
817
818
819 #        for i in seq: # Insert the item data.
820 #            idx = self.InsertItem(index, i[2])
821 #            self.SetItemData(idx, i[1])
822 #            for j in range(1, self.GetColumnCount()):
823 #                try: # Target list can have more columns than source.
824 #                    self.SetItem(idx, j, i[2+j])
825 #                except:
826 #                    pass # Ignore the extra columns.
827 #            index += 1
828
829 class ListForWords(ListForCate) :
830     def __init__(self, parent, dlist = {}, first = []):
831         wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
832         self.parent=parent
833         self.cate = self.parent.cate
834         self.dlist= self.cate.getwordstocate()
835         self.first = first
836         self.il = wx.ImageList(16, 16)
837         a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION"}
838         for k,v in list(a.items()):
839             s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
840             exec(s)
841         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
842         self.attr1 = wx.ListItemAttr()
843         self.attr1.SetBackgroundColour((230, 230, 230))
844         self.attr2 = wx.ListItemAttr()
845         self.attr2.SetBackgroundColour("light blue")
846         #self.attrselected = wx.ListItemAttr()
847         #self.attrselected.SetBackgroundColour("red")
848         self.SetListFont()
849         self.selected = {}
850         i = 0
851         for name in ['To categorize'] + self.first :
852             self.InsertColumn(i,name,wx.LIST_FORMAT_LEFT)
853             i += 1
854         self.itemDataMap = self.dlist
855         self.itemIndexMap = list(self.dlist.keys())
856         self.SetItemCount(len(self.dlist))
857         listmix.ListCtrlAutoWidthMixin.__init__(self)
858         listmix.ColumnSorterMixin.__init__(self, len(self.first) + 1)
859         self.SetColumnWidth(0, 400)
860         self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
861
862         self.SortListItems(1, False)
863
864         self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
865         self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnDClick)
866         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
867
868         dt = MyListDropCate(self)
869         self.SetDropTarget(dt)
870
871     def OnDClick(self, event) :
872         idx = event.GetIndex()
873         event.Skip()
874
875     def OnItemSelected(self, event):
876         self.currentItem = event.GetIndex() #event.m_itemIndex
877         event.Skip()
878
879     def OnGetItemImage(self, item):
880         return self.i_idx
881
882     def GetItemInfo(self, idx):
883         """
884         Collect all relevant data of a listitem, and put it in a list.
885         """
886
887         l = []
888         l.append(idx) # We need the original index, so it is easier to eventualy delete it.
889         l.append(self.GetItemData(idx)) # Itemdata.
890         l.append(self.GetItemText(idx)) # Text first column.
891         for i in range(1, self.GetColumnCount()): # Possible extra columns.
892             l.append(self.GetItem(idx, i).GetText())
893         l.append('words')
894         return l
895
896
897     def StartDrag(self, event):
898         """
899         Put together a data object for drag-and-drop _from_ this list.
900         """
901
902         l = []
903         idx = -1
904         while True: # Find all the selected items and put them in a list.
905             idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
906             if idx == -1:
907                 break
908             l.append(self.GetItemInfo(idx))
909
910         # Pickle the items list.
911         itemdata = pickle.dumps(l, 1)
912         # Create our own data format and use it
913         # in a Custom data object.
914         ldata = wx.CustomDataObject("ListCtrlItems")
915         ldata.SetData(itemdata)
916         # Now make a data object for the  item list.
917         data = wx.DataObjectComposite()
918         data.Add(ldata)
919
920         # Create drop source and begin drag-and-drop.
921         dropSource = wx.DropSource(self)
922         dropSource.SetData(data)
923         res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
924
925
926         # If move, we want to remove the item from this list.
927         if res == wx.DragMove and l[0][-1] != 'words':
928             # It's possible we are dragging/dropping from this list to this list.
929             # In which case, the index we are removing may have changed...
930
931             # Find correct position.
932             l.reverse() # Delete all the items, starting with the last item.
933             for i in l:
934                 pos = self.FindItem(i[0], i[2])
935                 print('detruit : ',pos)
936                 self.DeleteItem(pos)
937
938
939     def Insert(self, x, y, seq):
940         """
941         Insert text at given x, y coordinates --- used with drag-and-drop.
942         """
943
944         # Find insertion point.
945         index, flags = self.HitTest((x, y))
946
947         if index == wx.NOT_FOUND: # Not clicked on an item.
948             if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
949                 index = self.GetItemCount() # Append to end of list.
950             elif self.GetItemCount() > 0:
951                 if y <= self.GetItemRect(0).y: # Clicked just above first item.
952                     index = 0 # Append to top of list.
953                 else:
954                     index = self.GetItemCount() + 1 # Append to end of list.
955         else: # Clicked on an item.
956             # Get bounding rectangle for the item the user is dropping over.
957             rect = self.GetItemRect(index)
958
959             # If the user is dropping into the lower half of the rect,
960             # we want to insert _after_ this item.
961             # Correct for the fact that there may be a heading involved.
962             if y > rect.y - self.GetItemRect(0).y + rect.height/2:
963                 index += 1
964         word, eff = seq[0][1]
965         if seq[0][-1] == 'catewords' :
966             for val in seq :
967                 word, eff = val[1]
968                 categorie = self.cate.findcatefromword(word)
969                 self.cate.addwordinwords(categorie, word, eff)
970             self.RefreshData(self.cate.getwordstocate())
971             self.parent.m_listCate.RefreshData(self.cate.getcate())
972             self.parent.m_listCateWords.RefreshData(self.cate.getcatewords(categorie))
973             self.parent.butsave.SetBackgroundColour((255,0,0,255))
974         elif seq[0][-1] == 'cate' :
975             categorie = seq[0][1][0]
976             self.cate.delcate(categorie)
977             self.RefreshData(self.cate.getwordstocate())
978             self.parent.m_listCate.RefreshData(self.cate.getcate())
979             self.parent.m_listCate.SetSelection(0)
980             self.parent.m_listCateWords.RefreshData(self.cate.getcatewords(self.parent.m_listCate.GetItemText(0)))
981             self.parent.butsave.SetBackgroundColour((255,0,0,255))
982
983
984 class ListForCateWords(ListForCate) :
985     def __init__(self, parent, dlist = {}, first = []):
986         wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
987         self.parent=parent
988         self.cate = self.parent.cate
989         self.dlist= {}
990         self.first = first
991         self.il = wx.ImageList(16, 16)
992         a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","p_idx":"TIP","e_idx":"ERROR","i_idx":"QUESTION"}
993         for k,v in list(a.items()):
994             s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
995             exec(s)
996         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
997         self.attr1 = wx.ListItemAttr()
998         self.attr1.SetBackgroundColour((230, 230, 230))
999         self.attr2 = wx.ListItemAttr()
1000         self.attr2.SetBackgroundColour("light blue")
1001         #self.attrselected = wx.ListItemAttr()
1002         #self.attrselected.SetBackgroundColour("red")
1003         self.SetListFont()
1004         self.selected = {}
1005         i = 0
1006         for name in ['Contents'] + self.first :
1007             self.InsertColumn(i,name,wx.LIST_FORMAT_LEFT)
1008             i += 1
1009         self.itemDataMap = self.dlist
1010         self.itemIndexMap = list(self.dlist.keys())
1011         self.SetItemCount(len(self.dlist))
1012         listmix.ListCtrlAutoWidthMixin.__init__(self)
1013         listmix.ColumnSorterMixin.__init__(self, len(self.first) + 1)
1014         self.SetColumnWidth(0, 300)
1015         self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
1016
1017         self.SortListItems(1, False)
1018
1019         self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
1020         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
1021
1022         dt = MyListDropCate(self)
1023         self.SetDropTarget(dt)
1024
1025     def OnItemSelected(self, event):
1026         self.currentItem = event.GetIndex() #event.m_itemIndex
1027         event.Skip()
1028
1029
1030     def GetItemInfo(self, idx):
1031         """
1032         Collect all relevant data of a listitem, and put it in a list.
1033         """
1034
1035         l = []
1036         l.append(idx) # We need the original index, so it is easier to eventualy delete it.
1037         l.append(self.GetItemData(idx)) # Itemdata.
1038         l.append(self.GetItemText(idx)) # Text first column.
1039         for i in range(1, self.GetColumnCount()): # Possible extra columns.
1040             l.append(self.GetItem(idx, i).GetText())
1041         l.append('catewords')
1042         return l
1043
1044
1045     def StartDrag(self, event):
1046         """
1047         Put together a data object for drag-and-drop _from_ this list.
1048         """
1049
1050         l = []
1051         idx = -1
1052         while True: # Find all the selected items and put them in a list.
1053             idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
1054             if idx == -1:
1055                 break
1056             l.append(self.GetItemInfo(idx))
1057
1058         # Pickle the items list.
1059         itemdata = pickle.dumps(l, 1)
1060         # Create our own data format and use it
1061         # in a Custom data object.
1062         ldata = wx.CustomDataObject("ListCtrlItems")
1063         ldata.SetData(itemdata)
1064         # Now make a data object for the  item list.
1065         data = wx.DataObjectComposite()
1066         data.Add(ldata)
1067
1068         # Create drop source and begin drag-and-drop.
1069         dropSource = wx.DropSource(self)
1070         dropSource.SetData(data)
1071         res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
1072         print('current')
1073         print(self.parent.m_listCate.currentItem)
1074
1075         # If move, we want to remove the item from this list.
1076         #if res == wx.DragMove:
1077         #    # It's possible we are dragging/dropping from this list to this list.
1078         #    # In which case, the index we are removing may have changed...
1079
1080         #    # Find correct position.
1081         #    l.reverse() # Delete all the items, starting with the last item.
1082         #    for i in l:
1083         #        pos = self.FindItem(i[0], i[2])
1084         #        self.DeleteItem(pos)
1085
1086
1087     def Insert(self, x, y, seq):
1088         """
1089         Insert text at given x, y coordinates --- used with drag-and-drop.
1090         """
1091         pass
1092         # Find insertion point.
1093         index, flags = self.HitTest((x, y))
1094 #
1095 #        if index == wx.NOT_FOUND: # Not clicked on an item.
1096 #            if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
1097 #                index = self.GetItemCount() # Append to end of list.
1098 #            elif self.GetItemCount() > 0:
1099 #                if y <= self.GetItemRect(0).y: # Clicked just above first item.
1100 #                    index = 0 # Append to top of list.
1101 #                else:
1102 #                    index = self.GetItemCount() + 1 # Append to end of list.
1103 #        else: # Clicked on an item.
1104 #            # Get bounding rectangle for the item the user is dropping over.
1105 #            rect = self.GetItemRect(index)
1106 #
1107 #            # If the user is dropping into the lower half of the rect,
1108 #            # we want to insert _after_ this item.
1109 #            # Correct for the fact that there may be a heading involved.
1110 #            if y > rect.y - self.GetItemRect(0).y + rect.height/2:
1111 #                index += 1
1112         print('Insert de ListForCateWords', index,flags)
1113         if seq[0][-1] == 'words' :
1114             for val in seq :
1115                 word, eff = val[1]
1116                 categorie = self.parent.m_listCate.getColumnText(self.parent.m_listCate.GetFirstSelected(),0)
1117                 self.cate.addwordincate(categorie, word, eff)
1118             self.dlist = self.cate.getwordstocate()
1119             self.RefreshData(self.cate.getcatewords(categorie))
1120             self.parent.m_listCate.RefreshData(self.cate.getcate())
1121             self.parent.m_listToCate.RefreshData(self.dlist)
1122             self.parent.butsave.SetBackgroundColour((255,0,0,255))
1123
1124
1125 class MyListDropCate(wx.DropTarget):
1126     """
1127     Drop target for simple lists.
1128     """
1129     def __init__(self, source):
1130         """
1131         Arguments:
1132         source: source listctrl.
1133         """
1134         wx.DropTarget.__init__(self)
1135
1136         #------------
1137
1138         self.dv = source
1139
1140         #------------
1141
1142         # Specify the type of data we will accept.
1143         self.data = wx.CustomDataObject("ListCtrlItems")
1144         self.SetDataObject(self.data)
1145
1146     #-----------------------------------------------------------------------
1147
1148     # Called when OnDrop returns True.
1149     # We need to get the data and do something with it.
1150     def OnData(self, x, y, d):
1151         """
1152         ...
1153         """
1154
1155         # Copy the data from the drag source to our data object.
1156         if self.GetData():
1157             # Convert it back to a list and give it to the viewer.
1158             ldata = self.data.GetData()
1159             l = pickle.loads(ldata)
1160             self.dv.Insert(x, y, l)
1161
1162         # What is returned signals the source what to do
1163         # with the original data (move, copy, etc.)  In this
1164         # case we just return the suggested value given to us.
1165         return d