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