예제 #1
0
class ConcurrentWindow(wx.Panel, Mixin.Mixin):
    __mixinname__ = 'concurrent'
    concurrent_id = 0

    def __init__(self, parent):
        self.initmixin()

        wx.Panel.__init__(self, parent, -1)

        self.mainframe = Globals.mainframe
        self.pref = self.mainframe.pref

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer1 = wx.BoxSizer(wx.HORIZONTAL)

        if not self.pref.pairprog_username:
            self.pref.pairprog_username = self.pref.personal_username

        sizer1.Add(wx.StaticText(self, -1,
                                 tr("Name") + ':'), 0,
                   wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 2)
        self.txtName = wx.TextCtrl(self,
                                   -1,
                                   self.pref.pairprog_username,
                                   size=(100, -1))
        sizer1.Add(self.txtName, 0,
                   wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 2)
        sizer1.Add(wx.StaticText(self, -1,
                                 tr("Host") + ':'), 0,
                   wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 2)
        self.txtIP = wx.TextCtrl(self,
                                 -1,
                                 self.pref.pairprog_host,
                                 size=(150, -1))
        sizer1.Add(self.txtIP, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 2)
        sizer1.Add(wx.StaticText(self, -1,
                                 tr("Port") + ':'), 0,
                   wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 2)
        self.txtPort = wx.SpinCtrl(self,
                                   min=1,
                                   max=65536,
                                   value=str(self.pref.pairprog_port))
        sizer1.Add(self.txtPort, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 2)
        self.btnStart = wx.Button(self, -1, tr("Start Server"))
        sizer1.Add(self.btnStart, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 2)
        self.btnConnect = wx.Button(self, -1, tr("Connect Server"))
        sizer1.Add(self.btnConnect, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 2)

        sizer.Add(sizer1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 2)

        self.splitter = MultiSplitterWindow(self, -1)

        userpanel = UserPanel(self.splitter)
        self.splitter.AppendWindow(userpanel, 200)
        self.userlist = userpanel.list

        filelistpanel = FileListPanel(self.splitter)
        self.splitter.AppendWindow(filelistpanel, 150)
        self.filelist = filelistpanel.list

        chatpanel = ChatPanel(self.splitter)
        self.splitter.AppendWindow(chatpanel)
        self.chat = chatpanel.chat
        self.chatroom = chatpanel.chatroom
        self.btnSend = chatpanel.btnSend
        self.btnClear = chatpanel.btnClear
        self.btnSave = chatpanel.btnSave
        self.splitter.SetMinimumPaneSize(150)
        self.splitter.SetOrientation(wx.HORIZONTAL)

        sizer.Add(self.splitter, 1, wx.EXPAND | wx.ALL, 2)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)

        self.btnStart.Bind(wx.EVT_BUTTON, self.OnStart)
        self.btnConnect.Bind(wx.EVT_BUTTON, self.OnConnect)
        self.btnSend.Bind(wx.EVT_BUTTON, self.OnSend)
        self.btnClear.Bind(wx.EVT_BUTTON, self.OnClear)
        self.btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
        self.filelist.Bind(wx.EVT_RIGHT_DOWN, self.OnFilelistRClick)
        self.userlist.Bind(wx.EVT_RIGHT_DOWN, self.OnUserlistRClick)
        self.chat.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

        self.status = ''
        self.server = None
        self.client = None
        self.servercommands = ServerCommands(self)
        self.clientcommands = ClientCommands(self)
        self.users = {}
        self.files = {}
        self.cmdrecorder = CommandRecord.CommandRecord()
        self.filelistpopmenus = None
        self.userlistpopmenus = None

    def __get_me(self):
        return self.txtName.GetValue()

    me = property(__get_me)

    def OnStart(self, event=None):
        if not self.status:
            if not self.me or self.me == '*':
                common.showerror(self,
                                 tr("Username should not be empty or '*'"))
                self.txtName.SetFocus()
                return

            ip = self.txtIP.GetValue()
            if not ip:
                common.showerror(self, tr("Host address cannot be empty!"))
                self.txtIP.SetFocus()
                return
            port = int(self.txtPort.GetValue())
            self.pref.pairprog_host = ip
            self.pref.pairprog_port = port
            self.pref.pairprog_username = self.me
            self.pref.save()
            try:
                self.server = Server.start_server(ip, port,
                                                  self.servercommands)
                if self.server:
                    self.AddUser(self.me, manager=True)
                    self.change_status('startserver')
                    self.callplugin('start', self, 'server')
            except:
                common.warn(tr("Start server error!"))
                error.traceback()
        else:
            self.server.shut_down()
            self.server = None
            self.change_status('stopserver')
            self.callplugin('stop', self, 'server')

    def OnConnect(self, event=None):
        if not self.status:
            if not self.me or self.me == '*':
                common.showerror(self,
                                 tr("Username should not be empty or '*'"))
                self.txtName.SetFocus()
                return

            ip = self.txtIP.GetValue()
            if not ip:
                common.showerror(self, tr("Host address cannot be empty!"))
                self.txtIP.SetFocus()
                return
            port = int(self.txtPort.GetValue())
            self.pref.pairprog_host = ip
            self.pref.pairprog_port = port
            self.pref.pairprog_username = self.me
            self.pref.save()
            #            try:
            self.client = Client.start_client(ip, port, self.clientcommands)
            if self.client:
                self.client.call('join', self.me)

                self.change_status('connectserver')
                self.callplugin('start', self, 'client')


