From 94db7716520d397ab87a1a7730d2d0fd9f873da0 Mon Sep 17 00:00:00 2001 From: Pierre Ratinaud Date: Sat, 19 Jul 2014 01:31:41 +0200 Subject: [PATCH] ... --- TODO | 13 --- images/chi2.png | Bin 0 -> 405 bytes images/frequences.png | Bin 0 -> 434 bytes images/icone_chd.png | Bin 0 -> 407 bytes images/matrix.png | Bin 0 -> 455 bytes images/matroot.png | Bin 0 -> 453 bytes images/reinertmatrix.png | Bin 0 -> 603 bytes images/simimatrix.png | Bin 0 -> 622 bytes textchdalc.py | 299 ----------------------------------------------- vitemspicker.py | 267 ++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 267 insertions(+), 312 deletions(-) delete mode 100644 TODO create mode 100644 images/chi2.png create mode 100644 images/frequences.png create mode 100644 images/icone_chd.png create mode 100644 images/matrix.png create mode 100644 images/matroot.png create mode 100644 images/reinertmatrix.png create mode 100644 images/simimatrix.png delete mode 100644 textchdalc.py create mode 100644 vitemspicker.py diff --git a/TODO b/TODO deleted file mode 100644 index 261804c..0000000 --- a/TODO +++ /dev/null @@ -1,13 +0,0 @@ -- système de template pour la présentation des résultats -- traitement texte : - - méthode alceste (intégrer le temps et les personnes) -- AFCM (mja et mjca) -- système de configuration -- anova -- correlation -- U de Mann Whitney -- autres tests non paramétriques -- regression linéaire ? -- intégration avec openoffice - - diff --git a/images/chi2.png b/images/chi2.png new file mode 100644 index 0000000000000000000000000000000000000000..cafcdd4911fb01550d7c1f8b1ef06488d1aca9fb GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zZvkP(rWyBM00kvWTq8hFYQHah0c_n&LUa9|7L z;)y5ax1Wx0&~g9v&3dbY+OlcA6<4)8ygqTM*J zJo@=e>Zdys!;O0-q0d@bjXwI%VDm|zcFSIKTh;UOub%TSdzD%)*{#;8vf+@*%?f$H ul`_ud`L?EWk|K3?^{=|9z_&NHmdW~l!bMfX?@NI}$l&Sf=d#Wzp$PzF0-5;$ literal 0 HcmV?d00001 diff --git a/images/frequences.png b/images/frequences.png new file mode 100644 index 0000000000000000000000000000000000000000..802ab7a5414e785d34a5445136535295d3571a31 GIT binary patch literal 434 zcmV;j0ZsmiP)fLQxdQf9F0ekwjlaU_+3L1h1i?p(W@uG_*JP z4GNn27Hxfjh$7nB8ftVYA|aw2qGvuUA$^+O(_l#uiW$*=xtw#)|HuE_E9*J$dM*et`+{{Y#@d6(I2DqfeVq%jfVt*eSQsx6zCO|=|17L6J;!Rey_CcQjqtudzY5bDcC c_53EL?@aD+B3&&mwEzGB07*qoM6N<$g5r&`&j0`b literal 0 HcmV?d00001 diff --git a/images/icone_chd.png b/images/icone_chd.png new file mode 100644 index 0000000000000000000000000000000000000000..ea79d7e03a0839e00c52cb6a46a7a6dfc599e26e GIT binary patch literal 407 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Y)RhkE)4%c zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmPiH>041>c^y{G@y`ViEBiObAE1a zYF-J0b5UwyNotBhd1gt5g1e`0KzJjcI8f0iPZ!6Kh{JEM*m^N13LN`5e^HaztaFDB z#l08!AR(5dUd152QAFpc^Npw(PG1DN)CK-H@h2=&$}*lfeS=E(LsM+SbD40L_J``u^uTRV8F zoyP_|bC2`a7YiJ{&7AjgIh)rv=lj}6XA6kCB_tSrc^y>4UASmjW1ZoN11T@occoSI z*u-y6Jg&7!?{0LR2Cs~Job16Zxvq9vN7>e0ILMZ^*n76c&!w6XugqDK-jp5ou>N)+ uScHE!yVZ{F{I%h48&y0fsr=ku!)Sjt#`uA(`%0ki89ZJ6T-G@yGywpBNtoLJ literal 0 HcmV?d00001 diff --git a/images/matrix.png b/images/matrix.png new file mode 100644 index 0000000000000000000000000000000000000000..ddff27edfc3041486446e36c3c0afea163ec6c86 GIT binary patch literal 455 zcmV;&0XY7NP)QV)Bpeg8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10YpheK~y-6wUW(B!%z@~XYS9W#d=p&= zqT-@1#ZnvF+MhJdy}9E?5b8~J#NJ&s{OnN9?|m^>C-s}JXuLtn)0v9K@HI~-bN3>KEh(C+p+F*T|N={=6duIR)xSr5y0%6Z03qOMX z*ptfEM0PrA8V+i^OSapG#H-&Q2a2ZX#2##_rqiH3Aqns7%!r8{iAE;$u>l0wT x^4aJpXGLi;kDksWUqYve5Kg(ON1}0S@(E!Gm{`X-gDU_4002ovPDHLkV1h&qzvTb` literal 0 HcmV?d00001 diff --git a/images/matroot.png b/images/matroot.png new file mode 100644 index 0000000000000000000000000000000000000000..45da44a5331c17f11353ff48c305d502a95af1ae GIT binary patch literal 453 zcmV;$0XqJPP)QV)Bpeg8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10YXVcK~y-6mD9g!R6!iY@z2bi-0UVBvu1@@iA}^x#LC8Z$UA6Z zXX!Io*!v=aAc$ZSZ3M9iK?^Ym+eF+oS$FY{g;?F6|9<6shcoB!JCodWl=fW^%`2@N zmP$x@Y*x}OI~VU8ZwCD20poi%(xA^4IG!04i2+7|z-eN$k^}bZtT?nbd&DZZ^!0!= zB(3$?3iYj~xMH<+m+e5Hn=!df-U!@b`qB5u-G5D~N7_F|Xi4jRwnBZQDQVC0w-M${ z?vR5O{ab{D`j-f%n#FUP050D#e?cDh*#bVuMXTmLL@f@?j~|AAiI?*9R3|7Bcj=`t}h$fB&cs2Z|1qVW9Yh$u|q2A*|hLi0ZWA-FIDa z5=I?Qa6FkwVgba!=99LZyIa;&X@cHwhlD{GCvsxJCJl=>a#}hw7hQH+L%zP;XY2Vd z5D+7XK&F-;Q~4(YH)#ku(`*Y@vfBFCGaKt|R6#=ph2xjAWGb#sEAWM&rvgMlXsDFW z&Z+ecA|tECMPF+d(h-R{XkpNuRHCtgWt-q7m}{Hs_{dZ09;zGj#(nMS1Y^nX62iF zd9fdz`2|aU!8;5vt1@L*y{seeS6h+s;whi}f)@eC0@Rms)R%IxCZutzy17@gp@Im2 p0aZqfe|c5LyYVV0NVyTXe*i1mrWc6FZKD7H002ovPDHLkV1obF2n_%L literal 0 HcmV?d00001 diff --git a/images/simimatrix.png b/images/simimatrix.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2e3d618f0bc8f5530fcf7a0a0aebc5558fc902 GIT binary patch literal 622 zcmV-!0+IcRP)V?wT-w?r{$wf!7BR=s=c1)!a_H2~Qu~uum zgie*GOD1zJ+5QS5>gjLw|E4|7u`N=)tLd90& zg6j@a;ktiHbaYVNGMCnZrUi;X*4Xt3g=m!_1?w`(@<+|{3;WZxj;T?Hg#Z8m07*qo IM6N<$g2{#!d;kCd literal 0 HcmV?d00001 diff --git a/textchdalc.py b/textchdalc.py deleted file mode 100644 index 9e8b4ad..0000000 --- a/textchdalc.py +++ /dev/null @@ -1,299 +0,0 @@ -#!/bin/env python -# -*- coding: utf-8 -*- -#Author: Pierre Ratinaud -#Copyright (c) 2008-2009 Pierre Ratinaud -#Lisense: GNU/GPL - -from chemins import ConstructPathOut, ChdTxtPathOut -from OptionAlceste import OptionAlc -import wx -import os -from ConfigParser import RawConfigParser -import sys -from functions import sortedby, print_liste, CreateIraFile, exec_rcode, ReadDicoAsDico, check_Rresult -from dialog import PrefGraph -from layout import OpenCHDS, PrintRapport -from PrintRScript import RchdTxt, AlcesteTxtProf -from openanalyse import OpenAnalyse -from corpus import Corpus -from guifunct import getPage, getCorpus -from time import time, sleep - -class AnalyseAlceste : - def __init__(self,parent, cmd = False, big = False): - self.conf = None - self.parent = parent - self.type = 'alceste' - self.cmd = cmd - self.big = big - #page = getPage(self.parent) - #if page is not None : - # self.corpus = getCorpus(page) - # print self.corpus.parametre - #else : - try : - self.corpus = Corpus(parent) - self.corpus.parametre['encodage'] = parent.corpus_encodage - self.corpus.parametre['lang'] = parent.corpus_lang - self.corpus.parametre['filename'] = parent.filename - self.ConfigPath = parent.ConfigPath - self.DictPath = parent.DictPath - self.AlcesteConf = RawConfigParser() - self.AlcesteConf.read(self.ConfigPath['alceste']) - self.KeyConf = RawConfigParser() - self.KeyConf.read(self.ConfigPath['key']) - if not cmd : - self.dial = OptionAlc(self, parent) - self.dial.CenterOnParent() - self.val = self.dial.ShowModal() - self.print_alceste_parametre() - self.dial.Destroy() - else : - self.val = wx.ID_OK - if self.val == wx.ID_OK : - pathout = ConstructPathOut(self.corpus.parametre['filename'], 'alceste') - self.dictpathout = ChdTxtPathOut(pathout) - self.read_alceste_parametre() - self.KeyConf.read(self.ConfigPath['key']) - self.corpus.supplementaires = [option for option in self.KeyConf.options('KEYS') if self.KeyConf.get('KEYS', option) == "2"] - self.corpus.typeactive = [option for option in self.KeyConf.options('KEYS') if self.KeyConf.get('KEYS', option) == "1"] - self.make_analyse() - except AttributeError : - wx.MessageBox(u'Vous devez charger un corpus\nFichier -> Ouvrir un texte', u'Pas de corpus', wx.OK|wx.ICON_INFORMATION) - self.val = False - - def load_corpus(self): - self.corpus.read_formes() - self.corpus.read_lems() - self.corpus.read_ucis_paras_uces() - self.corpus.read_parametre() - - def print_alceste_parametre(self): - self.conf = RawConfigParser() - self.conf.read(self.parent.ConfigPath['alceste']) - lem = self.dial.radio_1.GetSelection() - expressions = self.dial.radio_exp.GetSelection() - if lem == 0 : lem = 'True' - else : lem = 'False' - if expressions == 0 : expressions = 'True' - else : expressions = 'False' - self.AlcesteConf.set('ALCESTE','lem',lem) - self.AlcesteConf.set('ALCESTE', 'expressions', expressions) - self.AlcesteConf.set('ALCESTE', 'classif_mode', str(self.dial.radio_box_2.GetSelection())) - self.AlcesteConf.set('ALCESTE', 'tailleuc1', str(self.dial.spin_ctrl_1.GetValue())) - self.AlcesteConf.set('ALCESTE', 'tailleuc2', str(self.dial.spin_ctrl_2.GetValue())) - self.AlcesteConf.set('ALCESTE', 'nbforme_uce', str(self.dial.spin_ctrl_3.GetValue())) - self.AlcesteConf.set('ALCESTE', 'mincl', str(self.dial.spin_ctrl_4.GetValue())) - self.AlcesteConf.set('ALCESTE', 'minforme', str(self.dial.spin_ctrl_5.GetValue())) - self.AlcesteConf.set('ALCESTE', 'nbcl_p1', str(self.dial.spin_nbcl.GetValue())) - self.AlcesteConf.set('ALCESTE', 'max_actives', str(self.dial.spin_max_actives.GetValue())) - with open(self.parent.ConfigPath['alceste'], 'w') as f: - self.AlcesteConf.write(f) - with open(self.parent.ConfigPath['key'], 'w') as f: - self.KeyConf.write(f) - - def read_alceste_parametre(self) : - self.conf = RawConfigParser() - self.conf.read(self.parent.ConfigPath['alceste']) - for option in self.conf.options('ALCESTE') : - if self.conf.get('ALCESTE', option).isdigit() : - self.corpus.parametre[option] = int(self.conf.get('ALCESTE', option)) - else : - self.corpus.parametre[option] = self.conf.get('ALCESTE', option) - - list_bool = ['lem', 'expressions'] - for var in list_bool : - if self.corpus.parametre[var] == 'True' : - self.corpus.parametre[var] = True - else : - self.corpus.parametre[var] = False - - def make_analyse(self) : - t1 = time() - if not self.big : - self.corpus.content = self.parent.content - if not self.cmd : - self.dlg = wx.ProgressDialog("Traitements", - "Veuillez patienter...", - maximum=9, - parent=self.parent, - style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE | wx.PD_ELAPSED_TIME | wx.PD_CAN_ABORT - ) - self.dlg.Center() - else : - self.dlg = None - ucis_txt, ucis_paras_txt = self.corpus.start_analyse(self.parent, dlg = self.dlg, cmd = self.cmd) - # #print('ATTENTION PHRASE') - # #ucis_paras_txt = self.corpus.make_ucis_paras_txt_phrases(para_coords, ucis_lines, ucis_txt) - # del ucis_lines - - #FIXME - self.corpus.make_len_uce(self.corpus.get_tot_occ_from_ucis_txt(ucis_txt)) - del ucis_txt - - if not self.cmd : - self.dlg.Update(5, '%i ucis - Construction des uces' % len(self.corpus.ucis)) - - if self.corpus.parametre['classif_mode'] in [0,1] : - self.corpus.make_ucis_paras_uces(ucis_paras_txt, make_uce = True) - #self.corpus.make_ucis_paras_uces_sentences(ucis_paras_txt, make_uce = True) - else : - self.corpus.make_ucis_paras_uces(ucis_paras_txt, make_uce = False) - del ucis_paras_txt - - print 'len(ucis_paras_uces', len(self.corpus.ucis_paras_uces) - - if not self.cmd : - self.dlg.Update(6, u'Dictionnaires') - uces, orderuces = self.corpus.make_forms_and_uces() - - print len(uces) - print len(orderuces) - self.corpus.ucenb = len(uces) - print 'len(uces)',len(uces) - #ucis_paras_uces_lems = self.corpus.make_ucis_paras_uces_lems(lexique) - self.corpus.make_lems(self.parent.lexique) - - #---------------------------------------------- - #self.corpus.make_eff_min_forme() - #self.corpus.parametre['max_actives'] = 1500 - self.corpus.min_eff_formes() - #---------------------------------------------- - - self.corpus.make_var_actives() - - self.corpus.make_var_supp() - - if not self.cmd : - self.dlg.Update(7, u'Creation des tableaux') - if self.corpus.parametre['classif_mode'] == 1 : - #tabuc1 = self.corpus.make_sparse_matrix_with_uce(orderuces) - #self.corpus.write_sparse_matrix(self.dictpathout['TableUc1'], tabuc1, len(orderuces), len(self.corpus.actives)) - #print time() - tps1 - #tps2 = time() - self.corpus.make_and_write_sparse_matrix_from_uce(orderuces, self.dictpathout['TableUc1']) - #print time() - tps2 - - #tabuc1 = self.corpus.make_table_with_uce(orderuces) - uc1 = None - uces1 = [[uce, orderuces[uce]] for uce in orderuces] - uces1 = sortedby(uces1, 1) - self.corpus.lenuc1 = len(uces1) - #uces1.sort() - self.corpus.write_tab([[u'uce',u'uc']] + [[i, i] for i in range(0,len(uces))], self.dictpathout['listeuce1']) - elif self.corpus.parametre['classif_mode'] == 0 : - self.corpus.lenuc1, uces_uc1 = self.corpus.make_uc(uces, orderuces, self.corpus.parametre['tailleuc1']) - print 'len uc1 : ', self.corpus.lenuc1 - uces1 = [[uce,uces_uc1[uce]] for uce in orderuces] - uces1 = sortedby(uces1, 1) - self.corpus.write_tab([[u'uce',u'uc']] + [[i, val[1]] for i, val in enumerate(uces1)], self.dictpathout['listeuce1']) - #tabuc1 = self.corpus.make_tab_uc(uces_uc1, uc1) - self.corpus.make_and_write_sparse_matrix_from_uc(uces_uc1, self.dictpathout['TableUc1']) - elif self.corpus.parametre['classif_mode'] == 2 : - #tabuc1 = self.corpus.make_table_with_uci() - self.corpus.make_and_write_sparse_matrix_from_uci(self.dictpathout['TableUc1']) - uc1 = None - uces1 = [[uce, orderuces[uce]] for uce in orderuces] - uces1 = sortedby(uces1, 1) - self.corpus.lenuc1 = len(uces1) - self.corpus.write_tab([[u'uce',u'uc']] + [[i, i] for i in range(0,len(orderuces))], self.dictpathout['listeuce1']) - - #self.corpus.write_sparse_matrix(self.dictpathout['TableUc1'], tabuc1, len(orderuces), len(self.corpus.actives)) - #self.corpus.write_tab(tabuc1,self.dictpathout['TableUc1']) - - if self.corpus.parametre['classif_mode'] == 0 : - self.corpus.lenuc2, uces_uc2 = self.corpus.make_uc(uces, orderuces, self.corpus.parametre['tailleuc2']) - print 'len uc2 :', self.corpus.lenuc2 - #tabuc2 = self.corpus.make_tab_uc(uces_uc2, uc2) - self.corpus.make_and_write_sparse_matrix_from_uc(uces_uc2, self.dictpathout['TableUc2']) - #self.corpus.write_tab(tabuc2, self.dictpathout['TableUc2']) - uces2 = [[uce, uces_uc2[uce]] for uce in orderuces] - uces2 = sortedby(uces2, 1) - self.corpus.write_tab([[u'uce',u'uc']] + [[i, val[1]] for i, val in enumerate(uces2)], self.dictpathout['listeuce2']) - - if sys.platform == 'win32' : - try : - if self.parent.pref.getboolean('iramuteq', 'R_mem') : - R_max_mem = self.parent.pref.getint('iramuteq','R_max_mem') - else : - R_max_mem = False - except : - R_max_mem = False - else : - R_max_mem = False - RchdTxt(self.dictpathout, self.parent.RscriptsPath, self.corpus.parametre['mincl'], self.corpus.parametre['classif_mode'], nbt = self.corpus.parametre['nbcl_p1'] - 1, libsvdc = self.parent.pref.getboolean('iramuteq','libsvdc'), libsvdc_path = self.parent.pref.get('iramuteq','libsvdc_path'), R_max_mem = R_max_mem) - - pid = exec_rcode(self.parent.RPath,self.dictpathout['Rchdtxt'],wait = False) - while pid.poll() == None : - if not self.cmd : - self.dlg.Pulse(u'CHD...') - sleep(0.2) - else : - sleep(0.2) - check_Rresult(self.parent, pid) - if not self.cmd : - self.dlg.Update(7, u'Profils') - ucecl = self.corpus.read_uce_from_R(self.dictpathout['uce']) - ucecl0 = [cl for uce,cl in ucecl if cl != 0] - clnb = len(list(set(ucecl0))) - classes = [cl for uce, cl in ucecl] - uces1 = [val for val, i in uces1] - - self.corpus.make_lc(uces1, classes, clnb) - self.corpus.build_profile(clnb, classes, self.corpus.actives, self.dictpathout['Contout']) - - #passives = [lem for lem in self.corpus.lems if lem not in self.corpus.actives] - self.corpus.build_profile(clnb, classes, self.corpus.supp, self.dictpathout['ContSupOut']) - - self.corpus.make_etoiles(self.corpus.para_coords) - - self.corpus.build_profile_et(clnb, classes, uces1, self.dictpathout['ContEtOut']) - - AlcesteTxtProf(self.dictpathout, self.parent.RscriptsPath, clnb, '0.9') - - pid = exec_rcode(self.parent.RPath, self.dictpathout['RTxtProfGraph'],wait = False) - while pid.poll() == None : - if not self.cmd : - self.dlg.Pulse(u'AFC...') - sleep(0.2) - else : - pass - check_Rresult(self.parent, pid) - - self.corpus.dictpathout = self.dictpathout - - if not self.cmd : - self.dlg.Update(8, u'rapport') - - temps = time() - t1 - self.corpus.minutes, self.corpus.seconds = divmod(temps, 60) - self.corpus.hours, self.corpus.minutes = divmod(self.corpus.minutes, 60) - - PrintRapport(self.corpus, 'txt') - - CreateIraFile(self.dictpathout, clnb, os.path.basename(self.corpus.parametre['filename'])) - - self.corpus.save_corpus(self.dictpathout['db']) - - afc_graph_list = [[os.path.basename(self.dictpathout['AFC2DL_OUT']), u'Variables actives - coordonnées - facteurs 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DSL_OUT']), u'variables supplémentaires - coordonnées - facteurs 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DEL_OUT']), u'Variables illustratives - Coordonnées - facteur 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DCL_OUT']), u'Classes - Coordonnées - facteur 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DCoul']), u'Variables actives - Corrélation - facteur 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DCoulSup']), u'Variables supplémentaires - Corrélation - facteur 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DCoulEt']), u'Variables illustratives - Corrélations - facteur 1 / 2'], - [os.path.basename(self.dictpathout['AFC2DCoulCl']), u'Classes - Corrélations - facteurs 1 / 2'],] - chd_graph_list = [[os.path.basename(self.dictpathout['dendro1']), u'dendrogramme à partir de chd1']] - if self.corpus.parametre['classif_mode'] == 0 : - chd_graph_list.append([os.path.basename(self.dictpathout['dendro2']), u'dendrogramme à partir de chd2']) - chd_graph_list.append([os.path.basename(self.dictpathout['arbre1']), u'chd1']) - if self.corpus.parametre['classif_mode'] == 0 : - chd_graph_list.append([os.path.basename(self.dictpathout['arbre2']), u'chd2']) - print_liste(self.dictpathout['liste_graph_afc'],afc_graph_list) - print_liste(self.dictpathout['liste_graph_chd'],chd_graph_list) - if not self.cmd : - self.dlg.Update(9, u'fin') - self.dlg.Destroy() - OpenAnalyse(self.parent, self.dictpathout['ira']) - else : - self.corpus.make_big() diff --git a/vitemspicker.py b/vitemspicker.py new file mode 100644 index 0000000..d385210 --- /dev/null +++ b/vitemspicker.py @@ -0,0 +1,267 @@ +''' +Created on Oct 3, 2010 + +@authors: Daphna Rosenbom,Gitty Zinger,Moshe Cohavi and Yoav Glazner +The widget is contributed by NDS ltd under the same license as wxPython + +items_picker.ItemsPicker: +- Displays available items to choose from, +- Selection is done by the Add button or Double Click, +- De-Selection is done by the Remove button or Double Click, + +Derived from wxPanel +''' +import wx +from listlex import ListForSpec +__version__ = 0.1 + +IP_DEFAULT_STYLE = 0 +IP_SORT_CHOICES = 1 +IP_SORT_SELECTED = 2 +IP_REMOVE_FROM_CHOICES = 4 + + +wxEVT_IP_SELECTION_CHANGED = wx.NewEventType() +EVT_IP_SELECTION_CHANGED = wx.PyEventBinder(wxEVT_IP_SELECTION_CHANGED, 1) +LB_STYLE = wx.LB_EXTENDED|wx.LB_HSCROLL + + +class IpSelectionChanged(wx.PyCommandEvent): + def __init__(self, id, items, object = None): + wx.PyCommandEvent.__init__(self, wxEVT_IP_SELECTION_CHANGED, id) + self.__items = items + self.SetEventObject(object) + + def GetItems(self): + return self.__items + + +class VItemsPicker(wx.Panel): + ''' +ItemsPicker is a widget that allows the user to form a set of picked +items out of a given list +''' + def __init__(self, parent, id=wx.ID_ANY, choices = [], + label = '', selectedLabel = '', + ipStyle = IP_DEFAULT_STYLE, + *args, **kw): + ''' +ItemsPicker(parent, choices = [], label = '', selectedLabel = '', +ipStyle = IP_DEFAULT_STYLE) +''' + self.parent = parent + self._destData = {} + wx.Panel.__init__(self, parent, id, *args, **kw) + self._ipStyle = ipStyle + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self._CreateSourceList(choices, label), 1, + wx.EXPAND|wx.ALL, 5) + sizer.Add(self._CreateButtons(), 0, wx.ALIGN_CENTER|wx.ALL, 5) + sizer.Add(self._CreateDestList(selectedLabel), 1, + wx.EXPAND|wx.ALL, 5) + self.SetSizer(sizer) + + + def SetItems(self, items): + '''SetItems(self, items)=> None +items - Sequence of strings that the user can pick from''' + pass + #return self._source.SetItems(items) + + + def GetItems(self): + '''GetItems(self)=> items +returns list of strings that the user can pick from''' + return self._source.GetItems() + + + Items = property(fget = GetItems, + fset = SetItems, + doc = 'See GetItems/SetItems') + + + def GetSelections(self): + '''GetSelections(self)=>items +returns list of strings that were selected +''' + return [self._destData[i][0] for i in self._destData] + + + def SetSelections(self, items): + '''SetSelections(self, items)=>None +items - Sequence of strings to be selected +The items are displayed in the selection part of the widget''' + assert len(items)==len(set(items)),"duplicate items are not allowed" + if items != self._dest.GetItems(): + self._dest.SetItems(items) + self._FireIpSelectionChanged() + + + Selections = property(fget = GetSelections, + fset = SetSelections, + doc = 'See GetSelections/SetSelections') + + + def _CreateButtons(self): + sizer = wx.BoxSizer(wx.VERTICAL) + self.bAdd = wx.Button(self, -1, label = 'Add ->') + self.bAdd.Bind(wx.EVT_BUTTON, self._OnAdd) + self.bRemove = wx.Button(self, -1, label = '<- Remove') + self.bRemove.Bind(wx.EVT_BUTTON, self._OnRemove) + sizer.Add(self.bAdd, 0, wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) + sizer.Add(self.bRemove, 0, wx.EXPAND|wx.ALL, 5) + return sizer + + + def _set_add_button_label(self, label=None): + if label is None: + return + self.bAdd.SetLabel(label) + + add_button_label = property(fset = _set_add_button_label, fget = lambda x:x) + + + def _set_remove_button_label(self, label=None): + if label is None: + return + self.bRemove.SetLabel(label) + + remove_button_label = property(fset = _set_remove_button_label, fget = lambda x:x) + + + def _OnAdd(self, e): + if self._ipStyle & IP_REMOVE_FROM_CHOICES: + self._MoveItems(self._source,self._dest) + else: + self._AddSelectedItems() + + def _MoveItems(self,source,dest): + selections = source.GetSelections() + selectedItems = map(source.GetString, selections) + dest.SetItems(dest.GetItems() + selectedItems) + selections = set(selections) + #source.SetItems([item for i, item in enumerate(source.GetItems())\ + # if i not in selections]) + self._FireIpSelectionChanged() + + def _AddSelectedItems(self): + newItems = self._source.getselectedwords()#map(self._source.GetString, self._source.GetSelections()) + items = [self._destData[i][0] for i in self._destData] + oldItems = set(items) + for newItem in newItems: + if newItem not in oldItems: + self._destData[len(self._destData)] = [newItem, ''] + self._SetDestItems() + self._source.selected[newItem] = 1 + self._source.Refresh() + #self.SetSelections(items) + self._FireIpSelectionChanged() + + def _FireIpSelectionChanged(self): + self.GetEventHandler().ProcessEvent( + IpSelectionChanged(self.GetId(), + None, + self )) + + + def _OnRemove(self, e): + if self._ipStyle & IP_REMOVE_FROM_CHOICES: + self._MoveItems(self._dest, self._source) + else: + self._RemoveSelected() + + def _RemoveSelected(self): + selections = self._dest.getselectedwords() + if selections: + #allItems = self._dest.GetItems() + #items = [item for i, item in enumerate(allItems)\ + # if i not in selections] + #notselected = [item for i, item in enumerate(allItems)\ + # if i in selections] + + for item in selections : + del self._source.selected[item] + tokeep = [self._destData[i][0] for i in self._destData if self._destData[i][0] not in selections] + self._destData = dict([[i, [word, '']] for i, word in enumerate(tokeep)]) + self._source.Refresh() + self._SetDestItems() + #self.SetSelections(items) + self._FireIpSelectionChanged() + + + def _CreateSourceList(self, items, label): + style = LB_STYLE + if self._ipStyle & IP_SORT_CHOICES: + style |= wx.LB_SORT + sizer = wx.BoxSizer(wx.VERTICAL) + if label: + sizer.Add(wx.StaticText(self, label = label), 0, + wx.ALIGN_LEFT|wx.ALL, 5) + #self._source = wx.VListBox(self, -1, style = style) + self._source = ListForSpec(self, self.parent, dlist = items, first = ['eff'], menu = True) + self._source.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick) + #self._source.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick) + #self._source.SetItems(items) + sizer.Add(self._source, 1, wx.EXPAND|wx.ALL, 5) + return sizer + + + def _CreateDestList(self, label): + style = LB_STYLE + if self._ipStyle & IP_SORT_SELECTED: + style |= wx.LB_SORT + sizer = wx.BoxSizer(wx.VERTICAL) + if label: + sizer.Add(wx.StaticText(self, label = label), 0, + wx.ALIGN_LEFT|wx.ALL, 5) + #self._dest = wx.ListBox(self, -1, style = style) + self._dest = ListForSpec(self, self.parent, dlist = {}, first = ['eff'], menu = True) + self._dest.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick) + #self._dest.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick) + sizer.Add(self._dest, 1, wx.EXPAND|wx.ALL, 5) + return sizer + + def _SetDestItems(self): + self._dest.itemDataMap = self._destData + self._dest.itemIndexMap = self._destData.keys() + self._dest.SetItemCount(len(self._destData)) + self._dest.Refresh() + + def _OnDClick(self, e): + lb = e.GetEventObject() + selections = lb.GetSelections() + if len(selections) != 1: + return #DCLICK only works on one item + #if e.GetSelection() != selections[0]: + #this can happen using ^DCLICK when two items are selected + # return + if lb == self._source: + self._OnAdd(e) + else: + self._OnRemove(e) + + + + +if __name__ == '__main__': + print 'ezerzerzer' + test = wx.App(0) + frame = wx.Frame(None, -1) + d = wx.Dialog(frame, style = wx.RESIZE_BORDER|wx.DEFAULT_DIALOG_STYLE) + + d.sizer = wx.BoxSizer(wx.VERTICAL) + d.sizer.Add(wx.StaticText(d, -1, label = 'Example of the ItemsPicker'), + 0, wx.ALL, 10) + ip = ItemsPicker(d, -1, ['pop', 'cool', 'lame'], + 'Stuff:', 'Selected stuff:',IP_SORT_SELECTED|IP_SORT_CHOICES|IP_REMOVE_FROM_CHOICES) + ip.add_button_label = u'left -> right' + ip.remove_button_label = u'right -> left' + d.sizer.Add(ip, 1, wx.EXPAND, 1) + d.SetSizer(d.sizer) + test.SetTopWindow(frame) + def callback(e): + print 'selected items', e.GetItems() + d.Bind(EVT_IP_SELECTION_CHANGED, callback) + d.ShowModal() + d.Destroy() + frame.Close() \ No newline at end of file -- 2.7.4