...
authorpierre <ratinaud@univ-tlse2.fr>
Sun, 4 Feb 2024 21:46:06 +0000 (22:46 +0100)
committerpierre <ratinaud@univ-tlse2.fr>
Sun, 4 Feb 2024 21:46:06 +0000 (22:46 +0100)
ProfList.py
Rscripts/simi.R
elcategorizator.py [new file with mode: 0644]
functions.py
iramuteq.py
layout.py
openanalyse.py
tableau.py

index 6038edb..ebc9a53 100644 (file)
@@ -116,12 +116,12 @@ class ProfListctrlPanel(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.Col
         self.InsertColumn(6, "forme", wx.LIST_FORMAT_RIGHT)
         self.InsertColumn(7, "p", wx.LIST_FORMAT_RIGHT)
         self.SetColumnWidth(0, 60)
         self.InsertColumn(6, "forme", wx.LIST_FORMAT_RIGHT)
         self.InsertColumn(7, "p", wx.LIST_FORMAT_RIGHT)
         self.SetColumnWidth(0, 60)
-        self.SetColumnWidth(1, 70)
-        self.SetColumnWidth(2, 80)
-        self.SetColumnWidth(3, 100)
-        self.SetColumnWidth(4, 70)
-        self.SetColumnWidth(5, 60)
-        self.SetColumnWidth(6, 140)
+        self.SetColumnWidth(1, 100)
+        self.SetColumnWidth(2, 100)
+        self.SetColumnWidth(3, 120)
+        self.SetColumnWidth(4, 150)
+        self.SetColumnWidth(5, 100)
+        self.SetColumnWidth(6, 300)
         self.SetColumnWidth(7, wx.LIST_AUTOSIZE)
         #These two should probably be passed to init more cleanly
         #setting the numbers of items = number of elements in the dictionary
         self.SetColumnWidth(7, wx.LIST_AUTOSIZE)
         #These two should probably be passed to init more cleanly
         #setting the numbers of items = number of elements in the dictionary
@@ -131,8 +131,10 @@ class ProfListctrlPanel(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.Col
         #mixins
         listmix.ListCtrlAutoWidthMixin.__init__(self)
         listmix.ColumnSorterMixin.__init__(self, len(classen[0]))
         #mixins
         listmix.ListCtrlAutoWidthMixin.__init__(self)
         listmix.ColumnSorterMixin.__init__(self, len(classen[0]))
-        #sort by genre (column 2), A->Z ascending order (1)
         self.SortListItems(0, True)
         self.SortListItems(0, True)
+        #sort by genre (column 2), A->Z ascending order (1)
+
+
         #events
         #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
         self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnPopupTwo, self)
         #events
         #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
         self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnPopupTwo, self)
index 2a4c8b7..bf42008 100755 (executable)
@@ -376,7 +376,7 @@ plot.simi <- function(graph.simi, p.type = 'tkplot',filename=NULL, communities =
             require(tcltk)
             ReturnVal <- tkmessageBox(title="RGL 3 D",message="Cliquez pour commencer le film",icon="info",type="ok")
 
             require(tcltk)
             ReturnVal <- tkmessageBox(title="RGL 3 D",message="Cliquez pour commencer le film",icon="info",type="ok")
 
-            movie3d(spin3d(axis=c(0,1,0),rpm=6), movie = 'film_graph', frames = "tmpfilm", duration=10, clean=TRUE, top = TRUE, dir = movie)
+            movie3d(spin3d(axis=c(0,0,1),rpm=6), movie = 'film_graph', frames = "tmpfilm", duration=10, clean=TRUE, top = TRUE, dir = movie)
             ReturnVal <- tkmessageBox(title="RGL 3 D",message="Film fini !",icon="info",type="ok")
         }
         #play3d(spin3d(axis=c(0,1,0),rpm=6))
             ReturnVal <- tkmessageBox(title="RGL 3 D",message="Film fini !",icon="info",type="ok")
         }
         #play3d(spin3d(axis=c(0,1,0),rpm=6))