#            except:
#                common.warn(tr("Connect to server error!"))
#                error.traceback()
        else:
            self.client.close()
            self.client = None
            self.change_status('disconnectserver')
            self.callplugin('stop', self, 'client')

    def OnSend(self, event=None):
        message = self.chat.GetValue()
        self.chat.SetValue('')
        if message:
            self.put_message(self.me, message)
            if self.status == 'startserver':  #server
                self.server.broadcast('message', self.me, message)
            else:
                self.client.call('message', self.me, message)

    def OnClear(self, event=None):
        self.chatroom.SetReadOnly(0)
        self.chatroom.SetText('')
        self.chatroom.SetReadOnly(1)

    def OnClose(self, win):
        if self.status == 'startserver':
            self.OnStart()
        elif self.status == 'connectserver':
            self.OnConnect()

    def OnSave(self, event=None):
        filename = None
        dlg = wx.FileDialog(self, tr("Save File"), self.pref.last_dir, '',
                            'Text file|*.txt', wx.SAVE | wx.OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            filename = dlg.GetPath()
            dlg.Destroy()
        if filename:
            try:
                file(filename,
                     'w').write(self.chatroom.GetText().encode('utf-8'))
            except:
                common.warn(tr("There is error as saving the file"))
            else:
                common.note(tr("Finished!"))

    def OnFilelistRClick(self, event):
        pt = event.GetPosition()
        item, flags = self.filelist.HitTest(pt)
        if item > -1:
            self.filelist.Select(item)
        if self.status == 'startserver':
            popmenulist = [
                (None, [
                    (10, 'IDPM_ADD', tr('Add Current Document'),
                     wx.ITEM_NORMAL, 'OnAddDocument', ''),
                    (20, 'IDPM_REMOVE', tr('Remove Document'), wx.ITEM_NORMAL,
                     'OnRemoveDocument', ''),
                ]),
            ]
        else:
            popmenulist = [
                (None, [
                    (10, 'IDPM_REGET', tr('Reget Document'), wx.ITEM_NORMAL,
                     'OnRegetDocument', ''),
                ]),
            ]

        other_menus = []
        if self.filelistpopmenus:
            self.filelistpopmenus.Destroy()
            self.filelistpopmenus = None
        self.callplugin('other_filelist_popup_menu', self, other_menus)
        import copy
        if other_menus:
            pop_menus = copy.deepcopy(popmenulist + other_menus)
        else:
            pop_menus = copy.deepcopy(popmenulist)
        self.filelistpopmenus = makemenu.makepopmenu(self, pop_menus)

        self.filelist.PopupMenu(self.filelistpopmenus)

    def OnUserlistRClick(self, event):
        pt = event.GetPosition()
        item, flags = self.userlist.HitTest(pt)
        if item > -1:
            self.userlist.Select(item)
        popmenulist = [
            (None, [
                (10, 'IDPM_KICK', tr('Kick User'), wx.ITEM_NORMAL,
                 'OnKickUser', ''),
            ]),
        ]

        other_menus = []
        if self.userlistpopmenus:
            self.userlistpopmenus.Destroy()
            self.userlistpopmenus = None
        self.callplugin('other_userlist_popup_menu', self, other_menus)
        import copy
        if other_menus:
            pop_menus = copy.deepcopy(popmenulist + other_menus)
        else:
            pop_menus = copy.deepcopy(popmenulist)
        self.userlistpopmenus = makemenu.makepopmenu(self, pop_menus)

        self.filelist.PopupMenu(self.userlistpopmenus)

    def OnAddDocument(self, event):
        document = self.mainframe.editctrl.getCurDoc()
        if not self.has_document(document):
            filename = document.getShortFilename()
            index = self.filelist.addline([filename])
            ConcurrentWindow.concurrent_id += 1
            _id = ConcurrentWindow.concurrent_id
            self.filelist.SetItemData(index, _id)
            self.files[_id] = document
            self.cmdrecorder.add_document(_id, document)

            def f(self):
                self.server.broadcast('update_files', self.__get_filelist())
                self.server.broadcast('editcmd', 'openfile',
                                      (_id, filename, document.getRawText()))
                self.server.broadcast('editcmd', 'setlex',
                                      (_id, document.languagename))
                self.server.broadcast(
                    'message', '*',
                    tr("%(user)s selects %(filename)s") % {
                        'user': self.me,
                        'filename': filename
                    })

            wx.CallAfter(f, self)

    def OnRemoveDocument(self, event=None):
        index = self.filelist.GetFirstSelected()
        if index > -1:
            filename = self.filelist.GetItem(index, 0).GetText()
            _id = self.filelist.GetItemData(index)
            del self.files[_id]
            self.filelist.DeleteItem(index)
            self.cmdrecorder.remove_document(_id)
            self.server.broadcast('forgivefile', _id)
            self.server.broadcast(
                'message', '*',
                tr('%(user)s discards %(filename)s') % {
                    'user': self.me,
                    'filename': filename
                })
        else:
            if self.filelist.GetItemCount() > 0:
                common.showerror(self, tr("You should select one item first"))
            else:
                common.showerror(self, tr("No item exists"))

    def OnRegetDocument(self, event=None):
        index = self.filelist.GetFirstSelected()
        if index > -1:
            filename = self.filelist.GetItem(index, 0).GetText()
            _id = self.filelist.GetItemData(index)
            del self.files[_id]
            self.cmdrecorder.remove_document(_id)
            self.client.call('regetfile', _id, filename)
        else:
            if self.filelist.GetItemCount() > 0:
                common.showerror(self, tr("You should select one item first"))
            else:
                common.showerror(self, tr("No item exists"))

    def OnKickUser(self, event):
        index = self.userlist.GetFirstSelected()
        if index > -1:
            m = self.userlist.GetItem(index, 0).GetText()
            username = self.userlist.GetItem(index, 1).GetText()
            if m != '*':  #not manager
                _id = self.userlist.GetItemData(index)
                user = self.users[_id]
                addr = user.addr
                username = user.name
                self.userlist.DeleteItem(index)
                del self.users[_id]
                info = tr("User [%s] has been kicked off") % username
                self.put_message('*', info)
                self.server.close_client(addr)
                self.server.broadcastexceptfor(addr, 'message', '*', info)
                self.server.broadcastexceptfor(addr, 'update_users',
                                               self.__get_userlist())
        else:
            if self.filelist.GetItemCount() > 0:
                common.showerror(self, tr("You should select one item first"))
            else:
                common.showerror(self, tr("No item exists"))

    def OnKeyDown(self, event):
        key = event.GetKeyCode()
        shift = event.ShiftDown()
        alt = event.AltDown()
        ctrl = event.ControlDown()
        if key == wx.WXK_RETURN and not shift and not alt and not ctrl:
            self.OnSend()
        elif key == wx.WXK_RETURN and shift and not alt and not ctrl:
            self.chat.WriteText('\n')
        else:
            event.Skip()

    def has_username(self, username):
        for user in self.users.values():
            if user.name == username:
                return True
        else:
            return False

    def has_document(self, document):
        return document in self.files.values()

    def get_doc_id(self, document):
        for _id, doc in self.files.items():
            if doc is document:
                return _id
        else:
            return None

    def change_status(self, status='startserver'):
        self.status = status
        if status == 'startserver':
            self.btnConnect.Enable(False)
            self.btnStart.SetLabel(tr('Stop Server'))
            self.txtName.Enable(False)
            self.txtIP.Enable(False)
            self.txtPort.Enable(False)
            self.userlist.Enable(True)
            self.filelist.Enable(True)
            self.chat.Enable(True)
            self.btnSend.Enable(True)
        elif status == 'stopserver':
            self.btnConnect.Enable(True)
            self.btnStart.SetLabel(tr('Start Server'))
            self.txtName.Enable(True)
            self.txtIP.Enable(True)
            self.txtPort.Enable(True)
            self.userlist.DeleteAllItems()
            self.filelist.DeleteAllItems()
            self.users = {}
            self.files = {}
            self.status = ''
            self.userlist.Enable(False)
            self.filelist.Enable(False)
            self.chat.Enable(False)
            self.btnSend.Enable(False)
            self.cmdrecorder.clear()
        elif status == 'connectserver':
            self.btnConnect.SetLabel(tr('Disconnect Server'))
            self.btnStart.Enable(False)
            self.txtName.Enable(False)
            self.txtIP.Enable(False)
            self.txtPort.Enable(False)
            self.userlist.Enable(False)
            self.filelist.Enable(True)
            self.chat.Enable(True)
            self.btnSend.Enable(True)
        elif status == 'disconnectserver':
            self.btnConnect.SetLabel(tr('Connect Server'))
            self.btnStart.Enable(True)
            self.status = ''
            self.userlist.DeleteAllItems()
            self.filelist.DeleteAllItems()
            self.txtName.Enable(True)
            self.txtIP.Enable(True)
            self.txtPort.Enable(True)
            self.userlist.Enable(False)
            self.filelist.Enable(False)
            self.chat.Enable(False)
            self.btnSend.Enable(False)
            self.users = {}
            self.files = {}
            self.cmdrecorder.clear()

    def put_message(self, username, message):
        self.chatroom.SetReadOnly(0)
        self.chatroom.GotoPos(self.chatroom.GetLength())
        pos = self.chatroom.GetCurrentPos()
        if username == '*':  #system
            name = tr("System")
        else:
            name = username
        txt = name + ' : ' + message + '\n'
        self.chatroom.AddText(txt)
        if username == '*':
            self.chatroom.StartStyling(pos, 0xff)
            self.chatroom.SetStyling(len(txt.encode('utf-8')), 3)
        else:
            self.chatroom.StartStyling(pos, 0xff)
            length = len(name.encode('utf-8'))
            self.chatroom.SetStyling(length, 1)
            self.chatroom.StartStyling(pos + length + 3, 0xff)
            self.chatroom.SetStyling(len(message.encode('utf-8')), 2)

        self.chatroom.SetReadOnly(1)

    def get_user(self, addr):
        for k, user in self.users.items():
            if user.addr == addr:
                return user
        else:
            return None

    def __get_userlist(self):
        items = self.users.items()
        items.sort()
        userlist = []
        for index, user in items:
            userlist.append((user.name, user.manager))
        return userlist

    def __get_filelist(self):
        items = self.files.items()
        items.sort()
        filelist = []
        for index, doc in items:
            filelist.append((doc.getShortFilename(), index))
        return filelist

    def AddUser(self, username, manager=False, addr=None):  #for server
        if self.has_username(username):
            self.server.sendto(
                addr, 'message', '*',
                tr('Username [%s] has also existed! Please try another') %
                username)
            self.server.sendto(addr, 'close')
            return

        user = User(username, manager=manager, addr=addr)

        def f(self):
            if manager:
                m = 'M'
            else:
                m = ''
            index = self.userlist.addline([m, username, ''])
            _id = self.userlist.GetItemData(index)
            self.users[_id] = user
            self.server.broadcast('update_users', self.__get_userlist())
            info = tr("User [%s] has entered the chatroom") % username
            self.put_message('*', info)
            self.server.broadcastexceptfor(addr, 'message', '*', info)
            self.server.sendto(addr, 'message', '*', 'Welcome!')
            self.server.sendto(addr, 'update_files', self.__get_filelist())
            for sid, doc in self.files.items():
                self.server.sendto(
                    addr, 'editcmd', 'openfile',
                    (sid, doc.getShortFilename(), doc.getRawText()))
                self.server.sendto(addr, 'editcmd', 'setlex',
                                   (sid, doc.languagename))

        wx.CallAfter(f, self)

    def UpdateUsers(self, userlist):  #for client
        """
        @param userlist: is a list of list [(username, manager)]
        @type userlist: list
        """
        def f(self):
            self.userlist.DeleteAllItems()
            for username, manager in userlist:
                if manager:
                    m = '*'
                else:
                    m = ''
                self.userlist.addline([m, username, ''])

        wx.CallAfter(f, self)

    def UpdateFiles(self, filelist):  #for client
        def f(self):
            self.filelist.DeleteAllItems()
            for filename, _id in filelist:
                index = self.filelist.addline([filename])
                self.filelist.SetItemData(index, _id)

        wx.CallAfter(f, self)

    def UserQuit(self, addr):  #for server
        for i in range(self.userlist.GetItemCount()):
            _id = self.userlist.GetItemData(i)
            user = self.users[_id]
            if user.addr == addr:  #quit
                username = user.name
                self.userlist.DeleteItem(i)
                del self.users[_id]
                info = tr("User [%s] has left the chatroom") % username
                self.put_message('*', info)
                self.server.broadcastexceptfor(addr, 'message', '*', info)
                self.server.sendto(addr, 'message', '*', 'See you next time!')
                self.server.broadcast('update_users', self.__get_userlist())
                break

    def ServerMessage(self, addr, username, message):  #for server
        def f(self):
            self.put_message(username, message)
            self.server.broadcastexceptfor(addr, 'message', username, message)

        wx.CallAfter(f, self)

    def ClientMessage(self, username, message):  #for client
        def f(self):
            self.put_message(username, message)

        wx.CallAfter(f, self)

    def ServerCommandPlay(self, addr, cmd, para):
        def f(self):
            if addr:
                self.cmdrecorder.do_command(cmd, para)
                self.server.broadcastexceptfor(addr, 'editcmd', cmd, para)
            else:
                self.server.broadcast('editcmd', cmd, para)
            user = self.get_user(addr)
            if user:
                username = user.name
            else:
                username = self.me
            self.ChangeUserAction(username, cmd)
            self.server.broadcast('activing', username, cmd)

        wx.CallAfter(f, self)

    def ClientCommandPlay(self, cmd, para):
        def f(self):
            self.cmdrecorder.do_command(cmd, para)
            if cmd == 'openfile':
                doc = self.cmdrecorder.check_document(para[0])
                self.files[para[0]] = doc

        wx.CallAfter(f, self)

    def RemoveFile(self, _id):  #for client
        def f(self):
            for i in range(self.filelist.GetItemCount()):
                s_id = self.filelist.GetItemData(i)
                if s_id == _id:
                    self.filelist.DeleteItem(i)
                    self.cmdrecorder.remove_document(_id)

        wx.CallAfter(f, self)

    def ClientClose(self):
        self.OnConnect()

    def ServerRegetFile(self, addr, _id, filename):
        self.put_message(
            '*',
            tr("User [%(user)s] asks file [%(filename)s]") % {
                'user': self.get_user(addr).name,
                'filename': filename
            })
        doc = self.files.get(_id, None)
        if doc:
            self.server.sendto(addr, 'editcmd', 'openfile',
                               (_id, doc.getShortFilename(), doc.getRawText()))
            self.server.sendto(addr, 'editcmd', 'setlex',
                               (_id, doc.languagename))
        else:
            self.server.sendto(addr, 'message', '*',
                               tr("Can't find the file [%s]") % filename)

    def ChangeUserAction(self, username, action):
        for i in range(self.userlist.GetItemCount()):
            name = self.userlist.GetItem(i, 1).GetText()
            self.userlist.SetStringItem(i, 2, '')
            if name == username:
                self.userlist.SetStringItem(i, 2, 'active')
예제 #2
0
class PanelPresences(wx.Panel):
    def __init__(self, parent, ID=-1):
        wx.Panel.__init__(self, parent, ID, name="panel_presences")
        self.init = False

    def InitPage(self):
        # Création des splitter
        self.splitterV = wx.SplitterWindow(self,
                                           -1,
                                           style=wx.SP_3D | wx.SP_NO_XP_THEME
                                           | wx.SP_LIVE_UPDATE)
        self.splitterH = MultiSplitterWindow(self.splitterV,
                                             -1,
                                             style=wx.SP_NOSASH
                                             | wx.SP_LIVE_UPDATE)
        self.splitterH.SetOrientation(wx.VERTICAL)
        self.splitterH.SetBackgroundColour(couleurFondPanneau)
        # Création du panel Planning
        self.panelPlanning = CTRL_Planning.PanelPlanning(self.splitterV, -1)
        # Création du panel Calendrier
        self.panelCalendrier = PanelCalendrier(self.splitterH, -1)
        self.panelCalendrier.SetMinSize((200, 220))
        self.splitterH.AppendWindow(self.panelCalendrier, 220)
        # Création du panel Légendes
        self.panelLegendes = PanelLegendes(self.splitterH, -1)
        #self.panelLegendes.SetMinSize((300, 200))
        self.splitterH.AppendWindow(self.panelLegendes, 160)
        # Création du panel Personnes
        self.panelPersonnes = PanelPersonnes(self.splitterH, -1)
        self.panelPersonnes.SetMinSize((200, 200))
        self.splitterH.AppendWindow(self.panelPersonnes, 200)

        self.splitterH.SetMinimumPaneSize(100)

        self.__do_layout()

        # Affichage des présences d'aujourd'hui
        self.panelCalendrier.MAJselectionDates(listeDates=selectionDates)

        self.init = True

    def __do_layout(self):
        sizer_base = wx.BoxSizer(wx.VERTICAL)
        self.splitterV.SplitVertically(self.splitterH, self.panelPlanning, 240)
        sizer_base.Add(self.splitterV, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_base)
        sizer_base.Fit(self)


##    def OnSashChanging(self, evt):
##        print evt.GetSashPosition()
##        # This is one way to control the sash limits
##        if evt.GetSashPosition() <= 232 :
##            evt.Veto()

    def SetSelectionDates(self, selecDates):
        global selectionDates
        selectionDates = selecDates

    def GetSelectionDates(self):
        return selectionDates

    def SetSelectionPersonnes(self, selecPersonnes):
        global selectionPersonnes
        selectionPersonnes = selecPersonnes

    def GetSelectionPersonnes(self):
        return selectionPersonnes

    def MAJpanelPlanning(self, reinitSelectionPersonnes=False):
        """ Met à jour le DC Planning """
        global selectionPersonnes, selectionDates
        modeAffichage = CTRL_Planning.modeAffichage
        if reinitSelectionPersonnes == True:
            selectionPersonnes = self.panelPlanning.RecherchePresents(
                selectionDates)

        self.panelPlanning.ReInitPlanning(modeAffichage, selectionPersonnes,
                                          selectionDates)
        self.panelPlanning.DCplanning.MAJ_listCtrl_Categories()
        self.panelPlanning.DCplanning.MAJAffichage()

    def MAJpanel(self, listeElements=[], reinitSelectionPersonnes=False):
        """ Met à jour les éléments du panel présences """
        # Elements possibles : [] pour tout, planning, listCtrl_personnes, legendes, calendrier
        if self.init == False:
            self.InitPage()

        if "planning" in listeElements or listeElements == []:
            self.panelPlanning.DCplanning.Init_valeurs_defaut()
            self.panelPlanning.RechargeDictCategories()
            self.MAJpanelPlanning(reinitSelectionPersonnes=True)
        if "listCtrl_personnes" in listeElements or listeElements == []:
            self.panelPersonnes.MAJpanel()
        if "legendes" in listeElements or listeElements == []:
            self.panelLegendes.MAJpanel()
        if "calendrier" in listeElements or listeElements == []:
            self.panelCalendrier.MAJpanel()
예제 #3
0
class PanelMiners(wx.Panel):
    lock = threading.RLock()

    def __init__(self, parent, frame, num_miners=4):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        self.parent = parent
        self.frame = frame
        self.resize_lock = False

        self.num_miners = num_miners

        self.devicesJson = self.loadDevices()

        self.splitter = MultiSplitterWindow(self,
                                            id=wx.ID_ANY,
                                            style=wx.SP_LIVE_UPDATE)
        self.splitter.SetOrientation(wx.HORIZONTAL)

        self.splitter.SetMinimumPaneSize(1)

        self.miner0 = PMI.PanelMinerInstance(self.splitter, self, "Miner #0",
                                             self.devicesJson['miner0'],
                                             self.devicesJson['miner0num'],
                                             self.devicesJson['devices'])
        self.miner1 = PMI.PanelMinerInstance(self.splitter, self, "Miner #1",
                                             self.devicesJson['miner1'],
                                             self.devicesJson['miner1num'],
                                             self.devicesJson['devices'])
        self.miner2 = PMI.PanelMinerInstance(self.splitter, self, "Miner #2",
                                             self.devicesJson['miner2'],
                                             self.devicesJson['miner2num'],
                                             self.devicesJson['devices'])
        self.miner3 = PMI.PanelMinerInstance(self.splitter, self, "Miner #3",
                                             self.devicesJson['miner3'],
                                             self.devicesJson['miner3num'],
                                             self.devicesJson['devices'])

        self.splitter.AppendWindow(self.miner0)
        self.splitter.AppendWindow(self.miner1)
        self.splitter.AppendWindow(self.miner2)
        self.splitter.AppendWindow(self.miner3)

        self.splitter.Bind(wx.EVT_SIZE, self.resizeMinerPanels)
        #self.splitter.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.sashChanging)
        #self.splitter.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.resizeMinerPanels)

        self.collapsePanel = CollapsePanel(self, self.devicesJson['resize'],
                                           self.devicesJson['transfer'])

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizerW = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.splitter, 1, wx.EXPAND)
        sizerW.Add(self.collapsePanel, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, -1)
        sizer.Add(sizerW, 0, wx.EXPAND | wx.TOP, 1)

        self.SetSizer(sizer)

    def loadDevices(self):
        f = open(DEVICES_FILE)
        data = f.read()
        f.close()

        return json.loads(data)

    def saveDevices(self):
        sel0 = self.miner0.handler.deviceCombo.GetValue()
        sel1 = self.miner1.handler.deviceCombo.GetValue()
        sel2 = self.miner2.handler.deviceCombo.GetValue()
        sel3 = self.miner3.handler.deviceCombo.GetValue()

        num0 = self.miner0.handler.deviceNum.GetValue()
        num1 = self.miner1.handler.deviceNum.GetValue()
        num2 = self.miner2.handler.deviceNum.GetValue()
        num3 = self.miner3.handler.deviceNum.GetValue()

        self.devicesJson['miner0'] = sel0
        self.devicesJson['miner1'] = sel1
        self.devicesJson['miner2'] = sel2
        self.devicesJson['miner3'] = sel3

        self.devicesJson['miner0num'] = num0
        self.devicesJson['miner1num'] = num1
        self.devicesJson['miner2num'] = num2
        self.devicesJson['miner3num'] = num3

        self.devicesJson['resize'] = self.collapsePanel.resizeBtn.GetValue()
        self.devicesJson['transfer'] = self.collapsePanel.transferBtn.GetValue(
        )

        io.open(DEVICES_FILE, 'wt',
                encoding='utf-8').write(unicode(json.dumps(self.devicesJson)))

    def deviceChanged(self):
        if self.collapsePanel.transferBtn.GetValue():
            devices = [
                self.miner0.handler.getDevice(),
                self.miner1.handler.getDevice(),
                self.miner2.handler.getDevice(),
                self.miner3.handler.getDevice()
            ]

            self.frame.notebook.broadcastEventToAllTabs(event_id="miner",
                                                        event_value=devices)

    def executeAlgo(self, maxAlgo, switch):
        if switch:
            self.stopMiners()
        else:
            self.stopCrashedMiners()

        ret0 = self.miner0.executeAlgo(maxAlgo, switch)
        ret1 = self.miner1.executeAlgo(maxAlgo, switch)
        ret2 = self.miner2.executeAlgo(maxAlgo, switch)
        ret3 = self.miner3.executeAlgo(maxAlgo, switch)

        if (ret0 is None and ret1 is None and ret2 is None and ret3 is None):
            return None

        return ret0 or ret1 or ret2 or ret3

    def stopMiners(self, wait=False, exit=False):
        self.miner0.stopMiner(exit)
        self.miner1.stopMiner(exit)
        self.miner2.stopMiner(exit)
        self.miner3.stopMiner(exit)

        if exit:
            self.stopLoop(self.checkMinersExited)

        elif wait:
            self.stopLoop(self.checkMinersReady)

        self.frame.notebook.broadcastEventToAllTabs(event_id="stop_mining")

    def stopCrashedMiners(self):
        if self.miner0.minerStatus() == PMI.STATUS_CRASHED:
            self.miner0.stopMiner()

        if self.miner1.minerStatus() == PMI.STATUS_CRASHED:
            self.miner1.stopMiner()

        if self.miner2.minerStatus() == PMI.STATUS_CRASHED:
            self.miner2.stopMiner()

        if self.miner3.minerStatus() == PMI.STATUS_CRASHED:
            self.miner3.stopMiner()

    def stopLoop(self, endFunction):
        success = False
        i = 0
        str_ini = "Waiting for miners to die "

        from miner import PanelMinerInstance

        while i < PanelMinerInstance.MAX_ITERATIONS:
            if not endFunction():
                time.sleep(0.5)
                i += 1
                str_out = str_ini + str(i)
                print str_out

            else:
                str_out = "MINERS done, Bye!"
                print str_out
                #time.sleep(2)
                success = True
                break

        print "Miners: Exited with success = " + str(success)

        if not success:
            str_out = "MINERS Dammit"
            print str_out
            time.sleep(5)

    def checkMinerCrashed(self):
        if self.miner0.minerStatus() == PMI.STATUS_CRASHED or \
           self.miner1.minerStatus() == PMI.STATUS_CRASHED or \
           self.miner2.minerStatus() == PMI.STATUS_CRASHED or \
           self.miner3.minerStatus() == PMI.STATUS_CRASHED:

            return False

        return True

    def checkMinersReady(self):
        if ( self.miner0.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ) and \
           ( self.miner1.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ) and \
           ( self.miner2.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ) and \
           ( self.miner3.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ):

            return True

        return False

    def checkMinersExited(self):
        if ( self.miner0.minerStatus() == PMI.STATUS_EXITED ) and \
           ( self.miner1.minerStatus() == PMI.STATUS_EXITED ) and \
           ( self.miner2.minerStatus() == PMI.STATUS_EXITED ) and \
           ( self.miner3.minerStatus() == PMI.STATUS_EXITED ):

            return True

        return False

    def checkMinersSelected(self):
        if ( self.miner0.minerStatus() == PMI.STATUS_DISABLED ) and \
           ( self.miner1.minerStatus() == PMI.STATUS_DISABLED ) and \
           ( self.miner2.minerStatus() == PMI.STATUS_DISABLED ) and \
           ( self.miner3.minerStatus() == PMI.STATUS_DISABLED ):

            return False

        return True

    def resizeMinerPanels(self, event=None, slide=False, forceResize=False):
        try:
            if not self.collapsePanel.resizeBtn.GetValue() and not forceResize:
                event.Skip()
                return

            width = self.parent.GetSize()[0]
            best = width / self.num_miners

            num_ready = sum(
                1 for miner in
                [self.miner0, self.miner1, self.miner2, self.miner3]
                if miner.minerStatus() is not PMI.STATUS_DISABLED)
            #num_rinning = sum(1 for miner in [self.miner0, self.miner1, self.miner2, self.miner3] if miner.minerStatus() == PMI.STATUS_RUNNING)

            factor = 1.5
            factor = factor if num_ready == 0 else factor + (
                float(num_ready * 1.5) / 10)
            #factor = 1.5 if num_ready == 0 else 1.5 * ( 1 + ( self.num_miners - float(num_ready) - 1 ) / 10 )

            num_not_ready = self.num_miners - num_ready

            if num_ready == 0 or num_not_ready == 0 or forceResize:
                wide = narrow = best
            else:
                factored_num_ready = num_ready * factor

                factored_total = factored_num_ready + num_not_ready

                factor_ready = float(factored_num_ready) / factored_total
                factor_not_ready = float(num_not_ready) / factored_total

                wide = (factor_ready * width) / num_ready
                narrow = (factor_not_ready * width) / num_not_ready

            #no slide effect allowed for resize event triggered calls to the function for performance reasons.
            if not slide:
                self.splitter.SetSashPosition(
                    0,
                    int(wide if self.miner0.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))
                self.splitter.SetSashPosition(
                    1,
                    int(wide if self.miner1.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))
                self.splitter.SetSashPosition(
                    2,
                    int(wide if self.miner2.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))
                self.splitter.SetSashPosition(
                    3,
                    int(wide if self.miner3.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))

                if event:
                    event.Skip()

                return

            thread = threading.Thread(target=self.resizeMinerPanelsThread,
                                      args=(wide, narrow))
            thread.start()

        except (PyDeadObjectError, AttributeError):
            pass

    def resizeMinerPanelsThread(self, wide, narrow):
        try:
            #with PanelMiners.lock:
            if self.resize_lock:
                time.sleep(0.5)

            if not self.resize_lock:
                self.resize_lock = True

                target0 = int(wide if self.miner0.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)
                target1 = int(wide if self.miner1.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)
                target2 = int(wide if self.miner2.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)
                target3 = int(wide if self.miner3.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)

                steps = 15

                for w in range(1, steps):
                    #if self.resize_lock == False:
                    #    break

                    delta0 = target0 - self.splitter.GetSashPosition(0)
                    delta1 = target1 - self.splitter.GetSashPosition(1)
                    delta2 = target2 - self.splitter.GetSashPosition(2)
                    delta3 = target3 - self.splitter.GetSashPosition(3)

                    pct = float(w) / steps

                    self.splitter.SetSashPosition(
                        0,
                        self.splitter.GetSashPosition(0) + pct * delta0)
                    self.splitter.SetSashPosition(
                        1,
                        self.splitter.GetSashPosition(1) + pct * delta1)
                    self.splitter.SetSashPosition(
                        2,
                        self.splitter.GetSashPosition(2) + pct * delta2)
                    self.splitter.SetSashPosition(
                        3,
                        self.splitter.GetSashPosition(3) + pct * delta3)

                    time.sleep(0.01)

                self.resize_lock = False

        except PyDeadObjectError:
            pass

    def setButtonExpanded(self, expanded):
        self.collapsePanel.setButtonExpanded(expanded)

    def getExpansionStatus(self):
        return self.collapsePanel.collapseBtn.GetValue()
