...
[iramuteq] / iramuteq.py
1 #!/bin/env python
2 # -*- coding: utf-8 -*-
3 #Author: Pierre Ratinaud
4 #Copyright (c) 2008-2012, Pierre Ratinaud
5 #License: GNU GPL
6
7 from optparse import OptionParser
8
9 parser = OptionParser()
10 parser.add_option("-f", "--file", dest="filename",
11                   help="open FILE", metavar="FILE", default=False)
12 (options, args) = parser.parse_args()
13
14 import sys
15 reload(sys)
16 import locale
17 import tempfile
18 import codecs
19 import os
20 from random import randint
21 from ConfigParser import ConfigParser, RawConfigParser
22 import webbrowser
23 import gettext
24 import logging
25 #------------------------------------
26 import wx
27 import wx.lib.agw.aui as aui
28 import wx.html
29 import wx.grid
30 import wx.lib.hyperlink as hl
31 #------------------------------------
32 from functions import BugReport, PlaySound, History, progressbar
33 from checkversion import NewVersion
34 from guifunct import *
35 from tableau import Tableau
36 from dialog import PrefDialog
37 from tabfrequence import Frequences, FreqMultiple
38 from tabchi2 import ChiSquare
39 #from tabstudent import MakeStudent
40 from tabchddist import ChdCluster
41 from tabafcm import DoAFCM
42 from tabchdalc import AnalyseQuest
43 from tabsimi import DoSimi
44 from tabrsimple import InputText
45 from tabverges import Prototypical
46 from tabsplitvar import SplitMatrixFromVar
47 #from textdist import AnalysePam
48 from textstat import Stat
49 from textaslexico import Lexico
50 from textsimi import SimiTxt, SimiFromCluster
51 from textwordcloud import WordCloud, ClusterCloud
52 from textreinert import Reinert
53 #from textcheckcorpus import checkcorpus
54 from openanalyse import OpenAnalyse
55 from corpus import Builder, SubBuilder
56 from checkinstall import CreateIraDirectory, CheckRPath, FindRPAthWin32, FindRPathNix, CheckRPackages, IsNew, UpgradeConf, CopyConf, RLibsAreInstalled
57 from chemins import RscriptsPath, ConstructConfigPath, ConstructDicoPath, ConstructGlobalPath, PathOut
58 from parse_factiva_xml import ImportFactiva
59 from parse_dmi import ImportDMI
60 from tools import Extract
61
62 from tree import LeftTree
63 ##########################################################
64 ID_OpenData = wx.NewId()
65 ID_Import = wx.NewId()
66 ID_OpenText = wx.NewId()
67 ID_OnOpenAnalyse = wx.NewId()
68 ID_Freq = wx.NewId()
69 ID_Chi2 = wx.NewId()
70 ID_Student = wx.NewId()
71 ID_CHDSIM = wx.NewId()
72 ID_CHDReinert = wx.NewId()
73 ID_TEXTAFCM = wx.NewId()
74 ID_TEXTSTAT = wx.NewId()
75 ID_ASLEX = wx.NewId()
76 ID_TEXTREINERT = wx.NewId()
77 ID_TEXTPAM = wx.NewId()
78 ID_CHECKCORPUS = wx.NewId()
79 ID_Tabcontent = wx.NewId()
80 ID_AFCM = wx.NewId()
81 ID_SIMI = wx.NewId()
82 ID_CloseTab = wx.NewId()
83 ID_SaveTab = wx.NewId()
84 ID_CreateText = wx.NewId()
85 ID_ACCEUIL = wx.NewId()
86 ID_RESULT = wx.NewId()
87 ID_HTMLcontent = wx.NewId()
88 ID_SimiTxt = wx.NewId()
89 ID_proto = wx.NewId()
90 ID_ImportTXM = wx.NewId()
91 ID_FreqMulti = wx.NewId()
92 ID_Splitfromvar = wx.NewId()
93 ID_Subtxtfrommeta = wx.NewId()
94 ID_Subtxtfromthem = wx.NewId()
95 ID_WC = wx.NewId()
96 ID_ImportEuro = wx.NewId()
97 ID_Fact_xml = wx.NewId()
98 ID_Fact_mail = wx.NewId()
99 ID_Fact_copy = wx.NewId()
100 ID_exportmeta = wx.NewId()
101 ID_importdmi = wx.NewId()
102 ##########################################################
103 #elements de configuration
104 ##########################################################
105 #encodage
106 if sys.platform == 'darwin' :
107     sys.setdefaultencoding('UTF-8')
108     wx.SetDefaultPyEncoding('UTF-8')
109 else :
110     sys.setdefaultencoding(locale.getpreferredencoding())
111
112 #chemin de l'application
113 AppliPath = os.path.abspath(os.path.dirname(os.path.realpath(sys.argv[0])))
114 #chemin des images
115 ImagePath = os.path.join(AppliPath, 'images')
116 #configuration generale
117 DictConfigPath = ConstructGlobalPath(AppliPath)
118 ConfigGlob = ConfigParser()
119 ConfigGlob.read(DictConfigPath['global'])
120 DefaultConf = ConfigParser()
121 DefaultConf.read(DictConfigPath['preferences'])
122 #repertoire de l'utilisateur
123 if os.getenv('HOME') != None:
124     user_home = os.getenv('HOME')
125 else:
126     user_home = os.getenv('HOMEPATH')
127 UserConfigPath = os.path.abspath(os.path.join(user_home, '.iramuteq'))
128 #Si pas de fichiers de config utilisateur, on cree le repertoire
129 CreateIraDirectory(UserConfigPath, AppliPath)
130 #fichiers log pour windows (py2exe)
131 log = logging.getLogger('iramuteq')
132 fh = logging.FileHandler(os.path.join(UserConfigPath,'stdout.log'))
133 formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
134 fh.setFormatter(formatter)
135 log.addHandler(fh)
136 if sys.platform != 'win32' and sys.platform != 'darwin':
137     ch = logging.StreamHandler()
138     ch.setFormatter(formatter)
139     log.addHandler(ch)
140 log.setLevel(logging.INFO)
141
142 class writer(object):
143     def write(self, data):
144         if data.strip() != '' :
145             log.info('ERROR : %s' % data)
146
147 class printer(object) :
148     def write(self, data) :
149         if data.strip() != '' :
150             log.info('Print : %s' % data)
151
152 sys.stderr = writer()
153 sys.stdout = printer()
154
155 ConfigPath = ConstructConfigPath(UserConfigPath)
156
157 langues = {'french' : wx.LANGUAGE_FRENCH,
158            'english' : wx.LANGUAGE_ENGLISH,
159            'portuguese' : wx.LANGUAGE_PORTUGUESE,
160            'italian' : wx.LANGUAGE_ITALIAN,
161            'spanish' : wx.LANGUAGE_SPANISH
162            }
163
164 code_langues = {'french' : 'fr_FR',
165                 'english' : 'en',
166                 'portuguese' : 'pt_PT',
167                 'italian' : 'it_IT',
168                 'spanish' : 'es_ES'
169                }
170
171 images_analyses = {
172         'textroot' : 'textroot.png',
173         'alceste' : 'reinert.png',
174         'corpus' : 'textcorpus.png',
175         'wordcloud' :'wordcloud.png',
176         'stat' :'stats.png',
177         'simitxt' : 'simitxt.png',
178         'clustersimitxt' :'clustersimitxt.png',
179         'clustercloud' : 'clustercloud.png',
180         'spec' : 'spec.png',
181         'matroot' : 'matroot.png',
182         'matrix' : 'matrix.png',
183         'freq' : 'frequences.png',
184         'freqmulti' : 'frequences.png',
185         'chi2' : 'chi2.png',
186         'reinertmatrix' : 'reinertmatrix.png',
187         'simimatrix' : 'simimatrix.png',
188         'simiclustermatrix' : 'simimatrix.png',
189         'proto' : 'proto.png',
190         'TXM' : 'TXM.png',
191         'europress' : 'europress.png',
192         'factiva_xml' : 'factiva_xml.png',
193         'factiva_copy' : 'factiva_copy.png',
194         'factiva_mail': 'factiva_mail.png',
195         'iramuteq' : 'iraicone.png',
196         'subcorpusmeta' : 'subcorpusmeta.png',
197         'subcorpusthema' : 'subcorpusthema.png',
198         'preferences' : 'preferences.png',
199         'exportmetatable' : 'exportmetatable.png',
200         'importdmi' : 'twitter.png'
201          }
202 #####################################################################
203
204 class IraFrame(wx.Frame):
205     def __init__(self, parent, id= -1, title="", pos=wx.DefaultPosition,
206                  size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE | 
207                                             wx.SUNKEN_BORDER | 
208                                             wx.CLIP_CHILDREN):
209         log.info('Starting...')
210         wx.Frame.__init__(self, parent, id, title, pos, size, style)
211         #configuration
212         self.AppliPath = AppliPath
213         self.images_path = os.path.join(AppliPath,'images')
214         self.UserConfigPath = UserConfigPath
215         #self.RscriptsPath = ConstructRscriptsPath(AppliPath)
216         self.RscriptsPath = PathOut(dirout=os.path.join(AppliPath, 'Rscripts'))
217         self.RscriptsPath.basefiles(RscriptsPath)
218         #self.DictPath = ConstructDicoPath(AppliPath)
219         self.DictPath = ConstructDicoPath(UserConfigPath)
220         self.ConfigGlob = ConfigGlob
221         self.ConfigPath = ConstructConfigPath(UserConfigPath)
222         self.pref = RawConfigParser()
223         #workaround for import problem
224         self.SimiFromCluster = SimiFromCluster
225         #langues
226         gettext.install('iramuteq',  os.path.join(AppliPath,'locale'), unicode=True)
227         #langues = ['fr_FR', 'en', 'pt_PT']
228         #for l in langues :
229         #    pass
230         self.preslangue = {}
231         for langue in code_langues :
232             self.preslangue[langue] = gettext.translation("iramuteq", os.path.join(AppliPath,'locale'), languages=[code_langues[langue]])
233         self.setlangue()
234         #self.presLan_fr = gettext.translation("iramuteq", os.path.join(AppliPath,'locale'), languages=['fr_FR'])
235         #self.presLan_en = gettext.translation("iramuteq", os.path.join(AppliPath,'locale'), languages=['en'])
236         # tell FrameManager to manage this frame        
237         #self._mgr = wx.aui.AuiManager()
238         self._mgr = aui.AuiManager()
239         self._mgr.SetManagedWindow(self)
240         self.x = 0
241         # create menu
242 #--------------------------------------------------------------------------------
243         self.images_analyses = images_analyses
244         for img in images_analyses :
245             self.images_analyses[img] = wx.Image(os.path.join(self.images_path, self.images_analyses[img]), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap()
246         self.mb = wx.MenuBar()
247
248         file_menu = wx.Menu()
249         item = wx.MenuItem(file_menu, ID_OpenData, _(u"Open a matrix").decode('utf8'), _(u"Open a matrix").decode('utf8'))
250         #item.SetBitmap(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN))
251         item.SetBitmap(self.images_analyses['matroot'])
252         file_menu.AppendItem(item)
253         
254         item = wx.MenuItem(file_menu, ID_OpenText, _(u"Open a text corpus").decode('utf8'), _(u"Open a text corpus").decode('utf8'))
255         item.SetBitmap(self.images_analyses['textroot'])
256         file_menu.AppendItem(item)
257         
258         item = wx.MenuItem(file_menu, ID_OnOpenAnalyse, _(u"Open an analysis").decode('utf8'), _(u"Open an analysis").decode('utf8'))
259         item.SetBitmap(self.images_analyses['iramuteq'])
260         file_menu.AppendItem(item)
261
262         item = wx.MenuItem(file_menu, ID_ImportTXM, _(u"Import from TXM").decode('utf8'), _(u"Import from TXM").decode('utf8'))
263         item.SetBitmap(self.images_analyses['TXM'])
264         file_menu.AppendItem(item)
265         
266         item = wx.MenuItem(file_menu, ID_ImportEuro, _(u"Import from Europress").decode('utf8'), _(u"Import from Europress").decode('utf8'))
267         item.SetBitmap(self.images_analyses['europress'])
268         file_menu.AppendItem(item)        
269         
270         item = wx.MenuItem(file_menu, ID_importdmi, _(u"Import from DMI-TCAT (exp.)").decode('utf8'), _(u"Import from DMI-TCAT (exp.)").decode('utf8'))
271         item.SetBitmap(self.images_analyses['importdmi'])
272         file_menu.AppendItem(item)        
273         
274         menuFactiva = wx.Menu()
275         fact_from_xml = wx.MenuItem(menuFactiva, ID_Fact_xml, _(u"from xml").decode('utf8'))
276         fact_from_xml.SetBitmap(self.images_analyses['factiva_xml'])
277         fact_from_mail = wx.MenuItem(menuFactiva, ID_Fact_mail, _(u"from mail").decode('utf8'))
278         fact_from_mail.SetBitmap(self.images_analyses['factiva_mail'])
279         fact_from_txt = wx.MenuItem(menuFactiva, ID_Fact_copy, _(u"from copy/paste").decode('utf8'))
280         fact_from_txt.SetBitmap(self.images_analyses['factiva_copy'])
281         menuFactiva.AppendItem(fact_from_xml)
282         menuFactiva.AppendItem(fact_from_mail)
283         menuFactiva.AppendItem(fact_from_txt)
284         file_menu.AppendMenu(-1, _(u"Import from factiva").decode('utf8'), menuFactiva)
285
286         menuTools = wx.Menu()
287         splitvar = wx.MenuItem(menuTools, wx.ID_ANY, _(u"Split from variable").decode('utf8'))
288         extractmod = wx.MenuItem(menuTools, wx.ID_ANY, _(u"Extract mods").decode('utf8'))
289         extractthem = wx.MenuItem(menuTools, wx.ID_ANY, _(u"Extract thematics").decode('utf8'))
290         menuTools.AppendItem(splitvar)
291         menuTools.AppendItem(extractmod)
292         menuTools.AppendItem(extractthem)
293         self.ID_splitvar = splitvar.GetId()
294         self.ID_extractmod = extractmod.GetId()
295         self.ID_extractthem = extractthem.GetId()
296         file_menu.AppendMenu(-1, _(u"Tools").decode('utf8'), menuTools)
297
298                
299         #item = wx.MenuItem(file_menu, ID_SaveTab, _(u"Save tab as...").decode('utf8'), _(u"Save tab as...").decode('utf8'))
300         #item.SetBitmap(wx.ArtProvider_GetBitmap(wx.ART_FILE_SAVE_AS))
301         #file_menu.AppendItem(item)
302         
303         file_menu.Append(wx.ID_EXIT, _(u"Exit").decode('utf8'))
304         
305         edit_menu = wx.Menu()
306         pref = wx.MenuItem(edit_menu, wx.ID_PREFERENCES, _(u'Preferences').decode('utf8'))
307         pref.SetBitmap(self.images_analyses['preferences'])
308         edit_menu.AppendItem(pref)
309         #edit_menu.Append(wx.ID_PREFERENCES, _(u'Preferences').decode('utf8'))
310         
311         view_menu = wx.Menu()
312         home = wx.MenuItem(view_menu, ID_ACCEUIL, _(u"Home page").decode('utf8'))
313         home.SetBitmap(wx.ArtProvider_GetBitmap(wx.ART_GO_HOME, size = (16,16)))
314         view_menu.AppendItem(home)
315         #view_menu.Append(ID_ACCEUIL, _(u"Home page").decode('utf8'))
316         results = wx.MenuItem(view_menu, ID_RESULT, _(u'Show results').decode('utf8'))
317         results.SetBitmap(wx.ArtProvider_GetBitmap(wx.ART_LIST_VIEW, size = (16,16)))
318         view_menu.AppendItem(results)
319         #view_menu.Append(ID_RESULT, _(u'Show results').decode('utf8'))
320         #view_menu.AppendSeparator()
321         matrix_menu = wx.Menu()
322         matanalyses = [[ID_Freq, _(u"Frequencies").decode('utf8'), 'freq'],
323                        [ID_FreqMulti, _(u"Multiple  Frequencies").decode('utf8'), 'freqmulti'],
324                        [ID_Chi2, _(u"Chi2").decode('utf8'), 'chi2'],
325                        {'name' : _(u"Clustering").decode('utf8'),
326                         'content' : [[ID_CHDReinert, _(u"Reinert's Method").decode('utf8'), 'reinertmatrix']]},
327                        [ID_SIMI, _(u"Similarities Analysis").decode('utf8'), 'simimatrix'],
328                        [ID_proto, _(u"Prototypical Analysis").decode('utf8'), 'proto'],
329                        [ID_Splitfromvar, _(u"Split from variable").decode('utf8'), 'subcorpusmeta'],
330                         ]
331         
332         for analyse in matanalyses :
333             if not isinstance(analyse, dict) :
334                 item = wx.MenuItem(matrix_menu, analyse[0], analyse[1])
335                 item.SetBitmap(self.images_analyses.get(analyse[2], wx.EmptyBitmap(16,16)))
336                 matrix_menu.AppendItem(item)
337             else :
338                 nmenu = wx.Menu()
339                 for subana in analyse['content'] :
340                     item = wx.MenuItem(nmenu, subana[0], subana[1])
341                     item.SetBitmap(self.images_analyses.get(subana[2], wx.EmptyBitmap(16,16)))
342                     nmenu.AppendItem(item)
343                 matrix_menu.AppendMenu(-1, analyse['name'], nmenu)
344         #item = wx.MenuItem(matrix_menu, ID_Freq, _(u"Frequencies").decode('utf8'))
345         #item.SetBitmap(self.images_analyses['freq'])
346         #matrix_menu.AppendItem(item)
347         #matrix_menu.Append(ID_Freq, _(u"Frequencies").decode('utf8'))
348         #item = wx.MenuItem(matrix_menu, ID_Freq, _(u"Multiple  Frequencies").decode('utf8'))
349         #item.SetBitmap(self.images_analyses['freqmulti'])
350         #matrix_menu.Append(ID_FreqMulti, _(u'Multiple frequencies').decode('utf8'))
351         #matrix_menu.AppendItem(item)
352         #matrix_menu.Append(ID_Chi2, _(u"Chi2").decode('utf8'))
353         #matrix_menu.Append(ID_Student, u"t de Student")
354         #menu_classif = wx.Menu()
355         #menu_classif.Append(ID_CHDReinert, _(u"Reinert's Method").decode('utf8'))
356         #menu_classif.Append(ID_CHDSIM, u"Par matrice des distances")
357         #matrix_menu.AppendMenu(-1, _(u"Clustering").decode('utf8'), menu_classif)
358         #matrix_menu.Append(ID_AFCM, u"AFCM")
359         #matrix_menu.Append(ID_SIMI, _(u"Similarities Analysis").decode('utf8'))
360         #matrix_menu.Append(ID_proto, _(u"Prototypical Analysis").decode('utf8'))
361         ID_RCODE = wx.NewId()
362         #matrix_menu.Append(ID_RCODE, u"Code R...") 
363         #menu_splittab = wx.Menu()
364         #ID_SPLITVAR = wx.NewId()
365         #splitvar = wx.MenuItem(menu_splittab, ID_SPLITVAR, _(u"Split from variable").decode('utf8'))
366         #menu_splittab.AppendItem(splitvar)
367         #matrix_menu.AppendMenu(-1, _(u"Split matrix").decode('utf8'), menu_splittab)
368         self.matrix_menu = matrix_menu
369         
370         text_menu = wx.Menu()
371         analyses_text = [[ID_TEXTSTAT, _(u"Statistics").decode('utf8'), 'stat'],
372                          [ID_ASLEX, _(u"Specificities and CA").decode('utf8'), 'spec'],
373                          {'name' : _(u"Clustering").decode('utf8'),
374                           'content' : [[ID_TEXTREINERT, _(u"Reinert's Method").decode('utf8'), 'alceste']]},
375                          [ID_SimiTxt, _(u"Similarities Analysis").decode('utf8'), 'simitxt'],
376                          [ID_WC, _(u"WordCloud").decode('utf8'), 'wordcloud'],
377                          {'name' : _(u"Sub corpus").decode('utf8'),
378                           'content' : [[ID_Subtxtfrommeta, _(u'Sub corpus from metadata').decode('utf8'), 'subcorpusmeta'],
379                                        [ID_Subtxtfromthem, _(u'Sub corpus from thematic').decode('utf8'), 'subcorpusthema']]},
380                          [ID_exportmeta, _(u"Export metadata table").decode('utf8'), 'exportmetatable'],
381                          ]
382         
383         for analyse in analyses_text :
384             if not isinstance(analyse, dict) :
385                 item = wx.MenuItem(text_menu, analyse[0], analyse[1])
386                 item.SetBitmap(self.images_analyses.get(analyse[2], wx.EmptyBitmap(16,16)))
387                 text_menu.AppendItem(item)
388             else :
389                 nmenu = wx.Menu()
390                 for subana in analyse['content'] :
391                     item = wx.MenuItem(nmenu, subana[0], subana[1])
392                     item.SetBitmap(self.images_analyses.get(subana[2], wx.EmptyBitmap(16,16)))
393                     nmenu.AppendItem(item)
394                 text_menu.AppendMenu(-1, analyse['name'], nmenu)
395         #text_menu.Append(ID_CHECKCORPUS, u"Vérifier le corpus")
396 #         text_menu.Append(ID_TEXTSTAT, _(u"Statistics").decode('utf8'))
397 #         text_menu.Append(ID_ASLEX, _(u"Specificities and CA").decode('utf8'))
398 #         #text_menu.Append(ID_TEXTAFCM, u"AFC sur UCI / Vocabulaire")
399 #         menu_classiftxt = wx.Menu()
400 #         menu_classiftxt.Append(ID_TEXTREINERT, _(u"Reinert's Method").decode('utf8'))
401 #         #menu_classiftxt.Append(ID_TEXTPAM, u"Par matrice des distances")
402 #         text_menu.AppendMenu(-1, _(u"Clustering").decode('utf8'), menu_classiftxt)
403 #         text_menu.Append(ID_SimiTxt, _(u"Similarities Analysis").decode('utf8')) 
404 #         
405 #         text_menu.Append(ID_WC, _(u"WordCloud").decode('utf8'))
406         self.text_menu = text_menu
407         
408         help_menu = wx.Menu()
409         about = wx.MenuItem(help_menu, wx.ID_ABOUT, _(u"About...").decode('utf8'))
410         about.SetBitmap(wx.ArtProvider_GetBitmap(wx.ART_INFORMATION, size = (16,16)))
411         help_menu.AppendItem(about)
412         #help_menu.Append(wx.ID_ABOUT, _(u"About...").decode('utf8'))
413         help = wx.MenuItem(help_menu, wx.ID_HELP, _(u"Online help...").decode('utf8'))
414         help.SetBitmap(wx.ArtProvider_GetBitmap(wx.ART_HELP, size = (16,16)))
415         help_menu.AppendItem(help)
416         #help_menu.Append(wx.ID_HELP, _(u"Online help...").decode('utf8'))
417         
418         self.mb.Append(file_menu, _(u"File").decode('utf8'))
419         self.mb.Append(edit_menu, _(u"Edition").decode('utf8'))
420         self.mb.Append(view_menu, _(u"View").decode('utf8'))
421         self.mb.Append(matrix_menu, _(u"Matrix analysis").decode('utf8'))
422         self.mb.Append(text_menu, _(u"Text analysis").decode('utf8'))
423         self.mb.Append(help_menu, _(u"Help").decode('utf8'))
424         
425         self.SetMenuBar(self.mb)
426 #--------------------------------------------------------------------
427         self.statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
428         self.statusbar.SetStatusWidths([-2, -3])
429         self.statusbar.SetStatusText(_(u"Ready").decode('utf8'), 0)
430         self.statusbar.SetStatusText(_(u"Welcome").decode('utf8'), 1)
431
432         # min size for the frame itself isn't completely done.
433         # see the end up FrameManager::Update() for the test
434         # code. For now, just hard code a frame minimum size
435         self.SetMinSize(wx.Size(400, 400))
436
437         # create some toolbars
438         tb1 = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
439                          wx.TB_FLAT | wx.TB_NODIVIDER)
440         tb1.SetToolBitmapSize(wx.Size(16, 16))
441         tb1.AddLabelTool(ID_OpenData, "OpenData", self.images_analyses['matroot'], shortHelp=_(u"Matrix").decode('utf8'), longHelp=_(u"Open a matrix").decode('utf8'))
442         tb1.AddSeparator()
443         tb1.AddLabelTool(ID_OpenText, "OpenText", self.images_analyses['textroot'], shortHelp=_(u"Text").decode('utf8'), longHelp=_(u"Open a text corpus").decode('utf8'))
444         tb1.AddSeparator()
445         tb1.AddLabelTool(ID_OnOpenAnalyse, "OpenAnalyse", self.images_analyses['iramuteq'], shortHelp= _(u"Open an analysis").decode('utf8'), longHelp=_(u"Open an analysis").decode('utf8'))
446         tb1.AddSeparator()
447         tb1.AddLabelTool(ID_ImportTXM, "ImportTXM", self.images_analyses['TXM'], shortHelp= _(u"Import from TXM").decode('utf8'), longHelp=_(u"Import from TXM").decode('utf8'))
448         tb1.AddSeparator()
449         tb1.AddLabelTool(ID_ImportEuro, "ImportEuro", self.images_analyses['europress'], shortHelp= _(u"Import from Europress").decode('utf8'), longHelp=_(u"Import from Europress").decode('utf8'))
450         tb1.AddSeparator()
451         tb1.AddLabelTool(ID_importdmi, "ImportDMI", self.images_analyses['importdmi'], shortHelp= _(u"Import from DMI-TCAT (exp.)").decode('utf8'), longHelp=_(u"Import from DMI-TCAT (exp.)").decode('utf8'))
452         tb1.AddSeparator()        
453         tb1.AddLabelTool(ID_Fact_xml, "ImportFactxml", self.images_analyses['factiva_xml'], shortHelp= _(u"Factiva from xml").decode('utf8'), longHelp=_(u"Factiva from xml").decode('utf8'))
454         tb1.AddLabelTool(ID_Fact_mail, "ImportFactmail", self.images_analyses['factiva_mail'], shortHelp= _(u"Factiva from mail").decode('utf8'), longHelp=_(u"Factiva from mail").decode('utf8'))
455         tb1.AddLabelTool(ID_Fact_copy, "ImportFactcopy", self.images_analyses['factiva_copy'], shortHelp= _(u"Factiva from copy/paste").decode('utf8'), longHelp=_(u"Factiva from copy/paste").decode('utf8'))
456         tb1.AddSeparator()
457         tb1.AddLabelTool(wx.ID_PREFERENCES, "Preferences", self.images_analyses['preferences'], shortHelp= _(u"Preferences").decode('utf8'), longHelp=_(u"Preferences").decode('utf8'))
458         tb1.AddSeparator()
459         tb1.AddLabelTool(ID_ACCEUIL, "Home", wx.ArtProvider_GetBitmap(wx.ART_GO_HOME, size = (16,16)), shortHelp= _(u"Home page").decode('utf8'), longHelp=_(u"Home page").decode('utf8'))
460         tb1.AddLabelTool(ID_RESULT, "Results", wx.ArtProvider_GetBitmap(wx.ART_LIST_VIEW, size = (16,16)), shortHelp= _(u'Show results').decode('utf8'), longHelp=_(u'Show results').decode('utf8'))
461         tb1.Realize()
462         
463         tb_text = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
464                          wx.TB_FLAT | wx.TB_NODIVIDER)
465         for analyse in analyses_text :
466             if not isinstance(analyse, dict) :
467                 tb_text.AddLabelTool(analyse[0], analyse[1], self.images_analyses.get(analyse[2], wx.EmptyBitmap(16,16)), shortHelp = analyse[1], longHelp = analyse[1])
468             else :
469                 for subana in analyse['content'] :
470                     tb_text.AddLabelTool(subana[0], subana[1], self.images_analyses.get(subana[2], wx.EmptyBitmap(16,16)), shortHelp = subana[1], longHelp = subana[1])
471         tb_text.Realize()
472         
473         tb_mat = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
474                          wx.TB_FLAT | wx.TB_NODIVIDER)
475         for analyse in matanalyses :
476             if not isinstance(analyse, dict) :
477                 tb_mat.AddLabelTool(analyse[0], analyse[1], self.images_analyses.get(analyse[2], wx.EmptyBitmap(16,16)), shortHelp = analyse[1], longHelp = analyse[1])
478             else :
479                 for subana in analyse['content'] :
480                     tb_mat.AddLabelTool(subana[0], subana[1], self.images_analyses.get(subana[2], wx.EmptyBitmap(16,16)), shortHelp = subana[1], longHelp = subana[1])        
481         tb_mat.Realize()
482         
483         tb_help = wx.ToolBar(self, -1, wx.DefaultPosition, wx.DefaultSize,
484                          wx.TB_FLAT | wx.TB_NODIVIDER)
485         tb_help.AddLabelTool(wx.ID_ABOUT, "About", wx.ArtProvider_GetBitmap(wx.ART_INFORMATION, size=(16,16)), shortHelp=_(u"About...").decode('utf8'), longHelp=_(u"About...").decode('utf8'))
486         tb_help.AddLabelTool(wx.ID_HELP, "Help", wx.ArtProvider_GetBitmap(wx.ART_HELP, size=(16,16)), shortHelp=_(u"Online help...").decode('utf8'), longHelp=_(u"Online help...").decode('utf8'))
487         tb_help.Realize()
488 #------------------------------------------------------------------------------------------------
489
490         self.text_ctrl_txt = wx.TextCtrl(self, -1, "", wx.Point(0, 0), wx.Size(200, 200), wx.NO_BORDER | wx.TE_MULTILINE | wx.TE_RICH2 | wx.TE_READONLY)
491                       
492         #self._mgr.AddPane(self.text_ctrl_txt, wx.aui.AuiPaneInfo().
493         #                  Name("Text").CenterPane())                      
494         self._mgr.AddPane(self.text_ctrl_txt, aui.AuiPaneInfo().
495                           Name("Text").CenterPane())
496         #self._mgr.AddPane(IntroPanel(self), wx.aui.AuiPaneInfo().Name("Intro_Text").
497         #                  CenterPane())
498         self._mgr.AddPane(IntroPanel(self), aui.AuiPaneInfo().Name("Intro_Text").
499                           CenterPane())
500         #if not os.path.exists(os.path.join(UserConfigPath, 'history.db')) :
501         #    with open(os.path.join(UserConfigPath, 'history.db'), 'w') as f :
502         #        f.write('')
503         self.history = History(os.path.join(UserConfigPath, 'history.db'))
504         self.tree = LeftTree(self)
505         self._mgr.AddPane(self.tree, aui.AuiPaneInfo().Name("lefttree").Caption(_(u"Historic").decode('utf8')).
506                           Left().MinSize(wx.Size(200,500)).Layer(1).Position(1).CloseButton(False).MaximizeButton(True).
507                           MinimizeButton(True))
508         
509         #self.nb = wx.aui.AuiNotebook(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.aui.AUI_NB_DEFAULT_STYLE | wx.aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.aui.AUI_NB_TAB_MOVE | wx.aui.AUI_NB_TAB_FLOAT| wx.NO_BORDER)
510         self.nb = aui.AuiNotebook(self, -1, wx.DefaultPosition, wx.DefaultSize, aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | aui.AUI_NB_TAB_MOVE | aui.AUI_NB_TAB_FLOAT| wx.NO_BORDER)
511         notebook_flags =  aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | aui.AUI_NB_TAB_MOVE | aui.AUI_NB_TAB_FLOAT| wx.NO_BORDER
512         self.nb.SetAGWWindowStyleFlag(notebook_flags)
513         self.nb.SetArtProvider(aui.ChromeTabArt())
514         #self.nb.SetArtProvider(aui.VC8TabArt())
515         #self.nb.parent = self
516         #self._notebook_style = aui.AUI_NB_DEFAULT_STYLE | aui.AUI_NB_TAB_EXTERNAL_MOVE | wx.NO_BORDER
517         #self._mgr.AddPane(self.nb, wx.aui.AuiPaneInfo().
518         #                      Name("Tab_content").
519         #                      CenterPane())
520         self._mgr.AddPane(self.nb, aui.AuiPaneInfo().
521                               Name("Tab_content").
522                               CenterPane())        
523         
524         #self._mgr.AddPane(self.Sheet, wx.aui.AuiPaneInfo().Name("Data").CenterPane())
525         #self._mgr.AddPane(self.Sheet, aui.AuiPaneInfo().Name("Data").CenterPane())
526         self.nb.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnCloseTab)
527         self.nb.Bind(aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
528         # add the toolbars to the manager
529                         
530         #self._mgr.AddPane(tb1, wx.aui.AuiPaneInfo().
531         #                  Name("tb1").Caption("Fichiers").
532         #                  ToolbarPane().Top().
533         #                  LeftDockable(False).RightDockable(False))
534         self._mgr.AddPane(tb1, aui.AuiPaneInfo().
535                           Name("tb1").Caption("Fichiers").
536                           ToolbarPane().Top().
537                           LeftDockable(True).RightDockable(False))
538         
539         self._mgr.AddPane(tb_text, aui.AuiPaneInfo().
540                           Name("tb_text").Caption("analyse_text").
541                           ToolbarPane().Top().
542                           LeftDockable(True).RightDockable(False))
543         
544         self._mgr.AddPane(tb_mat, aui.AuiPaneInfo().
545                           Name("tb_mat").Caption("analyse_matrix").
546                           ToolbarPane().Top().
547                           LeftDockable(True).RightDockable(False))
548                 
549         self._mgr.AddPane(tb_help, aui.AuiPaneInfo().
550                           Name("tb_help").Caption("help").
551                           ToolbarPane().Top().
552                           LeftDockable(True).RightDockable(False))
553                 
554         self._mgr.GetPane('tb_text').Hide()
555         self._mgr.GetPane('tb_mat').Hide()
556         
557         self.ShowAPane("Intro_Text")
558         self._mgr.GetPane("lefttree").Show()
559         self._mgr.GetPane("classif_tb").Hide()
560         # "commit" all changes made to FrameManager   
561         self._mgr.Update()
562
563         # Show How To Use The Closing Panes Event
564 ##################################################################        
565         self.Bind(wx.EVT_MENU, self.OnAcceuil, id=ID_ACCEUIL)
566         self.Bind(wx.EVT_MENU, self.ShowTab, id=ID_RESULT)
567         self.Bind(wx.EVT_MENU, self.OnOpenData, id=ID_OpenData)
568         self.Bind(wx.EVT_MENU, self.OnOpenText, id=ID_OpenText)
569         self.Bind(wx.EVT_MENU, self.OnOpenAnalyse, id=ID_OnOpenAnalyse)
570         self.Bind(wx.EVT_MENU, self.import_factiva_xml, fact_from_xml)
571         self.Bind(wx.EVT_MENU, self.import_factiva_mail, fact_from_mail)
572         self.Bind(wx.EVT_MENU, self.import_factiva_txt, fact_from_txt)
573         self.Bind(wx.EVT_MENU, self.ExtractTools, splitvar)
574         self.Bind(wx.EVT_MENU, self.ExtractTools, extractmod)
575         self.Bind(wx.EVT_MENU, self.ExtractTools, extractthem)
576         self.Bind(wx.EVT_MENU, self.OnFreq, id=ID_Freq)
577         self.Bind(wx.EVT_MENU, self.OnFreqMulti, id=ID_FreqMulti)
578         self.Bind(wx.EVT_MENU, self.OnChi2, id=ID_Chi2)
579         self.Bind(wx.EVT_MENU, self.OnStudent, id=ID_Student)
580         self.Bind(wx.EVT_MENU, self.OnCHDSIM, id=ID_CHDSIM)
581         self.Bind(wx.EVT_MENU, self.OnCHDReinert, id=ID_CHDReinert)
582         self.Bind(wx.EVT_MENU, self.OnAFCM, id=ID_AFCM)
583         self.Bind(wx.EVT_MENU, self.OnProto, id=ID_proto)
584         self.Bind(wx.EVT_MENU, self.OnSplitVar, id = ID_Splitfromvar)
585         #self.Bind(wx.EVT_MENU, self.OnRCode, id=ID_RCODE)
586         #self.Bind(wx.EVT_MENU, self.OnSplitVar, id=ID_SPLITVAR)
587         #self.Bind(wx.EVT_MENU, self.OnCheckcorpus, id = ID_CHECKCORPUS)
588         self.Bind(wx.EVT_MENU, self.OnTextStat, id=ID_TEXTSTAT)
589         self.Bind(wx.EVT_MENU, self.OnTextSpec, id=ID_ASLEX)
590         self.Bind(wx.EVT_MENU, self.OnTextAfcm, id=ID_TEXTAFCM)
591         self.Bind(wx.EVT_MENU, self.OnTextReinert, id=ID_TEXTREINERT)
592         self.Bind(wx.EVT_MENU, self.OnPamSimple, id=ID_TEXTPAM)
593         self.Bind(wx.EVT_MENU, self.OnSimiTxt, id=ID_SimiTxt)
594         self.Bind(wx.EVT_MENU, self.OnWordCloud, id=ID_WC)
595         self.Bind(wx.EVT_MENU, self.OnSubText, id = ID_Subtxtfrommeta)
596         self.Bind(wx.EVT_MENU, self.OnSubText, id = ID_Subtxtfromthem)
597         self.Bind(wx.EVT_MENU, self.OnSimiTab, id=ID_SIMI)
598         self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
599         #self.Bind(wx.EVT_MENU, self.OnSaveTabAs, id=ID_SaveTab)
600         self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
601         self.Bind(wx.EVT_MENU, self.OnHelp, id=wx.ID_HELP)
602         self.Bind(wx.EVT_MENU, self.OnPref, id=wx.ID_PREFERENCES)
603         self.Bind(wx.EVT_MENU, self.OnImportTXM, id=ID_ImportTXM)
604         self.Bind(wx.EVT_MENU, self.OnImportEuropress, id=ID_ImportEuro)
605         self.Bind(wx.EVT_MENU, self.OnImportDMI, id=ID_importdmi)
606         self.Bind(wx.EVT_MENU, self.OnExportMeta, id=ID_exportmeta)
607         self.Bind(wx.EVT_CLOSE, self.OnClose)
608 ##################################################################
609         flags = self._mgr.GetAGWFlags()
610         #flags &= ~wx.aui.AUI_MGR_TRANSPARENT_HINT
611         #flags &= ~wx.aui.AUI_MGR_VENETIAN_BLINDS_HINT
612         #flags &= ~wx.aui.AUI_MGR_RECTANGLE_HINT
613         flags &= ~(aui.AUI_MGR_RECTANGLE_HINT | aui.AUI_MGR_ALLOW_FLOATING)
614         self._mgr.SetAGWFlags(self._mgr.GetAGWFlags() ^ (aui.AUI_MGR_RECTANGLE_HINT | aui.AUI_MGR_ALLOW_FLOATING))
615         self._mgr.GetArtProvider().SetMetric(aui.AUI_DOCKART_GRADIENT_TYPE, aui.AUI_GRADIENT_HORIZONTAL)
616         self.GetDockArt().SetColor(aui.AUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR, "#00FFF9")
617         self.DoUpdate()
618
619         self._icon = wx.Icon(os.path.join(ImagePath, "iraicone.ico"), wx.BITMAP_TYPE_ICO)
620         self.SetIcon(self._icon)
621 ##########################
622         self.ctrl = ""
623         self.input_path = [False]
624         self.TEMPDIR = tempfile.mkdtemp('iramuteq')
625         self.FileTabList = []
626         self.listbar=[]
627         self.DictTab = {}
628         self.FreqNum = 0
629         self.colsep = ''
630         self.txtsep = ''
631         self.g_header = False
632         self.g_id = False
633         self.table = ''
634         self.fileforR = ''
635         self.filename = ''
636         self.nastrings = ''
637         self.encode = ''
638         self.SysEncoding = sys.getdefaultencoding()
639         self.syscoding = sys.getdefaultencoding()
640         #print 'SysEncoding',self.SysEncoding
641         if self.SysEncoding == 'mac-roman' : self.SysEncoding = 'MacRoman'
642         self.type = ''
643
644 ##############################################################@
645         self.ShowMenu('view', True)
646         self.ShowMenu('matrix', False)
647         self.ShowMenu('text', False)
648    
649         self._mgr.Update()
650
651         self.DataPop = False
652         self.DataTxt = False
653         self.Text = ''
654
655         self.lexique = None
656         self.corpus = None
657
658     def finish_init(self) :
659         try :
660             self.pref.read(self.ConfigPath['preferences'])
661             if IsNew(self) :
662                 UpgradeConf(self)
663                 self.pref.read(self.ConfigPath['preferences'])
664                 New = True
665             else :
666                 CopyConf(self)
667                 New = False
668         except :
669             UpgradeConf(self)
670             self.pref.read(self.ConfigPath['preferences'])
671             New = True
672         self.sound = self.pref.getboolean('iramuteq', 'sound')
673         self.check_update = self.pref.getboolean('iramuteq', 'checkupdate')
674         self.version = ConfigGlob.get('DEFAULT', 'version')
675         #configuration des chemins de R
676         self.PathPath = ConfigParser()
677         self.PathPath.read(ConfigPath['path'])
678         BestRPath = False
679         if not CheckRPath(self.PathPath) :
680             if sys.platform == 'win32':
681                 BestRPath = FindRPAthWin32()
682             else:
683                 BestRPath = FindRPathNix()
684             if BestRPath:
685                 self.PathPath.set('PATHS', 'rpath', BestRPath)
686                 with open(ConfigPath['path'], 'w') as f :
687                     self.PathPath.write(f)
688         else:
689             BestRPath = True 
690         if BestRPath :
691             self.RPath = self.PathPath.get('PATHS', 'rpath')
692             if New :
693                 CheckRPackages(self)
694             if not RLibsAreInstalled(self) :
695                 CheckRPackages(self)
696         else :
697             msg = '\n'.join([_(u"Can't find R executable").decode('utf8'), _(u"If R is not installed, get it from http://www.r-project.org.").decode('utf8'),
698                              _(u"If R is installed, report its path in Preferences.").decode('utf8'),
699                              _(u"IRaMuTeQ does not work without R.").decode('utf8')])
700             dlg = wx.MessageDialog(self, msg, _(u"Problem").decode('utf8'), wx.OK | wx.ICON_WARNING)
701             dlg.CenterOnParent()
702             if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
703                 pass
704             dlg.Destroy()
705
706     def setlangue(self) :
707         self.pref.read(self.ConfigPath['preferences'])
708         try :
709             guilangue = self.pref.get('iramuteq', 'guilanguage')
710         except :
711             guilangue = DefaultConf.get('iramuteq', 'guilanguage')
712         self.preslangue.get(guilangue, 'english').install()
713
714     def OnVerif(self, evt) :
715         pack = CheckRPackages(self)
716         if pack :
717             dlg = wx.MessageDialog(self, _(u"Installation OK").decode('utf8'), _(u"Installation").decode('utf8'), wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP)
718             dlg.CenterOnParent()
719             if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
720                 evt.Veto()
721
722     def ShowMenu(self, menu, Show=True):
723         if menu == 'text' :
724             menu_pos = 4
725             if Show :
726                 self._mgr.GetPane('tb_text').Show()
727             else :
728                 self._mgr.GetPane('tb_text').Hide()   
729         elif menu == 'matrix' :
730             menu_pos = 3
731             if Show :
732                 self._mgr.GetPane('tb_mat').Show()
733             else :
734                 self._mgr.GetPane('tb_mat').Hide()           
735         elif menu == 'view' :
736             menu_pos = 2
737         else :
738             menu_pos = None
739             
740         #menu_pos = self.mb.FindMenu(menu)
741         if not menu_pos is None :
742             self.mb.EnableTop(menu_pos, Show)
743             self.mb.UpdateMenus()
744         self._mgr.Update()
745
746 #--------------------------------------------------------------------
747     def OnClose(self, event):
748         print 'onclose'
749         with open(self.ConfigPath['path'], 'w') as f :
750             self.PathPath.write(f)
751         self._mgr.UnInit()
752         del self._mgr
753         self.Destroy()
754
755     def OnOpenData(self, event):
756         inputname, self.input_path = OnOpen(self, "Data")
757         if inputname:
758             #filename = self.input_path[0]
759             self.tableau = Tableau(self,os.path.abspath(self.input_path[0]))
760             val = get_table_param(self, self.input_path[0])
761             if val == wx.ID_OK :
762                 busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self)
763                 wx.SafeYield()
764                 try :
765                     self.tableau.make_content()
766                     OpenAnalyse(self, self.tableau.parametres)
767                     self.tree.OnItemAppend(self.tableau.parametres)
768                     del busy 
769                 except :
770                     del busy
771                     BugReport(self)
772                 #self.tableau.show_tab()
773
774     def OnOpenAnalyse(self, event):
775         self.AnalysePath = OnOpen(self, "Analyse")
776         if self.AnalysePath :
777             OpenAnalyse(self, self.AnalysePath[1][0], True)
778             self.ShowMenu('view')
779
780     def OnOpenText(self, event):
781         inputname, self.input_path = OnOpen(self, "Texte")
782         self.filename = self.input_path[0]
783         if inputname:
784             self.OpenText()
785    
786     def OnSubText(self, evt, corpus = None, parametres = None):
787         if corpus is None :
788             corpus = self.tree.getcorpus()
789         if evt.GetId() == ID_Subtxtfrommeta :
790             parametres = {'frommeta' : True}
791         elif evt.GetId() == ID_Subtxtfromthem :
792             parametres = {'fromtheme' : True}
793         builder = SubBuilder(self, corpus, parametres)
794         if builder.res == wx.ID_OK :
795             busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self)
796             wx.SafeYield()
797             corpus = builder.doanalyse()
798             self.history.add(corpus.parametres)
799             OpenAnalyse(self, corpus.parametres)
800             self.tree.OnItemAppend(corpus.parametres)
801             del busy
802             
803     def OpenText(self):
804         dlg = progressbar(self, 5) 
805         
806         builder =  Builder(self, dlg)
807         if builder.res == wx.ID_OK :
808             try :
809                 corpus = builder.doanalyse()
810                 self.history.add(corpus.parametres)
811                 self.tree.OnItemAppend(corpus.parametres)
812                 OpenAnalyse(self, corpus.parametres)
813             except :
814                 dlg.Destroy()
815                 BugReport(self)
816             else :
817                 count = 1
818                 keepGoing = dlg.Update(count, u"Lecture du fichier")
819                 self.ShowMenu('view')
820                 self.ShowMenu('text')
821                 self.ShowMenu('matrix', False)
822                 self.type = "Texte"
823                 self.DataTxt = False
824                 self.Text = ''
825                 count += 1
826                 keepGoing = dlg.Update(count, u"Chargement du dictionnaire")
827                 dlg.Destroy()
828         
829     def OnExit(self, event):
830         self.Close()
831
832     def OnAbout(self, event):
833         info = wx.AboutDialogInfo()
834         info.Name = ConfigGlob.get('DEFAULT', 'name')
835         info.Version = ConfigGlob.get('DEFAULT', 'version')
836         info.Copyright = ConfigGlob.get('DEFAULT', 'copyright')
837         info.Translators = ConfigGlob.get('DEFAULT', 'translators').decode('utf8').split(';')
838         info.Description = u"""
839 Interface de R pour les Analyses Multidimensionnelles 
840 de Textes et de Questionnaires
841
842 Un logiciel libre
843 construit avec des logiciels libres.
844
845 Laboratoire LERASS
846
847 REPERE
848 """
849         info.WebSite = ("http://www.iramuteq.org", u"Site web IRaMuTeQ")
850         dev = ConfigGlob.get('DEFAULT', 'dev').decode('utf8').split(';')
851         info.Developers = dev
852         info.License = u"""Iramuteq est un logiciel libre ; vous pouvez le diffuser et/ou le modifier 
853 suivant les termes de la Licence Publique Générale GNU telle que publiée 
854 par la Free Software Foundation ; soit la version 2 de cette licence, 
855 soit (à votre convenance) une version ultérieure.
856
857 Iramuteq est diffusé dans l'espoir qu'il sera utile, 
858 mais SANS AUCUNE GARANTIE ; sans même une garantie implicite 
859 de COMMERCIALISATION ou d'ADÉQUATION Ã€ UN USAGE PARTICULIER. 
860 Voyez la Licence Publique Générale GNU pour plus de détails.
861
862 Vous devriez avoir reçu une copie de la Licence Publique Générale GNU
863 avec Iramuteq ; sinon, veuillez Ã©crire Ã  la Free Software Foundation,
864 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, Ã‰tats-Unis."""
865         wx.AboutBox(info)
866
867     def GetDockArt(self):
868         return self._mgr.GetArtProvider()
869
870     def DoUpdate(self):
871         self._mgr.Update()
872
873     def OnPageChanged(self, event) :
874         new = event.GetSelection()
875         nobject = event.GetEventObject()
876         parent = nobject.GetParent()
877         if isinstance(parent, IraFrame) :
878             npage = self.nb.GetPage(new)
879             if 'parametres' in dir(npage) :
880                 self.tree.GiveFocus(uuid=npage.parametres['uuid'])
881                 if npage.parametres.get('matrix', False) :
882                     self.ShowMenu('text', False)
883                     self.ShowMenu('matrix', True)
884                 elif npage.parametres.get('corpus', False) :
885                     self.ShowMenu('text')
886                     self.ShowMenu('matrix', False)
887
888     def OnCloseTab(self, evt):
889         #log.info('Closing tab %s' % str(evt.GetEventObject()))
890         ctrl = evt.GetEventObject()
891         if isinstance(ctrl.GetParent(), aui.AuiNotebook) or isinstance(ctrl.GetParent(), wx.Panel):
892             notebook = True
893         else :
894             notebook = False
895         page = self.nb.GetPage(self.nb.GetSelection())
896         if 'parametres' in dir(page) and isinstance(ctrl.GetParent(), IraFrame) :
897             self.history.rmtab(page.parametres)
898             self.tree.CloseItem(uuid = page.parametres['uuid'])
899         TabTitle = self.nb.GetPageText(self.nb.GetSelection())
900
901         if self.nb.GetPageCount() == 1 and not notebook :
902             self.LastTabClose()
903     
904     def LastTabClose(self) :
905         if self.nb.GetPageCount() == 1 :
906             if self.DataTxt :
907                 self.ShowAPane("Text")
908             elif self.DataPop :
909                 self.ShowAPane("Data")
910             else :
911                 self.ShowAPane("Intro_Text")
912
913     def GetStartPosition(self):
914
915         self.x = self.x + 20
916         x = self.x
917         pt = self.ClientToScreen(wx.Point(0, 0))
918         
919         return wx.Point(pt.x + x, pt.y + x)
920     
921     def ShowAPane(self, panel):
922         for pane in self._mgr.GetAllPanes() :
923             if not pane.IsToolbar() and pane.name != 'lefttree': 
924                 pane.Hide()
925         self._mgr.GetPane(panel).Show()
926         self._mgr.Update()
927         
928     def OnAcceuil(self, event):
929         self.ShowAPane(u"Intro_Text")
930         event.Skip()
931     
932     def CreateHTMLCtrl(self):
933         ctrl = wx.html.HtmlWindow(self, -1, wx.DefaultPosition, wx.Size(400, 300))
934         if "gtk2" in wx.PlatformInfo:
935             ctrl.SetStandardFonts()
936         ctrl.SetPage(u"text")        
937         return ctrl
938
939     def ShowTab(self, evt):
940         self.ShowAPane("Tab_content")
941
942 ################################################################
943 #debut des analyses
944 ################################################################
945     def analyse_matrix(self, analyse, analyse_type = '', matrix = None, parametres = None, dlgnb = 1):
946         if matrix is None :
947             matrix = self.tree.getmatrix()
948         if parametres is not None :
949             parametres['type'] = analyse_type
950         else :
951             parametres = {'type' : analyse_type}
952         try :
953         #print 'plus de bug@@@@@@@@@@@@@@@@@@@@@@'
954             analyse(self, matrix, parametres = parametres, dlg = dlgnb)
955         except:
956             BugReport(self)           
957
958     def OnFreq(self, event, matrix = None):
959         self.analyse_matrix(Frequences, analyse_type = 'freq', matrix = matrix, dlgnb = 3)
960     
961     def OnFreqMulti(self, event, matrix = None):
962         self.analyse_matrix(FreqMultiple, analyse_type = 'freqmulti', matrix = matrix, dlgnb = 3)
963
964     def OnChi2(self, event, matrix = None):
965         self.analyse_matrix(ChiSquare, matrix = matrix, analyse_type = 'chi2', dlgnb = 3) 
966
967     def OnSimiTab(self, event, matrix = None):
968         self.analyse_matrix(DoSimi, matrix = matrix, analyse_type = 'simimatrix', dlgnb = 5)
969
970     def OnCHDReinert(self, event, matrix = None):
971         #if matrix is None :
972         #    matrix = self.tree.getmatrix()
973         #AnalyseQuest(self, matrix, parametres = {'type' : 'reinertmatrix'}, dlg = 3)
974         self.analyse_matrix(AnalyseQuest, matrix = matrix, analyse_type = 'reinertmatrix', dlgnb = 5)
975             
976     def OnStudent(self, event):
977         try:
978             MakeStudent(self) 
979         except:
980             BugReport(self)
981
982     def OnRCode(self, event):
983         try:
984             InputText(self)
985         except:
986             BugReport(self)
987
988     def OnCHDSIM(self, event):
989         try:
990         #    print 'ATTENTION!!!!'
991             chdsim = ChdCluster(self)
992             if chdsim.val == wx.ID_OK:
993                 PlaySound(self)
994         except:
995             BugReport(self)
996  
997 #     def OnCHDReinert(self, event):
998 #         try:
999 #          #   print('PLUS DE BUG SUR ALCESTE QUESTIONNAIRE')
1000 #             self.quest = AnalyseQuest(self)
1001 #             if self.quest.val == wx.ID_OK:
1002 #                 PlaySound(self)
1003 #         except:
1004 #             BugReport(self)
1005     
1006     def OnProto(self, evt, matrix = None) :
1007         self.analyse_matrix(Prototypical, matrix = matrix, analyse_type = 'proto', dlgnb = 3) 
1008         #Prototypical(self, {'type' : 'proto'})
1009     
1010     def OnSplitVar(self, evt, matrix = None):
1011         if matrix is None :
1012             matrix = self.tree.getmatrix()
1013         self.analyse_matrix(SplitMatrixFromVar, matrix = matrix, analyse_type = 'splitvar', parametres = {'pathout': matrix.pathout.dirout}, dlgnb = 3)
1014         #matrix = self.tree.getmatrix()
1015         
1016
1017     def OnSimiTxt(self, evt, corpus = None) :
1018         #    print 'PLUS DE BUG SUR SIMITXT'
1019         try :
1020             #self.Text = SimiTxt(self)
1021             if corpus is None :
1022                 corpus = self.tree.getcorpus()            
1023             self.Text = SimiTxt(self, corpus, parametres = {'type': 'simitxt'}, dlg = 3)
1024             if self.Text.val == wx.ID_OK :
1025                 PlaySound(self)
1026         except :
1027             BugReport(self)
1028     
1029     def OnWordCloud(self, evt, corpus = None) :
1030         #    print 'PLUS DE BUG SUR WORDCLOUD'
1031         try :
1032             if corpus is None :
1033                 corpus = self.tree.getcorpus()            
1034             self.Text = WordCloud(self, corpus, parametres = {'type' : 'wordcloud'}, dlg = 3)
1035             if self.Text.val == wx.ID_OK :
1036                 PlaySound(self)
1037         except :
1038             BugReport(self)
1039
1040     def OnClusterCloud(self, corpus, parametres = None) :
1041         self.Text = ClusterCloud(self, corpus, parametres = parametres, dlg = 3)
1042
1043     def OnAFCM(self, event):
1044         try:
1045             DoAFCM(self)
1046         except:
1047             BugReport(self)
1048
1049     def OnTextStat(self, event, corpus = None):
1050             #print 'PAS DE BUG SUR TEXT STAT'
1051         try:
1052             if corpus is None :
1053                 corpus = self.tree.getcorpus()
1054             self.Text = Stat(self, corpus, parametres = {'type': 'stat'}, dlg = 7)
1055             
1056             if self.Text.val == wx.ID_OK :
1057                 PlaySound(self)
1058         except:
1059             BugReport(self)
1060         
1061     def OnTextSpec(self, event, corpus = None):  
1062         try:
1063             #self.Text = AsLexico(self)
1064             #print('ATTENTION : PLUS DE BUG SUR LEXICO')
1065             if corpus is None :
1066                 corpus = self.tree.getcorpus()
1067             self.Text = Lexico(self, corpus, parametres = {'type' : 'spec'}, dlg = 3)
1068             if self.Text.val == wx.ID_OK :
1069                 PlaySound(self)
1070         except:
1071             BugReport(self)
1072     
1073     def OnTextAfcm(self, event):
1074         try:
1075             AfcUci(self)
1076             PlaySound(self)
1077         except:
1078             BugReport(self)
1079
1080     def import_factiva_xml(self,event):
1081         try :
1082             ImportFactiva(self, 'xml')
1083         except :
1084             BugReport(self)
1085
1086     def import_factiva_mail(self, evt) :
1087         try :
1088             ImportFactiva(self, 'mail')
1089         except :
1090             BugReport(self)
1091
1092     def import_factiva_txt(self, evt) :
1093         try :
1094             ImportFactiva(self, 'txt')
1095         except :
1096             BugReport(self)
1097
1098     def OnImportTXM(self, evt) :
1099         try :
1100             ImportFactiva(self, 'txm')
1101         except :
1102             BugReport(self)
1103     
1104     def OnImportEuropress(self, evt) :
1105         try :
1106             ImportFactiva(self, 'euro')
1107         except :
1108             BugReport(self)
1109     
1110     def OnImportDMI(self, evt):
1111         ImportDMI(self, {})
1112     
1113     def OnExportMeta(self, evt, corpus = None):
1114         if corpus is None :
1115             corpus = self.tree.getcorpus()
1116         try :
1117             ExportMetaTable(self, corpus)
1118         except :
1119             BugReport(self) 
1120
1121     def ExtractTools(self, evt) :
1122         ID = evt.GetId()
1123         if ID == self.ID_splitvar :
1124             Extract(self, 'splitvar')
1125         elif ID == self.ID_extractmod :
1126             Extract(self, 'mods')
1127         elif ID == self.ID_extractthem :
1128             Extract(self, 'them')
1129
1130     def OnTextReinert(self, event, corpus = None):
1131         try:
1132             #print('ATTENTION : PLUS DE BUG SUR ALCESTE')
1133             #RunAnalyse(self, corpus, Alceste, OptAlceste)
1134             if corpus is None :
1135                 corpus = self.tree.getcorpus()            
1136             self.Text = Reinert(self, corpus, parametres = {'type': 'alceste'}, dlg = 6)
1137             if self.Text.val == wx.ID_OK:
1138                 PlaySound(self)
1139         except:
1140             BugReport(self)
1141
1142     def OnPamSimple(self, event, corpus = None):
1143         try:
1144             if corpus is None :
1145                 corpus = self.tree.getcorpus()
1146             self.Text = AnalysePam(self, corpus, parametres = {'type' : 'pamtxt'}, dlg = 6)
1147             if self.Text.val == wx.ID_OK:
1148                 PlaySound(self)
1149         except:
1150             BugReport(self)
1151
1152     def SimiCluster(self, parametres = {}, fromprof = False, tableau = None) :
1153         self.analyse_matrix(DoSimi, parametres = parametres, analyse_type = 'simiclustermatrix', matrix = tableau, dlgnb = 5)
1154     
1155 #    def OnSimi(self,evt):
1156 #        try :
1157             #print 'ATTENTION !!!! VERGES'
1158             #print 'PLUS DE BUG SUR SIMI'
1159 #            self.res = DoSimi(self, param = None)
1160             #self.res = Verges(self)
1161 #            if self.res.val == wx.ID_OK :
1162 #                PlaySound(self)
1163 #        except :
1164 #            BugReport(self)
1165 #################################################################
1166
1167     def OnHelp(self, event):
1168         webbrowser.open('http://www.iramuteq.org/documentation')
1169     
1170     def OnPref(self, event):
1171         dlg = PrefDialog(self)
1172         dlg.CenterOnParent()
1173         self.val = dlg.ShowModal()
1174         dlg.Destroy()
1175
1176     def Upgrade(self) :
1177         if self.check_update:
1178             NewVersion(self)
1179         else:
1180             print 'pas de verif'    
1181         #IsNew(self)
1182         #CheckRPackages(self)
1183
1184     def OnOpenFromCmdl(self):
1185         truepath = True
1186         if options.filename :
1187             if os.path.exists(options.filename):
1188                 self.filename = os.path.abspath(options.filename)
1189             else:
1190                 truepath = False
1191         elif args :
1192             if os.path.exists(os.path.realpath(args[0])):
1193                 self.filename = os.path.abspath(os.path.realpath(args[0]))
1194             else:
1195                 truepath = False
1196         else:
1197             pass
1198         if truepath :
1199             if os.path.splitext(self.filename)[1] in ['.csv', '.xls', '.ods']:
1200                 self.tableau = Tableau(self, self.filename)
1201                 val = get_table_param(self, self.filename)
1202                 if val == wx.ID_OK :
1203                     self.tableau.make_content()
1204                     OpenAnalyse(self, self.tableau.parametres)
1205                     self.tree.OnItemAppend(self.tableau.parametres)
1206                 #get_table_param(self, self.filename)
1207                 #self.tableau.make_content()
1208                 #self.tableau.show_tab()
1209                 #open_data(self, self.filename)
1210             elif os.path.splitext(self.filename)[1] == '.txt':
1211                 self.OpenText()
1212             elif os.path.splitext(self.filename)[1] == '.ira' :
1213                 #self.corpus = Corpus(self)
1214                 #self.Text = OpenAnalyse(self, self.filename)
1215                 OpenAnalyse(self, self.filename)
1216         if not truepath:
1217             print 'This file does not exist'
1218             
1219         
1220
1221 class IntroPanel(wx.Panel):
1222     def __init__(self, parent):
1223         wx.Panel.__init__(self, parent)
1224         #col = randint(0, 255)
1225         #col1 = randint(0,255)
1226         #col2 = randint(0,255)
1227         #col = 57
1228         col = 161
1229         col1 = 198
1230         col2 = 224
1231         bckgrdcolor = wx.Colour(col, col1, col2)
1232         self.SetBackgroundColour(bckgrdcolor)
1233         txtcolour = wx.Colour(250, 250, 250)
1234         linkcolor = wx.Colour(255, 0, 0)
1235         sizer1 = wx.BoxSizer(wx.VERTICAL)
1236         sizer2 = wx.BoxSizer(wx.VERTICAL)
1237         sizer4 = wx.BoxSizer(wx.HORIZONTAL)
1238         grid_sizer_1 = wx.FlexGridSizer(1, 4, 0, 0)
1239         grid_sizer_3 = wx.FlexGridSizer(1, 4, 0, 0)
1240         grid_sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
1241         
1242         iralink = hl.HyperLinkCtrl(self, wx.ID_ANY, u"http://www.iramuteq.org", URL="http://www.iramuteq.org")
1243         iralink.SetColours(linkcolor, linkcolor, "RED")
1244         iralink.SetBackgroundColour(bckgrdcolor)
1245         iralink.EnableRollover(True)
1246         iralink.SetUnderlines(False, False, True)
1247         iralink.SetBold(True)
1248         iralink.UpdateLink()
1249         
1250         PanelPres = wx.Panel(self)
1251         bckgrdcolor = wx.Colour(randint(0, 255), randint(0, 255), randint(0, 255))
1252         PanelPres.SetBackgroundColour(bckgrdcolor)
1253         
1254         label_1 = wx.StaticText(self, -1, u"IRaMuTeQ", size=(-1, -1))
1255         label_1.SetFont(wx.Font(46, wx.TELETYPE, wx.NORMAL, wx.BOLD, 0, "Purisa"))
1256         label_1.SetForegroundColour(wx.RED)
1257         
1258         iraicone = wx.Image(os.path.join(ImagePath,'iraicone100x100.png'), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
1259         but_ira = wx.StaticBitmap(self, -1, bitmap = iraicone)
1260
1261         
1262         label2 = wx.StaticText(PanelPres, -1 , u'\nVersion ' + ConfigGlob.get('DEFAULT', 'version') + '\n')
1263         label2.SetForegroundColour(txtcolour)
1264         label2.SetBackgroundColour(bckgrdcolor)
1265         self.hyper2 = hl.HyperLinkCtrl(PanelPres, wx.ID_ANY, u"REPERE", URL="http://repere.no-ip.org/")
1266         self.hyper2.SetColours(linkcolor, linkcolor, "RED")
1267         self.hyper2.SetBackgroundColour(bckgrdcolor)
1268         self.hyper2.EnableRollover(True)
1269         self.hyper2.SetUnderlines(False, False, True)
1270         self.hyper2.SetBold(True)
1271         self.hyper2.UpdateLink()
1272         
1273         label_lerass = wx.StaticText(PanelPres, -1, u'Laboratoire ')
1274         label_lerass.SetForegroundColour(txtcolour)
1275         label_lerass.SetBackgroundColour(bckgrdcolor)
1276         
1277         self.hyper_lerass = hl.HyperLinkCtrl(PanelPres, -1, u'LERASS', URL="http://www.lerass.com")
1278         self.hyper_lerass.SetColours(linkcolor, linkcolor, "RED")
1279         self.hyper_lerass.SetBackgroundColour(bckgrdcolor)
1280         self.hyper_lerass.EnableRollover(True)
1281         self.hyper_lerass.SetUnderlines(False, False, True)
1282         self.hyper_lerass.SetBold(True)
1283         self.hyper_lerass.UpdateLink()
1284         
1285         blank = wx.StaticText(PanelPres, -1, u'\n')
1286         blank1 = wx.StaticText(PanelPres, -1, u'\n')
1287         
1288         labellicence = wx.StaticText(PanelPres, -1, _(u"License GNU GPL").decode('utf8'))
1289         labellicence.SetForegroundColour(txtcolour)
1290         labellicence.SetBackgroundColour(bckgrdcolor)
1291         
1292         labelcopy = wx.StaticText(PanelPres, -1, ConfigGlob.get('DEFAULT', 'copyright'))
1293         labelcopy.SetForegroundColour(txtcolour)
1294         labelcopy.SetBackgroundColour(bckgrdcolor)
1295         
1296         python_img = wx.Image(os.path.join(ImagePath,'python-logo.jpg'), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
1297         r_img = wx.Image(os.path.join(ImagePath,'Rlogo.jpg'), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
1298         lexique_img = wx.Image(os.path.join(ImagePath,'LexTexte4.jpg'), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
1299         but_python = wx.BitmapButton(self, -1, python_img)
1300         but_lexique = wx.BitmapButton(self, -1, lexique_img)
1301         but_r = wx.BitmapButton(self, -1, r_img)
1302         self.Bind(wx.EVT_BUTTON, self.OnPython, but_python)
1303         self.Bind(wx.EVT_BUTTON, self.OnLexique, but_lexique)
1304         self.Bind(wx.EVT_BUTTON, self.OnR, but_r)
1305         
1306         
1307         grid_sizer_1.Add(self.hyper2, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL, 0)
1308         grid_sizer_3.Add(label_lerass, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL, 0)
1309         grid_sizer_3.Add(self.hyper_lerass, 0, wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL, 0)
1310         sizer4.Add(label_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
1311         
1312         sizer2.Add(label2, 0, wx.ALIGN_CENTER, 5)
1313         sizer2.Add(wx.StaticText(PanelPres, -1, u''), 0, wx.ALIGN_CENTER, 5)
1314         sizer2.Add(wx.StaticText(PanelPres, -1, u''), 0, wx.ALIGN_CENTER, 5)
1315         sizer2.Add(grid_sizer_3, 0, wx.ALIGN_CENTER, 5)
1316         sizer2.Add(wx.StaticText(PanelPres, -1, u' '), 0, wx.ALIGN_CENTER, 5)
1317         sizer2.Add(grid_sizer_1, 0, wx.ALIGN_CENTER, 5)
1318         sizer2.Add(labellicence, 0, wx.ALIGN_CENTER, 5)
1319         sizer2.Add(labelcopy, 0, wx.ALIGN_CENTER, 5)
1320         sizer1.Add(sizer4, 2, wx.ALIGN_CENTER_HORIZONTAL, 0)
1321         sizer1.Add(but_ira, 1, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 5)
1322         sizer1.Add(iralink, 1, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_TOP, 5)
1323         sizer2.Add(wx.StaticText(PanelPres, -1, u''), 0, wx.ALIGN_CENTER, 10)
1324         PanelPres.SetSizer(sizer2)
1325         grid_sizer_2.Add(but_python, 1, wx.ALIGN_BOTTOM)
1326         grid_sizer_2.Add(but_lexique, 1, wx.ALIGN_BOTTOM)
1327         grid_sizer_2.Add(but_r, 1,  wx.ALIGN_BOTTOM)
1328         
1329         sizer1.Add(PanelPres, 0, wx.EXPAND |wx.ALL, 10)
1330         sizer1.Add(grid_sizer_2, 2, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 1)
1331         self.SetSizer(sizer1)
1332         sizer1.Fit(self)
1333     
1334     def OnPython(self,evt):
1335         webbrowser.open('http://www.python.org')
1336     
1337     def OnLexique(self,evt):
1338         webbrowser.open('http://www.lexique.org')
1339         
1340     def OnR(self,evt):
1341         webbrowser.open('http://www.r-project.org')
1342
1343 class MySplashScreen(wx.SplashScreen):
1344     def __init__(self):
1345         bmp = wx.Image(os.path.join(ImagePath, 'splash.png')).ConvertToBitmap()
1346         wx.SplashScreen.__init__(self, bmp,
1347                                  wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_TIMEOUT,
1348                                  2000, None, -1)
1349         self.Bind(wx.EVT_CLOSE, self.OnClose)
1350         self.fc = wx.FutureCall(1, self.ShowMain)
1351
1352     def OnClose(self, evt):
1353         evt.Skip()
1354         self.Hide()
1355         
1356         if self.fc.IsRunning():
1357             self.fc.Stop()
1358             self.ShowMain()
1359
1360     def ShowMain(self):
1361         displaySize = wx.DisplaySize()
1362         w = displaySize[0]/1.2
1363         h = displaySize[1]/1.2
1364         frame = IraFrame(None, -1, "IRaMuTeQ " + ConfigGlob.get('DEFAULT', 'version'), size=(w, h))
1365         frame.Show()
1366         frame.finish_init()
1367         frame.Upgrade()
1368         frame.OnOpenFromCmdl()
1369 #        if self.fc.IsRunning():
1370 #            self.Raise()
1371         #wx.CallAfter(frame.ShowTip)
1372         
1373 class MyApp(wx.App):
1374     def OnInit(self):
1375         """
1376         Create and show the splash screen.  It will then create and show
1377         the main frame when it is time to do so.
1378         """
1379         wx.SystemOptions.SetOptionInt("mac.window-plain-transition", 1)
1380         self.SetAppName("Iramuteq")       
1381         splash = MySplashScreen()
1382         splash.Show()
1383         return True
1384
1385 def main():
1386     app = MyApp(False)
1387     app.MainLoop()
1388
1389 if __name__ == '__main__':
1390     __name__ = 'Main'
1391     main()