diff --git a/elcategorizator.py b/elcategorizator.py
new file mode 100644 (file)
index 0000000..b9f531c
--- /dev/null
@@ -0,0 +1,1005 @@
+# -*- coding: utf-8 -*-
+#Author: Pierre Ratinaud
+#Copyright (c) 2022 Pierre Ratinaud
+#License: GNU/GPL
+
+import os
+import wx
+import wx.xrc
+#from wx.lib.splitter import MultiSplitterWindow
+from listlex import *
+import pickle
+import json
+
+
+
+class CategoDict :
+    def __init__(self, pathout = None):
+        self.pathout = pathout
+        self.cate = self.readjson()
+        self.lenwords = len(self.cate['TOCATE']) + len([word for categorie in self.cate['CATE'] for word in self.cate['CATE'][categorie][1]])
+
+    def readjson(self):
+        if self.pathout is not None :
+            with open(self.pathout['cate.json'], 'r') as f :
+                cate = json.load(f)
+        else :
+            cate = {'TOCATE' : {'word1': 3, 'word2' : 2, 'word3' : 5}, 'CATE': {'cat1' : [34,{'word6':30, 'word7':4}], 'cat2' : [20,{'word20':20}]}}
+        return cate
+
+    def save(self) :
+        with open(self.pathout['cate.json'], 'w', encoding='utf8') as f :
+            f.write(json.dumps(self.cate, indent=4))
+        print("json saved!")
+
+    def exportdict(self):
+        pass
+
+    def getcate(self) :
+        cate = []
+        i = 0
+        for val in self.cate['CATE'] :
+            cate.append([i, [val, self.cate['CATE'][val][0]]])
+            i += 1
+        return dict(cate)
+
+    def getwordstocate(self) :
+        words = []
+        i = 0
+        for val in self.cate['TOCATE'] :
+            words.append([i, [val, self.cate['TOCATE'][val]]])
+            i+= 1
+        return dict(words)
+
+    def getcatewords(self, cat) :
+        catewords = []
+        i = 0
+        if cat not in self.cate['CATE'] :
+            return {}
+        for val in self.cate['CATE'][cat][1] :
+            catewords.append([i, [val, self.cate['CATE'][cat][1][val]]])
+            i += 1
+        return dict(catewords)
+
+    def getwordscate(self) :
+        wc = {}
+        for word in self.cate['TOCATE'] :
+            wc[word] = word
+        for categorie in self.cate['CATE'] :
+            for word in self.cate['CATE'][categorie][1] :
+                wc[word] = categorie
+        return wc
+
+    def addwordincate(self, categorie, word, eff) :
+        self.cate['CATE'][categorie][1][word] = eff
+        self.cate['CATE'][categorie][0] += eff
+        del(self.cate['TOCATE'][word])
+
+    def addwordinwords(self, categorie, word, eff) :
+        print(categorie, word, eff)
+        self.cate['TOCATE'][word] = eff
+        self.cate['CATE'][categorie][0] -= eff
+        del(self.cate['CATE'][categorie][1][word])
+        if self.cate['CATE'][categorie][0] == 0 :
+            del(self.cate['CATE'][categorie])
+
+    def findcatefromword(self, word) :
+        for categorie in self.cate['CATE'] :
+            if word in self.cate['CATE'][categorie][1] :
+                return categorie
+        return None
+
+    def changewordcate(self, newcate, word, eff) :
+        oldcat = self.findcatefromword(word)
+        del(self.cate['CATE'][oldcat][1][word])
+        self.cate['CATE'][oldcat][0] -= eff
+        self.cate['CATE'][newcate][1][word] = eff
+        self.cate['CATE'][newcate][0] += eff
+        if self.cate['CATE'][oldcat][0] == 0 :
+            del(self.cate['CATE'][oldcat])
+
+    def addcatefromwordtocate(self, word, eff) :
+        if word in self.cate['CATE'] :
+            return False
+        else :
+            self.cate['CATE'][word]=[eff,{word:eff}]
+            del(self.cate['TOCATE'][word])
+            return True
+
+    def addcatefromwordcate(self, word, eff) :
+        if word in self.cate['CATE'] :
+            return False
+        else :
+            oldcat = self.findcatefromword(word)
+            self.cate['CATE'][word]=[eff,{word:eff}]
+            del(self.cate['CATE'][oldcat][1][word])
+            self.cate['CATE'][oldcat][0] -= eff
+            if self.cate['CATE'][oldcat][0] == 0 :
+                del(self.cate['CATE'][oldcat])
+            return True
+
+    def delcate(self, categorie) :
+        for word in self.cate['CATE'][categorie][1] :
+            self.cate['TOCATE'][word] = self.cate['CATE'][categorie][1][word]
+        del(self.cate['CATE'][categorie])
+
+    def loadcate(self, infile) :
+        if self.cate['CATE'] != {} :
+            print("Categories should be empty")
+            return False
+        with open(infile, 'r') as f :
+            newcate = json.load(f)
+        for categorie in newcate['CATE'] :
+            self.cate['CATE'][categorie] = [0,{}]
+            for word in newcate['CATE'][categorie][1] :
+                if word in self.cate['TOCATE'] :
+                    self.cate['CATE'][categorie][1][word] = self.cate['TOCATE'][word]
+                    self.cate['CATE'][categorie][0] += self.cate['TOCATE'][word]
+                    del(self.cate['TOCATE'][word])
+
+    def makestat(self) :
+        totocat = sum([self.cate['TOCATE'][word] for word in self.cate['TOCATE']])
+        nbtocat = len(self.cate['TOCATE'])
+        nbcate = len(self.cate['CATE'])
+        totcate = sum([self.cate['CATE'][categorie][0] for categorie in self.cate['CATE']])
+        lenwordincate = len([word for categorie in self.cate['CATE'] for word in self.cate['CATE'][categorie][1]])
+        return nbtocat, totocat, nbcate, totcate, lenwordincate
+
+
+#cate = CategoDict()
+
+
+class ElCategorizator ( wx.Panel ):
+
+    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 ):
+        wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name )
+        self.pathout = pathout
+        self.parent = parent
+        self.tableau = tableau
+
+        self.cate = CategoDict(self.pathout)
+        gsizer =  wx.BoxSizer( wx.VERTICAL )
+
+        bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
+
+        self.m_listToCate = ListForWords(self, dlist = self.cate, first = ['eff'])
+        bSizer1.Add( self.m_listToCate, 2, wx.ALL|wx.EXPAND, 5 )
+
+        self.m_listCate = ListForCate(self, dlist = self.cate, first = ['eff'])
+        bSizer1.Add( self.m_listCate, 1, wx.ALL|wx.EXPAND, 5 )
+
+        self.m_listCateWords = ListForCateWords(self, dlist = self.cate, first = ['eff'])
+        bSizer1.Add( self.m_listCateWords, 1, wx.ALL|wx.EXPAND, 5 )
+
+        bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
+
+        self.butsave = wx.Button( self, wx.ID_SAVE, u"Save", wx.DefaultPosition, wx.DefaultSize, 0 )
+        bSizer2.Add( self.butsave, 0, wx.ALL, 5 )
+
+        self.butcsv = wx.Button( self, wx.ID_ANY, u"Export Columns", wx.DefaultPosition, wx.DefaultSize, 0 )
+        bSizer2.Add( self.butcsv, 0, wx.ALL, 5 )
+
+        self.butdict = wx.Button( self, wx.ID_ANY, u"Export dictonary", wx.DefaultPosition, wx.DefaultSize, 0 )
+        bSizer2.Add( self.butdict, 0, wx.ALL, 5 )
+
+        self.butload = wx.Button( self, wx.ID_ANY, u"Load a categorization", wx.DefaultPosition, wx.DefaultSize, 0 )
+        bSizer2.Add( self.butload, 0, wx.ALL, 5 )
+
+        bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
+
+        self.nbword = """Words : {:d} ({:d}) | """
+
+        self.stat = """ Words to categorize : {:d} ({}%) - {:d} ({}%) -- Categories : {:d} - {:d} ({}%) - {:d} ({}%)"""
+#        nbtocat, totocat, nbcate, totcate = self.cate.makestat()
+#        lenwords = self.cate.lenwords
+#        totwords = totocat + totcate
+#        prtocat = repr(nbtocat/lenwords)
+#        prtotocat = repr(totocat/totwords)
+#        prcate = repr(totcate/totwords)
+        self.wordtxt = wx.StaticText(self, -1, "")
+        bSizer3.Add( self.wordtxt, 0, wx.ALL, 5 )
+        self.stattxt = wx.StaticText(self, -1, "")
+        bSizer3.Add( self.stattxt, 0, wx.ALL, 5 )
+
+
+        gsizer.Add( bSizer2, 0, wx.EXPAND, 5 )
+        gsizer.Add( bSizer1, 2, wx.EXPAND, 5 )
+        gsizer.Add( bSizer3, 0, wx.EXPAND, 5 )
+
+        self.butsave.Bind(wx.EVT_BUTTON, self.OnSave)
+        self.butcsv.Bind(wx.EVT_BUTTON, self.OnCSV)
+        self.butdict.Bind(wx.EVT_BUTTON, self.OnDict)
+        self.butsave.SetBackgroundColour((14, 242, 14, 255))
+        self.butload.Bind(wx.EVT_BUTTON, self.OnLoad)
+        self.OnStat()
+        self.SetSizer( gsizer )
+        self.Layout()
+
+    def __del__( self ):
+        pass
+
+
+    def OnLoad(self, event) :
+        if len(self.cate.cate['CATE']) != 0 :
+            print("Categories should be empty")
+            event.Skip()
+            return
+        wildcard = "json|*.json|" \
+                   "All file|*.*"
+        dlg = wx.FileDialog(
+             self, message="Choose a file",
+             defaultDir=self.pathout.dirout,
+             defaultFile="",
+             wildcard=wildcard,
+             style=wx.FD_OPEN |
+                   wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST |
+                   wx.FD_PREVIEW
+             )
+
+        if dlg.ShowModal() == wx.ID_OK:
+            paths = dlg.GetPaths()
+            path = paths[0]
+            self.cate.loadcate(path)
+            self.m_listCate.RefreshData(self.cate.getcate())
+            self.m_listToCate.RefreshData(self.cate.getwordstocate())
+        dlg.Destroy()
+
+    def OnSave(self, event) :
+        self.cate.save()
+        self.butsave.SetBackgroundColour((14, 242, 14, 255))
+
+    def OnCSV(self, event) :
+        wordscate = self.cate.getwordscate()
+        newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
+        for line in self.tableau.select_col(self.tableau.selected_col):
+            newline = []
+            for word in line :
+                newline.append(wordscate.get(word,word))
+            newtab.append(newline)
+        with open(self.pathout['tableout.csv'], 'w') as f :
+            f.write('\n'.join(['\t'.join(line) for line in newtab]))
+        print("csv exported !")
+
+    def OnDict(self, event):
+        with open(self.pathout['dictionnary.txt'], 'w') as f :
+            for categorie in self.cate.cate['CATE'] :
+                f.write(categorie + ': \t' + repr(self.cate.cate['CATE'][categorie][0]) + '\n')
+                for word in self.cate.cate['CATE'][categorie][1] :
+                    f.write('\t' + word + ': \t' + repr(self.cate.cate['CATE'][categorie][1][word]) + '\n')
+            for word in self.cate.cate['TOCATE'] :
+                f.write(word + ':\t' + repr(self.cate.cate['TOCATE'][word]) + '\n')
+        print("dictionnary exported !")
+
+    def OnStat(self) :
+        nbtocat, totocat, nbcate, totcate, lenwordincate = self.cate.makestat()
+        totwords = totocat + totcate
+        prtocat = repr(round((nbtocat/self.cate.lenwords) * 100 ,2))
+        prtotocat = repr(round((totocat/totwords) * 100, 2))
+        prcate = repr(round((totcate/totwords)*100, 2))
+        prwordincate = repr(round((lenwordincate/self.cate.lenwords)*100, 2))
+        self.stattxt.SetLabel(self.stat.format(nbtocat, prtocat, totocat, prtotocat, nbcate, lenwordincate, prwordincate, totcate, prcate))
+
+    def OnAddToTable(self) :
+        wordscate = self.cate.getwordscate()
+        newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
+        for line in self.tableau.select_col(self.tableau.selected_col):
+            newline = []
+            for word in line :
+                newline.append(wordscate.get(word,word))
+            newtab.append(newline)
+
+
+
+#class ListPanel(wx.Panel) :
+#     def __init__(self, parent, gparent, List):
+#        wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN)
+#        self.parent = parent
+#        self.cate = gparent.cate
+#        self.list = List(self, dlist = gparent.cate, first = ['eff'])
+
+
+#class ElCategorizator ( wx.Panel ):
+#
+#    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 ):
+#        wx.Panel.__init__ ( self, parent, id = id, pos = pos, size = size, style = style, name = name )
+#        self.pathout = pathout
+#        self.parent = parent
+#        self.tableau = tableau
+#
+#        self.cate = CategoDict(self.pathout)
+#
+#        splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
+#        self.splitter = splitter
+#        sizer = wx.BoxSizer(wx.HORIZONTAL)
+#        sizer.Add(splitter, 1, wx.EXPAND)
+#        self.SetSizer(sizer)
+#
+#        panelwords = ListPanel(splitter, self, ListForWords)
+#        splitter.AppendWindow(panelwords, 150)
+#        panelcate = ListPanel(splitter, self, ListForCate)
+#        splitter.AppendWindow(panelcate, 150)
+#        panelwordscate = ListPanel(splitter, self, ListForCateWords)
+#        splitter.AppendWindow(panelwordscate, 150)
+#        self.m_listToCate = panelwords.list
+#        self.m_listCate = panelcate.list
+#        self.m_listCateWords = panelwordscate.list
+#
+#    def __del__( self ):
+#        pass
+#
+#    def OnSave(self, event) :
+#        self.cate.save()
+#        self.butsave.SetBackgroundColour((14, 242, 14, 255))
+#
+#    def OnCSV(self, event) :
+#        wordscate = self.cate.getwordscate()
+#        newtab = [['category%i' % i for i in range(1, len(self.tableau.selected_col)+1)]]
+#        for line in self.tableau.select_col(self.tableau.selected_col):
+#            newline = []
+#            for word in line :
+#                newline.append(wordscate.get(word,word))
+#            newtab.append(newline)
+#        with open(self.pathout['tableout.csv'], 'w') as f :
+#            f.write('\n'.join(['\t'.join(line) for line in newtab]))
+#        print("csv exported !")
+#
+#    def OnDict(self, event):
+#        with open(self.pathout['dictionnary.txt'], 'w') as f :
+#            for categorie in self.cate.cate['CATE'] :
+#                f.write(categorie + ': \t' + repr(self.cate.cate['CATE'][categorie][0]) + '\n')
+#                for word in self.cate.cate['CATE'][categorie][1] :
+#                    f.write('\t' + word + ': \t' + repr(self.cate.cate['CATE'][categorie][1][word]) + '\n')
+#            for word in self.cate.cate['TOCATE'] :
+#                f.write(word + ':\t' + repr(self.cate.cate['TOCATE'][word]) + '\n')
+#        print("dictionnary exported !")
+
+
+class ListForCate(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
+
+    def __init__(self, parent, dlist = {}, first = [], usefirst = False, menu = True):
+        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)
+        self.parent=parent
+        self.cate = self.parent.cate
+        self.dlist= self.cate.getcate()
+        self.first = first
+        self.il = wx.ImageList(20, 20)
+        a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION", "p_idx":"PLUS"}
+        for k,v in list(a.items()):
+            s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(20,20)))" % (k,v)
+            exec(s)
+        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+        self.attr1 = wx.ListItemAttr()
+        self.attr1.SetBackgroundColour((230, 230, 230))
+        self.attr2 = wx.ListItemAttr()
+        self.attr2.SetBackgroundColour("light blue")
+        #self.attrselected = wx.ListItemAttr()
+        #self.attrselected.SetBackgroundColour("red")
+        self.SetListFont()
+        self.selected = {}
+        i = 0
+        for name in ['Categories'] + self.first :
+            self.InsertColumn(i,name,wx.LIST_FORMAT_LEFT)
+            i += 1
+        self.itemDataMap = self.dlist
+        self.itemIndexMap = list(self.dlist.keys())
+        self.SetItemCount(len(self.dlist))
+        listmix.ListCtrlAutoWidthMixin.__init__(self)
+        listmix.ColumnSorterMixin.__init__(self, len(self.first) + 1)
+
+        #self.SortListItems(1, False)
+        self.SetColumnWidth(0, 300)
+        self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+
+        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
+        self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.ShowWords)
+        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnBeginEdit)
+        self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit)
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
+        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnSortColumn)
+
+        if self.GetItemCount() != 0 :
+            #self.SetItemState(0, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
+            self.Select(0, on=1)
+
+        dt = MyListDropCate(self)
+        self.SetDropTarget(dt)
+
+    def OnSortColumn(self, evt) :
+        print(self.currentItem)
+        evt.Skip()
+
+    def SetListFont(self) :
+        self.SetFont(wx.Font(16, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
+
+    def OnGetItemImage(self, item):
+        return self.p_idx
+
+    def OnBeginEdit(self, event) :
+        self.EditLabel(event.GetIndex())
+        event.Skip()
+
+    def OnEndEdit(self, event) :
+        newlabel = event.GetLabel()
+        idx = event.GetIndex()
+        oldlabel = self.GetItemText(idx)
+        if newlabel not in self.cate.cate['CATE'] :
+            self.cate.cate['CATE'][newlabel] = self.cate.cate['CATE'][oldlabel]
+            del(self.cate.cate['CATE'][oldlabel])
+        self.RefreshData(self.cate.getcate())
+
+    def ShowWords(self, event) :
+        index = event.GetIndex()
+        try :
+            data = self.cate.getcatewords(self.GetItemText(index))
+            self.parent.m_listCateWords.RefreshData(data)
+            self.parent.m_listCateWords.SetSelection(0)
+        except :
+            pass
+        event.Skip()
+
+    def RefreshData(self, data):
+        try :
+            item = self.currentItem
+        except :
+            item = 0
+        self.itemDataMap = data
+        self.itemIndexMap = list(data.keys())
+        self.SetItemCount(len(data))
+        order = self._colSortFlag[self._col]
+        self.SortListItems(self._col, order)
+        #self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+        #self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+        #self.SetColumnWidth(0,300)
+        self.parent.OnStat()
+        self.Refresh()
+        try :
+            self.SetSelection(item)
+            self.Focus(item)
+        except :
+            pass
+
+    def GetListCtrl(self):
+        return self
+
+    def GetSortImages(self):
+        return (self.sm_dn, self.sm_up)
+
+    def SortItems(self, sorter=None):
+        try :
+            select = self.currentItem
+            word = self.GetItemData(select)[0]
+        except Exception as e: print('word',e)
+
+        listTemp = sorted(self.itemDataMap.items(),
+            key=lambda x:x[1][self._col], reverse= (self._colSortFlag[self._col]!=True))
+        dlist = dict([[line[0],line[1]] for line in listTemp])
+        self.itemDataMap = dlist
+        self.itemIndexMap = list(dlist.keys())
+        self.Refresh() # redraw the list
+        try :
+            formes = [self.getColumnText(i, 0) for i in range(self.GetItemCount())]
+            idx = [i for i, val in enumerate(formes) if val == word][0]
+            self.SetSelection(idx)
+            self.Focus(idx)
+        except Exception as e: print(e)
+
+    def OnGetItemText(self, item, col):
+        index=self.itemIndexMap[item]
+        s = self.itemDataMap[index][col]
+        if isinstance(s, (int, float)):
+            return str(s)
+        else:
+            return s #modification pour python 3
+
+    def OnGetItemAttr(self, item):
+#        if self.IsSelected(index) == True :
+#            print('selected', index)
+        index=self.itemIndexMap[item]
+        if item % 2 :
+           return self.attr1
+        else :
+           return self.attr2
+
+    def getselectedwords(self) :
+        words = [self.getColumnText(self.GetFirstSelected(), 0)]
+        last = self.GetFirstSelected()
+        while self.GetNextSelected(last) != -1:
+            last = self.GetNextSelected(last)
+            words.append(self.getColumnText(last, 0))
+        return words
+
+    def GetString(self):
+        return self.getselectedwords()[0]
+
+    def GetSelections(self):
+        return self.getselectedwords()
+
+    def getColumnText(self, index, col):
+        item = self.GetItem(index, col)
+        return item.GetText()
+
+    def GetItemData(self, item) :
+        index=self.itemIndexMap[item]
+        s = self.itemDataMap[index]
+        return s
+
+    def OnItemSelected(self, event):
+        self.currentItem = event.GetIndex() #event.m_itemIndex
+        event.Skip()
+
+    def SetSelection(self, index) :
+        for i in range(0, self.GetItemCount(), 1) :
+            self.Select(i, on=0)
+        self.Select(index, on=1)
+
+    def GetItemInfo(self, idx):
+        """
+        Collect all relevant data of a listitem, and put it in a list.
+        """
+
+        l = []
+        l.append(idx) # We need the original index, so it is easier to eventualy delete it.
+        l.append(self.GetItemData(idx)) # Itemdata.
+        l.append(self.GetItemText(idx)) # Text first column.
+        for i in range(1, self.GetColumnCount()): # Possible extra columns.
+            l.append(self.GetItem(idx, i).GetText())
+        l.append('cate')
+        return l
+
+
+    def StartDrag(self, event):
+        """
+        Put together a data object for drag-and-drop _from_ this list.
+        """
+
+        l = []
+        idx = -1
+        while True: # Find all the selected items and put them in a list.
+            idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
+            if idx == -1:
+                break
+            l.append(self.GetItemInfo(idx))
+
+        # Pickle the items list.
+        itemdata = pickle.dumps(l, 1)
+        # Create our own data format and use it
+        # in a Custom data object.
+        ldata = wx.CustomDataObject("ListCtrlItems")
+        ldata.SetData(itemdata)
+        # Now make a data object for the  item list.
+        data = wx.DataObjectComposite()
+        data.Add(ldata)
+
+        # Create drop source and begin drag-and-drop.
+        dropSource = wx.DropSource(self)
+        dropSource.SetData(data)
+        res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
+
+        # If move, we want to remove the item from this list.
+        if res == wx.DragMove and l[0][-1] != 'cate' :
+            # It's possible we are dragging/dropping from this list to this list.
+            # In which case, the index we are removing may have changed...
+
+            # Find correct position.
+            l.reverse() # Delete all the items, starting with the last item.
+            for i in l:
+                pos = self.FindItem(i[0], i[2])
+                self.DeleteItem(pos)
+
+
+    def Insert(self, x, y, seq):
+        """
+        Insert text at given x, y coordinates --- used with drag-and-drop.
+        """
+
+        # Find insertion point.
+        index, flags = self.HitTest((x, y))
+
+        if index == wx.NOT_FOUND: # Not clicked on an item.
+            if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
+                index = self.GetItemCount() # Append to end of list.
+            elif self.GetItemCount() > 0:
+                if y <= self.GetItemRect(0).y: # Clicked just above first item.
+                    index = -1 # Append to top of list.
+                else:
+                    index = self.GetItemCount() + 1 # Append to end of list.
+        else: # Clicked on an item.
+            # Get bounding rectangle for the item the user is dropping over.
+            rect = self.GetItemRect(index)
+
+            # If the user is dropping into the lower half of the rect,
+            # we want to insert _after_ this item.
+            # Correct for the fact that there may be a heading involved.
+            #if y > rect.y - self.GetItemRect(0).y + rect.height/2:
+            #    index += 1
+        print('Insert de ListForCate', index, flags)
+        word, eff = seq[0][1]
+        if seq[0][-1] == 'words' :
+            if index < self.GetItemCount() and index != -1 :
+                for val in seq :
+                    word, eff = val[1]
+                    self.cate.addwordincate(self.GetItemData(index)[0], word, eff)
+            else :
+                index = self.GetItemCount()
+                if self.cate.addcatefromwordtocate(word, eff) :
+                    pass
+                else :
+                    dial = wx.MessageDialog(self, "This category name is already used", style=wx.OK|wx.CENTRE).ShowModal()
+            self.dlist = self.cate.getcate()
+            self.RefreshData(self.dlist)
+            self.parent.m_listToCate.RefreshData(self.cate.getwordstocate())
+            self.parent.m_listCateWords.RefreshData(self.parent.cate.getcatewords(self.GetItemData(index)[0]))
+            for i in range(0, self.GetItemCount(), 1):
+                self.Select(i, on=0)
+            self.Select(index, on=1)
+            self.parent.butsave.SetBackgroundColour((255,0,0,255))
+        if seq[0][-1] == 'catewords' :
+            if index < self.GetItemCount() and index != -1 :
+                for val in seq :
+                    word, eff = val[1]
+                    if word not in self.cate.cate['CATE'][self.GetItemData(index)[0]][1] :
+                        self.cate.changewordcate(self.GetItemData(index)[0], word, eff)
+                        self.parent.butsave.SetBackgroundColour((255,0,0,255))
+            else :
+                index = self.GetItemCount()
+                if self.cate.addcatefromwordcate(word, eff) :
+                    self.parent.butsave.SetBackgroundColour((255,0,0,255))
+                else :
+                    dial = wx.MessageDialog(self, "This category name is already used", style=wx.OK|wx.CENTRE).ShowModal()
+                #self.cate.addwordincate(self.GetItemData(index)[0], word, eff)
+            self.dlist = self.cate.getcate()
+            self.RefreshData(self.dlist)
+            self.parent.m_listToCate.RefreshData(self.cate.getwordstocate())
+            #self.parent.m_listCateWords.RefreshData(self.parent.cate.getcatewords(self.GetItemData(index)[0]))
+            self.parent.m_listCateWords.RefreshData(self.parent.cate.getcatewords(self.GetItemData(self.currentItem)[0]))
+            #self.SetSelection(index)
+
+
+
+#        for i in seq: # Insert the item data.
+#            idx = self.InsertItem(index, i[2])
+#            self.SetItemData(idx, i[1])
+#            for j in range(1, self.GetColumnCount()):
+#                try: # Target list can have more columns than source.
+#                    self.SetItem(idx, j, i[2+j])
+#                except:
+#                    pass # Ignore the extra columns.
+#            index += 1
+
+class ListForWords(ListForCate) :
+    def __init__(self, parent, dlist = {}, first = []):
+        wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
+        self.parent=parent
+        self.cate = self.parent.cate
+        self.dlist= self.cate.getwordstocate()
+        self.first = first
+        self.il = wx.ImageList(16, 16)
+        a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION"}
+        for k,v in list(a.items()):
+            s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
+            exec(s)
+        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+        self.attr1 = wx.ListItemAttr()
+        self.attr1.SetBackgroundColour((230, 230, 230))
+        self.attr2 = wx.ListItemAttr()
+        self.attr2.SetBackgroundColour("light blue")
+        #self.attrselected = wx.ListItemAttr()
+        #self.attrselected.SetBackgroundColour("red")
+        self.SetListFont()
+        self.selected = {}
+        i = 0
+        for name in ['To categorize'] + self.first :
+            self.InsertColumn(i,name,wx.LIST_FORMAT_LEFT)
+            i += 1
+        self.itemDataMap = self.dlist
+        self.itemIndexMap = list(self.dlist.keys())
+        self.SetItemCount(len(self.dlist))
+        listmix.ListCtrlAutoWidthMixin.__init__(self)
+        listmix.ColumnSorterMixin.__init__(self, len(self.first) + 1)
+        self.SetColumnWidth(0, 400)
+        self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+
+        self.SortListItems(1, False)
+
+        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
+        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnDClick)
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
+
+        dt = MyListDropCate(self)
+        self.SetDropTarget(dt)
+
+    def OnDClick(self, event) :
+        idx = event.GetIndex()
+        event.Skip()
+
+    def OnItemSelected(self, event):
+        self.currentItem = event.GetIndex() #event.m_itemIndex
+        event.Skip()
+
+    def OnGetItemImage(self, item):
+        return self.i_idx
+
+    def GetItemInfo(self, idx):
+        """
+        Collect all relevant data of a listitem, and put it in a list.
+        """
+
+        l = []
+        l.append(idx) # We need the original index, so it is easier to eventualy delete it.
+        l.append(self.GetItemData(idx)) # Itemdata.
+        l.append(self.GetItemText(idx)) # Text first column.
+        for i in range(1, self.GetColumnCount()): # Possible extra columns.
+            l.append(self.GetItem(idx, i).GetText())
+        l.append('words')
+        return l
+
+
+    def StartDrag(self, event):
+        """
+        Put together a data object for drag-and-drop _from_ this list.
+        """
+
+        l = []
+        idx = -1
+        while True: # Find all the selected items and put them in a list.
+            idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
+            if idx == -1:
+                break
+            l.append(self.GetItemInfo(idx))
+
+        # Pickle the items list.
+        itemdata = pickle.dumps(l, 1)
+        # Create our own data format and use it
+        # in a Custom data object.
+        ldata = wx.CustomDataObject("ListCtrlItems")
+        ldata.SetData(itemdata)
+        # Now make a data object for the  item list.
+        data = wx.DataObjectComposite()
+        data.Add(ldata)
+
+        # Create drop source and begin drag-and-drop.
+        dropSource = wx.DropSource(self)
+        dropSource.SetData(data)
+        res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
+
+
+        # If move, we want to remove the item from this list.
+        if res == wx.DragMove and l[0][-1] != 'words':
+            # It's possible we are dragging/dropping from this list to this list.
+            # In which case, the index we are removing may have changed...
+
+            # Find correct position.
+            l.reverse() # Delete all the items, starting with the last item.
+            for i in l:
+                pos = self.FindItem(i[0], i[2])
+                print('detruit : ',pos)
+                self.DeleteItem(pos)
+
+
+    def Insert(self, x, y, seq):
+        """
+        Insert text at given x, y coordinates --- used with drag-and-drop.
+        """
+
+        # Find insertion point.
+        index, flags = self.HitTest((x, y))
+
+        if index == wx.NOT_FOUND: # Not clicked on an item.
+            if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
+                index = self.GetItemCount() # Append to end of list.
+            elif self.GetItemCount() > 0:
+                if y <= self.GetItemRect(0).y: # Clicked just above first item.
+                    index = 0 # Append to top of list.
+                else:
+                    index = self.GetItemCount() + 1 # Append to end of list.
+        else: # Clicked on an item.
+            # Get bounding rectangle for the item the user is dropping over.
+            rect = self.GetItemRect(index)
+
+            # If the user is dropping into the lower half of the rect,
+            # we want to insert _after_ this item.
+            # Correct for the fact that there may be a heading involved.
+            if y > rect.y - self.GetItemRect(0).y + rect.height/2:
+                index += 1
+        word, eff = seq[0][1]
+        if seq[0][-1] == 'catewords' :
+            for val in seq :
+                word, eff = val[1]
+                categorie = self.cate.findcatefromword(word)
+                self.cate.addwordinwords(categorie, word, eff)
+            self.RefreshData(self.cate.getwordstocate())
+            self.parent.m_listCate.RefreshData(self.cate.getcate())
+            self.parent.m_listCateWords.RefreshData(self.cate.getcatewords(categorie))
+            self.parent.butsave.SetBackgroundColour((255,0,0,255))
+        elif seq[0][-1] == 'cate' :
+            categorie = seq[0][1][0]
+            self.cate.delcate(categorie)
+            self.RefreshData(self.cate.getwordstocate())
+            self.parent.m_listCate.RefreshData(self.cate.getcate())
+            self.parent.m_listCate.SetSelection(0)
+            self.parent.m_listCateWords.RefreshData(self.cate.getcatewords(self.parent.m_listCate.GetItemText(0)))
+            self.parent.butsave.SetBackgroundColour((255,0,0,255))
+
+
+class ListForCateWords(ListForCate) :
+    def __init__(self, parent, dlist = {}, first = []):
+        wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
+        self.parent=parent
+        self.cate = self.parent.cate
+        self.dlist= {}
+        self.first = first
+        self.il = wx.ImageList(16, 16)
+        a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","p_idx":"TIP","e_idx":"ERROR","i_idx":"QUESTION"}
+        for k,v in list(a.items()):
+            s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
+            exec(s)
+        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+        self.attr1 = wx.ListItemAttr()
+        self.attr1.SetBackgroundColour((230, 230, 230))
+        self.attr2 = wx.ListItemAttr()
+        self.attr2.SetBackgroundColour("light blue")
+        #self.attrselected = wx.ListItemAttr()
+        #self.attrselected.SetBackgroundColour("red")
+        self.SetListFont()
+        self.selected = {}
+        i = 0
+        for name in ['Contents'] + self.first :
+            self.InsertColumn(i,name,wx.LIST_FORMAT_LEFT)
+            i += 1
+        self.itemDataMap = self.dlist
+        self.itemIndexMap = list(self.dlist.keys())
+        self.SetItemCount(len(self.dlist))
+        listmix.ListCtrlAutoWidthMixin.__init__(self)
+        listmix.ColumnSorterMixin.__init__(self, len(self.first) + 1)
+        self.SetColumnWidth(0, 300)
+        self.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+
+        self.SortListItems(1, False)
+
+        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
+
+        dt = MyListDropCate(self)
+        self.SetDropTarget(dt)
+
+    def OnItemSelected(self, event):
+        self.currentItem = event.GetIndex() #event.m_itemIndex
+        event.Skip()
+
+
+    def GetItemInfo(self, idx):
+        """
+        Collect all relevant data of a listitem, and put it in a list.
+        """
+
+        l = []
+        l.append(idx) # We need the original index, so it is easier to eventualy delete it.
+        l.append(self.GetItemData(idx)) # Itemdata.
+        l.append(self.GetItemText(idx)) # Text first column.
+        for i in range(1, self.GetColumnCount()): # Possible extra columns.
+            l.append(self.GetItem(idx, i).GetText())
+        l.append('catewords')
+        return l
+
+
+    def StartDrag(self, event):
+        """
+        Put together a data object for drag-and-drop _from_ this list.
+        """
+
+        l = []
+        idx = -1
+        while True: # Find all the selected items and put them in a list.
+            idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
+            if idx == -1:
+                break
+            l.append(self.GetItemInfo(idx))
+
+        # Pickle the items list.
+        itemdata = pickle.dumps(l, 1)
+        # Create our own data format and use it
+        # in a Custom data object.
+        ldata = wx.CustomDataObject("ListCtrlItems")
+        ldata.SetData(itemdata)
+        # Now make a data object for the  item list.
+        data = wx.DataObjectComposite()
+        data.Add(ldata)
+
+        # Create drop source and begin drag-and-drop.
+        dropSource = wx.DropSource(self)
+        dropSource.SetData(data)
+        res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
+        print('current')
+        print(self.parent.m_listCate.currentItem)
+
+        # If move, we want to remove the item from this list.
+        #if res == wx.DragMove:
+        #    # It's possible we are dragging/dropping from this list to this list.
+        #    # In which case, the index we are removing may have changed...
+
+        #    # Find correct position.
+        #    l.reverse() # Delete all the items, starting with the last item.
+        #    for i in l:
+        #        pos = self.FindItem(i[0], i[2])
+        #        self.DeleteItem(pos)
+
+
+    def Insert(self, x, y, seq):
+        """
+        Insert text at given x, y coordinates --- used with drag-and-drop.
+        """
+        pass
+        # Find insertion point.
+        index, flags = self.HitTest((x, y))
+#
+#        if index == wx.NOT_FOUND: # Not clicked on an item.
+#            if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
+#                index = self.GetItemCount() # Append to end of list.
+#            elif self.GetItemCount() > 0:
+#                if y <= self.GetItemRect(0).y: # Clicked just above first item.
+#                    index = 0 # Append to top of list.
+#                else:
+#                    index = self.GetItemCount() + 1 # Append to end of list.
+#        else: # Clicked on an item.
+#            # Get bounding rectangle for the item the user is dropping over.
+#            rect = self.GetItemRect(index)
+#
+#            # If the user is dropping into the lower half of the rect,
+#            # we want to insert _after_ this item.
+#            # Correct for the fact that there may be a heading involved.
+#            if y > rect.y - self.GetItemRect(0).y + rect.height/2:
+#                index += 1
+        print('Insert de ListForCateWords', index,flags)
+        if seq[0][-1] == 'words' :
+            for val in seq :
+                word, eff = val[1]
+                categorie = self.parent.m_listCate.getColumnText(self.parent.m_listCate.GetFirstSelected(),0)
+                self.cate.addwordincate(categorie, word, eff)
+            self.dlist = self.cate.getwordstocate()
+            self.RefreshData(self.cate.getcatewords(categorie))
+            self.parent.m_listCate.RefreshData(self.cate.getcate())
+            self.parent.m_listToCate.RefreshData(self.dlist)
+            self.parent.butsave.SetBackgroundColour((255,0,0,255))
+
+
+class MyListDropCate(wx.DropTarget):
+    """
+    Drop target for simple lists.
+    """
+    def __init__(self, source):
+        """
+        Arguments:
+        source: source listctrl.
+        """
+        wx.DropTarget.__init__(self)
+
+        #------------
+
+        self.dv = source
+
+        #------------
+
+        # Specify the type of data we will accept.
+        self.data = wx.CustomDataObject("ListCtrlItems")
+        self.SetDataObject(self.data)
+
+    #-----------------------------------------------------------------------
+
+    # Called when OnDrop returns True.
+    # We need to get the data and do something with it.
+    def OnData(self, x, y, d):
+        """
+        ...
+        """
+
+        # Copy the data from the drag source to our data object.
+        if self.GetData():
+            # Convert it back to a list and give it to the viewer.
+            ldata = self.data.GetData()
+            l = pickle.loads(ldata)
+            self.dv.Insert(x, y, l)
+
+        # What is returned signals the source what to do
+        # with the original data (move, copy, etc.)  In this
+        # case we just return the suggested value given to us.
+        return d
index a18fbc5..da8fbae 100755 (executable)
@@ -117,7 +117,9 @@ class History :
         self.read()
 
     def read(self) :
         self.read()
 
     def read(self) :
-        d = shelve.open(self.filein)
+        with open(self.filein, 'r') as fjson :
+            d = json.load(fjson)
+#        d = shelve.open(self.filein, protocol=1)
         self.history = d.get('history', [])
         self.matrix = d.get('matrix', [])
         self.ordercorpus = dict([[corpus['uuid'], i] for i, corpus in enumerate(self.history)])
         self.history = d.get('history', [])
         self.matrix = d.get('matrix', [])
         self.ordercorpus = dict([[corpus['uuid'], i] for i, corpus in enumerate(self.history)])
@@ -125,13 +127,16 @@ class History :
         self.analyses = dict([[analyse['uuid'], analyse] for corpus in self.history for analyse in corpus.get('analyses', [])])
         self.matrixanalyse = dict([[mat['uuid'], mat] for mat in self.matrix])
         self.ordermatrix = dict([[matrix['uuid'], i] for i, matrix in enumerate(self.matrix)])
         self.analyses = dict([[analyse['uuid'], analyse] for corpus in self.history for analyse in corpus.get('analyses', [])])
         self.matrixanalyse = dict([[mat['uuid'], mat] for mat in self.matrix])
         self.ordermatrix = dict([[matrix['uuid'], i] for i, matrix in enumerate(self.matrix)])
-        d.close()
+#        d.close()
 
     def write(self) :
 
     def write(self) :
-        d = shelve.open(self.filein)
+        d = {}
         d['history'] = self.history
         d['matrix'] = self.matrix
         d['history'] = self.history
         d['matrix'] = self.matrix
-        d.close()
+        with open(self.filein, 'w') as f :
+            f.write(json.dumps(d, indent=4, default=str))
+       #d = shelve.open(self.filein, protocol=1)
+       #d.close()
 
     def add(self, analyse) :
         log.info('add to history %s' % analyse.get('corpus_name', 'pas un corpus'))
 
     def add(self, analyse) :
         log.info('add to history %s' % analyse.get('corpus_name', 'pas un corpus'))
index 2938c88..2bec72a 100755 (executable)
@@ -56,6 +56,7 @@ from tabfrequence import Frequences, FreqMultiple
 from tableau import Tableau
 from tabrsimple import InputText
 from tabsimi import DoSimi
 from tableau import Tableau
 from tabrsimple import InputText
 from tabsimi import DoSimi
+from tabcatego import Categorisation
 from tabsplitvar import SplitMatrixFromVar
 from tabverges import Prototypical
 from textaslexico import Lexico
 from tabsplitvar import SplitMatrixFromVar
 from tabverges import Prototypical
 from textaslexico import Lexico
@@ -93,6 +94,7 @@ ID_CHECKCORPUS = wx.Window.NewControlId()
 ID_Tabcontent = wx.Window.NewControlId()
 ID_AFCM = wx.Window.NewControlId()
 ID_SIMI = wx.Window.NewControlId()
 ID_Tabcontent = wx.Window.NewControlId()
 ID_AFCM = wx.Window.NewControlId()
 ID_SIMI = wx.Window.NewControlId()
+ID_CATE = wx.Window.NewControlId()
 ID_CloseTab = wx.Window.NewControlId()
 ID_SaveTab = wx.Window.NewControlId()
 ID_CreateText = wx.Window.NewControlId()
 ID_CloseTab = wx.Window.NewControlId()
 ID_SaveTab = wx.Window.NewControlId()
 ID_CreateText = wx.Window.NewControlId()
@@ -217,7 +219,8 @@ images_analyses = {
         'preferences' : 'preferences.png',
         'exportmetatable' : 'exportmetatable.png',
         'importdmi' : 'twitter.png',
         'preferences' : 'preferences.png',
         'exportmetatable' : 'exportmetatable.png',
         'importdmi' : 'twitter.png',
-        'labbe' : 'spec.png'
+        'labbe' : 'spec.png',
+        'categorisation' : 'spec.png',
          }
 
 
          }
 
 