예제 #4
0
class PanelPersonnes(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, name="Personnes")
        self.parent = parent
        self.init = False

    def InitPage(self):
        self.splitter = wx.SplitterWindow(self,
                                          -1,
                                          style=wx.SP_3D | wx.SP_NO_XP_THEME
                                          | wx.SP_LIVE_UPDATE)
        self.window_D = wx.Panel(self.splitter, -1)

        # Panel Etat des dossiers
        self.window_G = MultiSplitterWindow(self.splitter,
                                            -1,
                                            style=wx.SP_NOSASH
                                            | wx.SP_LIVE_UPDATE)
        self.window_G.SetOrientation(wx.VERTICAL)
        self.window_G.SetMinimumPaneSize(100)
        self.panel_dossiers = PanelDossiers(self.window_G)
        self.window_G.AppendWindow(
            self.panel_dossiers,
            500)  # Ici c'est la hauteur du panel pb de dossiers

        # Panel vide
        self.panel_vide = wx.Panel(self.window_G, -1)
        self.panel_vide.SetBackgroundColour((122, 161, 230))
        self.window_G.AppendWindow(self.panel_vide, 200)

        self.panel_resume = PanelResume(self.window_D)
        self.label_selection = wx.StaticText(self.window_D, -1, u"")
        self.label_selection.SetForegroundColour((122, 161, 230))
        self.label_selection.Show(False)
        self.listCtrl_personnes = OL_personnes.ListView(
            self.window_D,
            id=-1,
            name="OL_personnes",
            style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_SINGLE_SEL
            | wx.LC_HRULES | wx.LC_VRULES)
        self.listCtrl_personnes.SetMinSize((20, 20))
        self.barreRecherche = BarreRecherche(self.window_D)

        self.bouton_ajouter = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Ajouter.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_modifier = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Modifier.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_supprimer = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Supprimer.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_rechercher = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(
                Chemins.GetStaticPath("Images/16x16/Calendrier3jours.png"),
                wx.BITMAP_TYPE_ANY))
        self.bouton_affichertout = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Actualiser.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_options = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Mecanisme.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_courrier = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Mail.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_imprimer = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Imprimante.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_export_texte = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Document.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_export_excel = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Excel.png"),
                      wx.BITMAP_TYPE_ANY))
        self.bouton_aide = wx.BitmapButton(
            self.window_D, -1,
            wx.Bitmap(Chemins.GetStaticPath("Images/16x16/Aide.png"),
                      wx.BITMAP_TYPE_ANY))

        self.barreTitre_liste = FonctionsPerso.BarreTitre(
            self.window_D, _(u"Liste des individus"),
            _(u"Liste des individus"))

        # Diminution de la taille de la police sous linux
        if "linux" in sys.platform:
            self.bouton_export_excel.Enable(False)

        self.__set_properties()
        self.__do_layout()

        # Binds
        self.Bind(wx.EVT_BUTTON, self.OnBoutonAjouter, self.bouton_ajouter)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonModifier, self.bouton_modifier)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonSupprimer, self.bouton_supprimer)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonRechercher,
                  self.bouton_rechercher)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonAfficherTout,
                  self.bouton_affichertout)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonOptions, self.bouton_options)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonCourrier, self.bouton_courrier)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonImprimer, self.bouton_imprimer)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonExportTexte,
                  self.bouton_export_texte)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonExportExcel,
                  self.bouton_export_excel)
        self.Bind(wx.EVT_BUTTON, self.OnBoutonAide, self.bouton_aide)

        self.bouton_modifier.Enable(False)
        self.bouton_supprimer.Enable(False)

        self.AffichePanelResume(False)

        self.init = True