@@ -236,6 +239,8 @@ class IraFrame(wx.Frame):
         log.info('Starting Iramuteq... ' )
         log.info('version : %s' % ConfigGlob.get('DEFAULT', 'version'))
         wx.Frame.__init__(self, parent, id, title, pos, size, style)
         log.info('Starting Iramuteq... ' )
         log.info('version : %s' % ConfigGlob.get('DEFAULT', 'version'))
         wx.Frame.__init__(self, parent, id, title, pos, size, style)
+        #Font
+        self.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
         # configuration
         self.AppliPath = AppliPath
         self.images_path = os.path.join(AppliPath,'images')
         # configuration
         self.AppliPath = AppliPath
         self.images_path = os.path.join(AppliPath,'images')
@@ -351,6 +356,7 @@ class IraFrame(wx.Frame):
                        [ID_SIMI, _("Similarities Analysis"), 'simimatrix'],
                        [ID_proto, _("Prototypical Analysis"), 'proto'],
                        [ID_Splitfromvar, _("Split from variable"), 'subcorpusmeta'],
                        [ID_SIMI, _("Similarities Analysis"), 'simimatrix'],
                        [ID_proto, _("Prototypical Analysis"), 'proto'],
                        [ID_Splitfromvar, _("Split from variable"), 'subcorpusmeta'],
+                       [ID_CATE, _("ElCaTeGoRiZatoR"), 'categorisation'],
                       ]
         for analyse in matanalyses :
             if not isinstance(analyse, dict) :
                       ]
         for analyse in matanalyses :
             if not isinstance(analyse, dict) :
@@ -488,10 +494,10 @@ class IraFrame(wx.Frame):
         #------------------------------------------------------------------------------------------------
         # fichier d'historique de Iramuteq
         #------------------------------------------------------------------------------------------------
         #------------------------------------------------------------------------------------------------
         # fichier d'historique de Iramuteq
         #------------------------------------------------------------------------------------------------
-        #if not os.path.exists(os.path.join(UserConfigPath, 'history.db')) :
-        #    with open(os.path.join(UserConfigPath, 'history.db'), 'w') as f :
-        #        f.write('')
-        self.history = History(os.path.join(UserConfigPath, 'historyIramuteq'))
+        if not os.path.exists(os.path.join(UserConfigPath, 'history.db')) :
+            with open(os.path.join(UserConfigPath, 'history.db'), 'w') as f :
+                f.write('{}')
+        self.history = History(os.path.join(UserConfigPath, 'history.db'))
         # l'extension ".db" est ajoutée automatiquement par le module
 
         #------------------------------------------------------------------------------------------------
         # l'extension ".db" est ajoutée automatiquement par le module
 
         #------------------------------------------------------------------------------------------------