##        self.splitter.SetSashPosition(250, True)

    def __set_properties(self):
        self.barreRecherche.SetToolTip(
            wx.ToolTip(
                _(u"Saisissez ici un nom, un prénom, un nom de ville, etc... pour retrouver une personne donnée."
                  )))
        self.bouton_ajouter.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour créer une nouvelle fiche individuelle")))
        self.bouton_modifier.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour modifier la fiche sélectionnée dans la liste\n(Vous pouvez également double-cliquer sur une ligne)"
                  )))
        self.bouton_supprimer.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour supprimer la fiche sélectionnée dans la liste"
                  )))
        self.bouton_rechercher.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour rechercher les personnes présentes sur une période donnée"
                  )))
        self.bouton_affichertout.SetToolTip(
            wx.ToolTip(_(u"Cliquez ici pour réafficher toute la liste")))
        self.bouton_options.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour afficher les options de la liste")))
        self.bouton_imprimer.SetToolTip(
            wx.ToolTip(_(u"Cliquez ici pour imprimer la liste")))
        self.bouton_export_texte.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour exporter la liste au format texte")))
        self.bouton_export_excel.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour exporter la liste au format Excel")))
        self.bouton_aide.SetToolTip(
            wx.ToolTip(_(u"Cliquez ici pour obtenir de l'aide")))
        self.bouton_courrier.SetToolTip(
            wx.ToolTip(
                _(u"Cliquez ici pour créer un courrier ou un Email par publipostage"
                  )))

    def __do_layout(self):
        sizer_base = wx.BoxSizer(wx.VERTICAL)
        sizer_D = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_D = wx.FlexGridSizer(rows=4, cols=1, vgap=0, hgap=0)
        grid_sizer_liste = wx.FlexGridSizer(rows=1, cols=2, vgap=5, hgap=5)
        grid_sizer_liste2 = wx.FlexGridSizer(rows=2, cols=1, vgap=0, hgap=0)
        grid_sizer_boutons = wx.FlexGridSizer(rows=16, cols=1, vgap=5, hgap=5)

        ##        # Panel Gauche
        ##        sizer_G = wx.BoxSizer(wx.VERTICAL)
        ####        sizer_G.Add(self.barreTitre_problemes, 0, wx.EXPAND, 0)
        ##        grid_sizer_G = wx.FlexGridSizer(rows=3, cols=1, vgap=10, hgap=10)
        ##        grid_sizer_G.Add(self.tree_ctrl_problemes, 1, wx.EXPAND|wx.ALL, 40)
        ##        grid_sizer_G.AddGrowableRow(0)
        ##        grid_sizer_G.AddGrowableCol(0)
        ##        sizer_G.Add(grid_sizer_G, 1, wx.ALL|wx.EXPAND, 0)
        ##        self.window_G.SetSizer(sizer_G)

        # Panel Droite
        grid_sizer_D.Add(self.barreTitre_liste, 0, wx.EXPAND, 0)

        grid_sizer_D.Add(self.label_selection, 1, wx.EXPAND | wx.ALL, 4)

        # Liste des personnes
        grid_sizer_liste2.Add(self.listCtrl_personnes, 1, wx.EXPAND, 0)
        grid_sizer_liste2.Add(self.barreRecherche, 0, wx.EXPAND, 0)
        grid_sizer_liste2.AddGrowableRow(0)
        grid_sizer_liste2.AddGrowableCol(0)
        grid_sizer_liste.Add(grid_sizer_liste2, 1, wx.EXPAND, 0)
        grid_sizer_boutons.Add(self.bouton_ajouter, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_modifier, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_supprimer, 0, 0, 0)
        grid_sizer_boutons.Add((20, 20), 0, wx.EXPAND, 0)
        grid_sizer_boutons.Add(self.bouton_rechercher, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_affichertout, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_options, 0, 0, 0)
        grid_sizer_boutons.Add((20, 20), 0, wx.EXPAND, 0)
        grid_sizer_boutons.Add(self.bouton_courrier, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_imprimer, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_export_texte, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_export_excel, 0, 0, 0)
        grid_sizer_boutons.Add((20, 20), 0, wx.EXPAND, 0)
        grid_sizer_boutons.Add(self.bouton_aide, 0, 0, 0)
        grid_sizer_boutons.AddGrowableRow(2)
        grid_sizer_liste.Add(grid_sizer_boutons, 1,
                             wx.EXPAND | wx.TOP | wx.BOTTOM | wx.RIGHT, 5)
        grid_sizer_liste.AddGrowableRow(0)
        grid_sizer_liste.AddGrowableCol(0)
        grid_sizer_D.Add(grid_sizer_liste, 1, wx.EXPAND | wx.ALL, 0)

        ##        grid_sizer_D.Add(self.barreRecherche, 1, wx.EXPAND|wx.ALL, 0)
        grid_sizer_D.Add(self.panel_resume, 1, wx.EXPAND, 0)

        grid_sizer_D.AddGrowableRow(2)
        grid_sizer_D.AddGrowableCol(0)

        sizer_D.Add(grid_sizer_D, 1, wx.EXPAND, 0)
        self.window_D.SetSizer(sizer_D)
        self.splitter.SplitVertically(self.window_G, self.window_D, 240)
        sizer_base.Add(self.splitter, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_base)
        sizer_base.Fit(self)
        self.Layout()
        self.Centre()

        self.grid_sizer_D = grid_sizer_D

    def OnBoutonAjouter(self, event):
        self.listCtrl_personnes.Ajouter()

    def OnBoutonModifier(self, event):
        self.listCtrl_personnes.Modifier()

    def OnBoutonSupprimer(self, event):
        self.listCtrl_personnes.Supprimer()

    def OnBoutonRechercher(self, event):
        resultat = self.listCtrl_personnes.Rechercher()
        if resultat != False:
            self.AfficheLabelSelection(True)
            date_debut = resultat[0].strftime("%d/%m/%Y")
            date_fin = resultat[1].strftime("%d/%m/%Y")
            texte = _(u"Sélection des personnes présentes du %s au %s :") % (
                date_debut, date_fin)
            self.label_selection.SetLabel(texte)

    def OnBoutonAfficherTout(self, event):
        self.listCtrl_personnes.AfficherTout()
        self.AfficheLabelSelection(etat=False)

    def OnBoutonOptions(self, event):
        self.listCtrl_personnes.Options()

    def OnBoutonAide(self, event):
        from Utils import UTILS_Aide
        UTILS_Aide.Aide("Personnes")

    def AffichePanelResume(self, etat=True):
        """ Affiche ou fait disparaître le panel Résumé """
        if etat == True and self.panel_resume.IsShown() == True:
            return
        self.panel_resume.Show(etat)
        self.grid_sizer_D.Layout()
        self.Refresh()

    def AfficheLabelSelection(self, etat=True):
        """ Affiche ou fait disparaître le label Sélection en cours de la liste des personnes """
        if etat == True and self.label_selection.IsShown() == True:
            return
        self.label_selection.Show(etat)
        self.grid_sizer_D.Layout()
        self.Refresh()

    def MAJpanel(self, listeElements=[]):
        """ Met à jour les éléments du panel personnes """
        # Elements possibles : [] pour tout, listCtrl_personnes
        if self.init == False:
            self.InitPage()
        #print "Je mets a jour le panel Personnes "
        if "listCtrl_personnes" in listeElements or listeElements == []:
            self.listCtrl_personnes.MAJ()
            self.panel_dossiers.tree_ctrl_problemes.MAJ_treeCtrl()
            if self.listCtrl_personnes.GetNbrePersonnes() == 0:
                self.AffichePanelResume(False)

    def OnBoutonCourrier(self, event):
        self.listCtrl_personnes.CourrierPublipostage(mode='multiple')

    def OnBoutonImprimer(self, event):
        self.listCtrl_personnes.Imprimer()

    def OnBoutonExportTexte(self, event):
        self.listCtrl_personnes.ExportTexte()

    def OnBoutonExportExcel(self, event):
        self.listCtrl_personnes.ExportExcel()