@@ -504,7 +510,7 @@ class IraFrame(wx.Frame):
             Name("lefttree").
             Caption(_("Historic")).
             Left().
             Name("lefttree").
             Caption(_("Historic")).
             Left().
-            MinSize(wx.Size(200,500)).
+            MinSize(wx.Size(300,400)).
             Layer(1).
             Position(1).
             CloseButton(False).
             Layer(1).
             Position(1).
             CloseButton(False).
@@ -602,6 +608,7 @@ class IraFrame(wx.Frame):
         self.Bind(wx.EVT_MENU, self.OnAFCM, id=ID_AFCM)
         self.Bind(wx.EVT_MENU, self.OnProto, id=ID_proto)
         self.Bind(wx.EVT_MENU, self.OnSplitVar, id = ID_Splitfromvar)
         self.Bind(wx.EVT_MENU, self.OnAFCM, id=ID_AFCM)
         self.Bind(wx.EVT_MENU, self.OnProto, id=ID_proto)
         self.Bind(wx.EVT_MENU, self.OnSplitVar, id = ID_Splitfromvar)
+        self.Bind(wx.EVT_MENU, self.OnCategorisation, id = ID_CATE)
         #self.Bind(wx.EVT_MENU, self.OnRCode, id=ID_RCODE) #???
         #self.Bind(wx.EVT_MENU, self.OnSplitVar, id=ID_SPLITVAR) #???
         #self.Bind(wx.EVT_MENU, self.OnCheckcorpus, id = ID_CHECKCORPUS) #???
         #self.Bind(wx.EVT_MENU, self.OnRCode, id=ID_RCODE) #???
         #self.Bind(wx.EVT_MENU, self.OnSplitVar, id=ID_SPLITVAR) #???
         #self.Bind(wx.EVT_MENU, self.OnCheckcorpus, id = ID_CHECKCORPUS) #???
@@ -1007,6 +1014,10 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, États-Unis."""
     def OnSimiTab(self, event, matrix = None):
         self.analyse_matrix(DoSimi, matrix = matrix, analyse_type = 'simimatrix', dlgnb = 5)
 
     def OnSimiTab(self, event, matrix = None):
         self.analyse_matrix(DoSimi, matrix = matrix, analyse_type = 'simimatrix', dlgnb = 5)
 
+    def OnCategorisation(self, event, matrix = None) :
+        self.analyse_matrix(Categorisation, matrix = matrix, analyse_type = 'categorisation', dlgnb = 1)
+
+
     def OnCHDReinert(self, event, matrix = None):
         #if matrix is None :
         #    matrix = self.tree.getmatrix()
     def OnCHDReinert(self, event, matrix = None):
         #if matrix is None :
         #    matrix = self.tree.getmatrix()
index 5fd493c..19a53af 100644 (file)
--- a/layout.py
+++ b/layout.py
@@ -38,6 +38,7 @@ from PrintRScript import write_afc_graph, print_simi3d, PrintSimiScript
 from profile_segment import ProfileSegment
 from listlex import *
 from Liste import *
 from profile_segment import ProfileSegment
 from listlex import *
 from Liste import *
+from elcategorizator import ElCategorizator
 from search_tools import SearchFrame
 from dialog import PrefGraph, PrefExport, PrefSimpleFile, PrefDendro, SimpleDialog, ImageViewer
 from guifunct import SelectColumn, PrepSimi, PrefSimi, redosimi
 from search_tools import SearchFrame
 from dialog import PrefGraph, PrefExport, PrefSimpleFile, PrefDendro, SimpleDialog, ImageViewer
 from guifunct import SelectColumn, PrepSimi, PrefSimi, redosimi
@@ -1397,6 +1398,11 @@ class ProtoLayout(DefaultMatLayout) :
         #self.ira.nb.SetSelection(self.ira.nb.GetPageCount() - 1)
         #self.ira.ShowAPane("Tab_content")
 
         #self.ira.nb.SetSelection(self.ira.nb.GetPageCount() - 1)
         #self.ira.ShowAPane("Tab_content")
 
+class CateLayout(DefaultMatLayout) :
+
+    def dolayout(self) :
+        TabCate = ElCategorizator(self.ira.nb, self.pathout, self.tableau)
+        self.ira.nb.AddPage(TabCate, ' - '.join([_('ElCaTeGoRiZaToR'), self.parametres['name']]))
 
 class SimiMatLayout(DefaultMatLayout) :
 
 
 class SimiMatLayout(DefaultMatLayout) :
 
index e894bee..873f4b3 100644 (file)
@@ -14,7 +14,7 @@ import logging
 # import des fichiers du projet
 #------------------------------------
 from chemins import ChdTxtPathOut, StatTxtPathOut, PathOut
 # import des fichiers du projet
 #------------------------------------
 from chemins import ChdTxtPathOut, StatTxtPathOut, PathOut
-from layout import OpenCHDS, dolexlayout, StatLayout, WordCloudLayout, OpenCorpus, SimiLayout, SimiMatLayout, ProtoLayout, MatLayout, FreqLayout, Chi2Layout, LabbeLayout
+from layout import OpenCHDS, dolexlayout, StatLayout, WordCloudLayout, OpenCorpus, SimiLayout, SimiMatLayout, ProtoLayout, MatLayout, FreqLayout, Chi2Layout, LabbeLayout, CateLayout
 from corpus import Corpus, copycorpus
 from tableau import Tableau
 from functions import DoConf, ReadDicoAsDico
 from corpus import Corpus, copycorpus
 from tableau import Tableau
 from functions import DoConf, ReadDicoAsDico
@@ -181,3 +181,6 @@ class OpenAnalyse():
             FreqLayout(self.parent, corpus, self.conf)
         elif self.conf['type'] == 'chi2' or self.conf['type'] == 'chi2mcnemar':
             Chi2Layout(self.parent, corpus, self.conf)
             FreqLayout(self.parent, corpus, self.conf)
         elif self.conf['type'] == 'chi2' or self.conf['type'] == 'chi2mcnemar':
             Chi2Layout(self.parent, corpus, self.conf)
+        elif self.conf['type'] == 'categorisation' :
+            CateLayout(self.parent, corpus, self.conf)
+            print(self.conf)
index 032b395..7325279 100644 (file)
@@ -173,7 +173,6 @@ class Tableau() :
             self.read_ods()
         self.parametres['csvfile'] = os.path.join(self.parametres['pathout'], 'csvfile.csv')
         self.make_tmpfile()
             self.read_ods()
         self.parametres['csvfile'] = os.path.join(self.parametres['pathout'], 'csvfile.csv')
         self.make_tmpfile()
-        print(self.parametres)
         DoConf().makeoptions(['matrix'],[self.parametres], self.parametres['ira'])
         self.parent.history.addMatrix(self.parametres)
 
         DoConf().makeoptions(['matrix'],[self.parametres], self.parametres['ira'])
         self.parent.history.addMatrix(self.parametres)
 
@@ -181,7 +180,7 @@ class Tableau() :
         self.parametres['csvfile'] = os.path.join(self.parametres['pathout'], 'csvfile.csv')
         self.make_tmpfile()
         DoConf().makeoptions(['matrix'],[self.parametres], self.parametres['ira'])
         self.parametres['csvfile'] = os.path.join(self.parametres['pathout'], 'csvfile.csv')
         self.make_tmpfile()
         DoConf().makeoptions(['matrix'],[self.parametres], self.parametres['ira'])
-        self.parent.history.addMatrix(self.parametres)        
+        self.parent.history.addMatrix(self.parametres)
 
     def read_xls(self) :
         #FIXME : encodage
 
     def read_xls(self) :
         #FIXME : encodage
@@ -207,7 +206,7 @@ class Tableau() :
 
     def read_csv(self) :
         with codecs.open(self.parametres['originalpath'], 'r', self.parametres['encodage']) as f :
 
     def read_csv(self) :
         with codecs.open(self.parametres['originalpath'], 'r', self.parametres['encodage']) as f :
-            content = f.read() 
+            content = f.read()
         self.linecontent = [line.split(self.parametres['colsep']) for line in content.splitlines()]
         self.linecontent = [[val.replace('"','').replace(';',' ').replace('\t', ' ').strip() for val in line] for line in self.linecontent]
 
         self.linecontent = [line.split(self.parametres['colsep']) for line in content.splitlines()]
         self.linecontent = [[val.replace('"','').replace(';',' ').replace('\t', ' ').strip() for val in line] for line in self.linecontent]
 
@@ -234,7 +233,7 @@ class Tableau() :
         else :
             self.rownames = [repr(i) for i in range(self.rownb)]
             self.idname = 'identifiant'
         else :
             self.rownames = [repr(i) for i in range(self.rownb)]
             self.idname = 'identifiant'
-        self.csvtable = [[self.idname] + self.colnames] + [[self.rownames[i]] + self.linecontent[i] for i in range(len(self.rownames))] 
+        self.csvtable = [[self.idname] + self.colnames] + [[self.rownames[i]] + self.linecontent[i] for i in range(len(self.rownames))]
         self.write_csvfile()
 
     def read_csvfile(self):
         self.write_csvfile()
 
     def read_csvfile(self):
@@ -287,10 +286,9 @@ class Tableau() :
     def getactlistfromselection(self, listact) :
         selcol = self.select_col(listact)
         self.actives = self.make_dico(selcol)
     def getactlistfromselection(self, listact) :
         selcol = self.select_col(listact)
         self.actives = self.make_dico(selcol)
-        return [[val, self.actives[val][0]] for val in self.actives]       
+        return [[val, self.actives[val][0]] for val in self.actives]
 
     def make_listactives(self) :
 
     def make_listactives(self) :
-        print(self.actives, self.parametres['mineff'])
         self.listactives = [val for val in self.actives if val != 'NA' and self.actives[val][0] >= self.parametres['mineff']]
 
     def write01(self, fileout, dico, linecontent) :
         self.listactives = [val for val in self.actives if val != 'NA' and self.actives[val][0] >= self.parametres['mineff']]
 
     def write01(self, fileout, dico, linecontent) :
@@ -300,7 +298,7 @@ class Tableau() :
         for i, forme in enumerate(self.listactives) :
             for line in dico[forme][1] :
                 out[line][i] = '1'
         for i, forme in enumerate(self.listactives) :
             for line in dico[forme][1] :
                 out[line][i] = '1'
-        #out = [[self.rownames[i]] + out[i] for i in range(len(linecontent))] 
+        #out = [[self.rownames[i]] + out[i] for i in range(len(linecontent))]
         #out.insert(0,[self.idname] + self.listactives)
         out.insert(0, self.listactives)
         with open(fileout, 'w') as f :
         #out.insert(0,[self.idname] + self.listactives)
         out.insert(0, self.listactives)
         with open(fileout, 'w') as f :
@@ -321,7 +319,7 @@ class Tableau() :
                     if forme[0] == '*':
                         UpdateDico(self.sups, forme, i)
                     else:
                     if forme[0] == '*':
                         UpdateDico(self.sups, forme, i)
                     else:
-                        UpdateDico(self.actives, forme, i)        
+                        UpdateDico(self.actives, forme, i)
         self.listactives = [val for val in self.actives if self.actives[val][0] >= self.parametres['mineff']]
         table = [['0' for i in range(len(self.listactives))] for j in range(self.rownb)]
         for i, val in enumerate(self.listactives) :
         self.listactives = [val for val in self.actives if self.actives[val][0] >= self.parametres['mineff']]
         table = [['0' for i in range(len(self.listactives))] for j in range(self.rownb)]
         for i, val in enumerate(self.listactives) :
@@ -378,9 +376,9 @@ class Tableau() :
                         if sup in self.linecontent[uce]:
                             line[i + 1] += 1
             tablecontet.append([line[0]] + [repr(don) for don in line if type(don) == type(1)])
                         if sup in self.linecontent[uce]:
                             line[i + 1] += 1
             tablecontet.append([line[0]] + [repr(don) for don in line if type(don) == type(1)])
-            
+
         self.printtable(self.pathout['ContEtOut'], tablecontet)
         self.printtable(self.pathout['ContEtOut'], tablecontet)
-        self.printtable(self.pathout['Contout'], tablecont)        
+        self.printtable(self.pathout['Contout'], tablecont)
 
     def get_colnames(self) :
         return self.colnames[:]
 
     def get_colnames(self) :
         return self.colnames[:]