def __init__(self,parent):
     wx.Panel.__init__(self, parent, pos = (5,409),size = (1000,350),style=wx.TAB_TRAVERSAL | wx.BORDER_SIMPLE)
     mainsplitter = MultiSplitterWindow(self)
     mainsplitter.SetOrientation(wx.VERTICAL)
     self.splitterpanel_result = ResultPanel(mainsplitter)
     self.splitterpanel_log = LogPanel(mainsplitter)
     mainsplitter.AppendWindow(self.splitterpanel_result,0)
     mainsplitter.AppendWindow(self.splitterpanel_log,0)
     mainsplitter.SetSashPosition(0,200)
 def __init__(self,parent,id,title=""):
     wx.Frame.__init__(self,parent,title = title,pos = (15,15),size = (1260,800))
     mainsplitter = MultiSplitterWindow(self, style=wx.SP_3D | wx.SP_LIVE_UPDATE)
     mainsplitter.SetOrientation(wx.VERTICAL)
     self.splitterpanel1 = MainPanel(mainsplitter)
     self.splitterpanel2 = BottomPanel(mainsplitter)
     mainsplitter.AppendWindow(self.splitterpanel1, -1)
     mainsplitter.AppendWindow(self.splitterpanel2, -1)
     mainsplitter.SetSashPosition(0, 410)
Пример #3
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')
Пример #4
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()
Пример #5
0
class icMainWindow(wx.Frame):
    """
    Класс окна системы.
    """
    def __init__(self,
                 Name_,
                 WinStruct_,
                 ResFile_='',
                 Parent_=None,
                 Runner_=None):
        """
        Конструктор.
        @param Name_: Имя окна.
        @param WinStruct_: Словарь, описывающий окно.
        @param ResFile_: Имя ресурсного файла.
        @param Parent_: Родительское окно.
        @param Runner_: Родительский ДВИЖОК.
        """
        # --- Свойства класса ---
        # Иденитификатор числовой
        self._ID = 0
        # Имя
        self._Name = ''
        # Имя ресурсного файла
        self._ResFile = ''
        # Флаг разрешения/запрещения изменения заголовка окна
        self._TitleReadOnly = 1
        # Выражение для формирования заголовка окна
        self._TitleFunc = {}
        # Объект главного менеджера системных панелей
        self._MainNotebook = None
        # Функция вызываемая каждй раз при отрисовке главного окна.
        self._PaintFunc = None
        # Движок
        self._RunnerApp = Runner_
        # Открытие органайзера
        self._OnOrgOpen = None
        # Закрытие органайзера
        self._OnOrgClose = None

        # Закрытие окна
        self._OnClose = None
        # Открытие окна
        self._OnOpen = None
        # Уже открывалось окно?
        # Необходимо обработчик вызвать только один раз
        self._is_opened = False

        # --- Инициализация ---
        # Расширение структуры до спецификации
        WinStruct_ = ic.utils.ic_util.SpcDefStruct(SPC_IC_WIN, WinStruct_)

        # Содержит линейку меню? По умолчанию - да
        self.is_menubar = WinStruct_.get('is_menubar', True)

        # Содержит статусную строку? По умолчанию - да
        self.is_statusbar = WinStruct_.get('is_statusbar', True)

        self._ID = wx.NewId()
        self._Name = Name_
        if ResFile_ != '':
            self._ResFile = ResFile_

        left, top = 0, 0
        if RES_WIN_POS in WinStruct_ and WinStruct_[RES_WIN_POS] is not None:
            left = WinStruct_[RES_WIN_POS][0]
            top = WinStruct_[RES_WIN_POS][1]
        width, height = IC_WIN_WIDTH_MIN, IC_WIN_HEIGHT_MIN
        if RES_WIN_SIZE in WinStruct_ and WinStruct_[RES_WIN_SIZE] is not None:
            width = WinStruct_[RES_WIN_SIZE][0]
            height = WinStruct_[RES_WIN_SIZE][1]

        win_title = ''
        if RES_WIN_TITLEFUNC in WinStruct_ and \
           not ic.utils.ic_exec.IsEmptyMethod(WinStruct_[RES_WIN_TITLEFUNC]):
            win_title = ic.utils.ic_exec.ExecuteMethod(
                WinStruct_[RES_WIN_TITLEFUNC])
        else:
            if RES_WIN_TITLE in WinStruct_ and WinStruct_[
                    RES_WIN_TITLE] is not None:
                win_title = WinStruct_[RES_WIN_TITLE]

        # Вызов конструктора предка
        wx.Frame.__init__(self,
                          id=self._ID,
                          name=self._Name,
                          parent=Parent_,
                          pos=wx.Point(left, top),
                          size=wx.Size(width, height),
                          title=win_title,
                          style=wx.DEFAULT_FRAME_STYLE)

        # Вывести на экран окно приглашения к работе
        self._splash = None
        if RES_WIN_SPLASH in WinStruct_ and WinStruct_[RES_WIN_SPLASH]:
            self._splash = WinStruct_[RES_WIN_SPLASH]

        # --- Статусная строка ---
        if self.is_statusbar:
            self.status_bar = icStatusBar(self)
            self.SetStatusBar(self.status_bar)
            # Контекстное меню
            # Появляется только на статусной строке
            self.status_bar.Bind(wx.EVT_RIGHT_DOWN,
                                 self.onStatusBarRightMouseClick)
            self.status_bar.Bind(wx.EVT_LEFT_DCLICK,
                                 self.onStatusBarMouseDblClick)

        # Условия распахивания окна
        if width <= 0 and height <= 0:
            self.Maximize(True)  # Распахнуть окно

        # Установка дополнительных атрибутов окна
        # ...
        # Цвет фона окна
        if RES_WIN_PHONECOLOR in WinStruct_ and WinStruct_[
                RES_WIN_PHONECOLOR] is not None:
            phone_color = wx.Colour(
                WinStruct_[RES_WIN_PHONECOLOR][ic_color.I_RED],
                WinStruct_[RES_WIN_PHONECOLOR][ic_color.I_GREEN],
                WinStruct_[RES_WIN_PHONECOLOR][ic_color.I_BLUE])
        else:
            phone_color = wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW)
        # Установить цвет фона
        self.SetBackgroundColour(phone_color)

        # Установить иконку (если файл существует)
        if RES_WIN_ICON in WinStruct_ and WinStruct_[RES_WIN_ICON]:
            self.setIcon(WinStruct_[RES_WIN_ICON])

        # Установить параметры заголовка
        if RES_WIN_TITLEREADONLY in WinStruct_ and WinStruct_[
                RES_WIN_TITLEREADONLY] is not None:
            self._TitleReadOnly = WinStruct_[RES_WIN_TITLEREADONLY]
        if RES_WIN_TITLEFUNC in WinStruct_ and WinStruct_[
                RES_WIN_TITLEFUNC] is not None:
            self._TitleFunc = WinStruct_[RES_WIN_TITLEFUNC]

        # Установить параметры бордюра
        style = wx.CAPTION | wx.BORDER
        value = IC_WIN_SIMPLE_BORDER
        if RES_WIN_BORDER in WinStruct_ and WinStruct_[
                RES_WIN_BORDER] is not None:
            value = WinStruct_[RES_WIN_BORDER]
        if value == IC_WIN_NO_BORDER:
            style |= wx.NO_BORDER
        elif value == IC_WIN_SIMPLE_BORDER:
            style |= wx.SIMPLE_BORDER
        elif value == IC_WIN_DOUBLE_BORDER:
            style |= wx.DOUBLE_BORDER
        elif value == IC_WIN_SUNKEN_BORDER:
            style |= wx.SUNKEN_BORDER
        elif value == IC_WIN_RAISED_BORDER:
            style |= wx.RAISED_BORDER
        elif value == IC_WIN_RAISED_BORDER:
            style |= wx.RAISED_BORDER

        if RES_WIN_SYSMENU in WinStruct_ and WinStruct_[RES_WIN_SYSMENU]:
            style |= wx.SYSTEM_MENU
        if RES_WIN_MIN in WinStruct_ and WinStruct_[RES_WIN_MIN]:
            style |= wx.MINIMIZE_BOX
        if RES_WIN_MAX in WinStruct_ and WinStruct_[RES_WIN_MAX]:
            style |= wx.MAXIMIZE_BOX

        # Возможность изменения размеров
        style |= wx.RESIZE_BORDER

        # Установить стиль окна
        self.SetWindowStyle(style)

        # --- Области главного окна ---
        self._h_area_splitter = None
        self._v_area_splitter = None
        self.area_split = False
        if RES_WIN_AREASPLIT in WinStruct_:
            self.area_split = bool(WinStruct_[RES_WIN_AREASPLIT])

        # Панели главного окна
        self.left_panel = None
        self.right_panel = None
        self.top_panel = None
        self.bottom_panel = None
        self.central_panel = None

        # --- Объект-содержание главного окна ---
        content_psp = WinStruct_.get('content', None)
        if content_psp:
            self.content_obj = ic.getKernel().Create(content_psp, parent=self)
            io_prnt.outLog(u'Наполнение главного окна <%s>' % self.content_obj)
            self.setCentralPanel(self.content_obj)

        # Функция вызываемая каждй раз при отрисовке главного окна.
        if RES_WIN_PAINT in WinStruct_:
            self._PaintFunc = WinStruct_[RES_WIN_PAINT]
        # Обработчик отрисовки фона главного окна
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_SIZE, self.OnSize)

        # Обработчик закрытия главного окна
        if RES_WIN_CLOSE in WinStruct_:
            self._OnClose = WinStruct_[RES_WIN_CLOSE]

        self.Bind(wx.EVT_CLOSE, self.OnClose)

        # Обработчик открытия главного окна
        if RES_WIN_OPEN in WinStruct_:
            self._OnOpen = WinStruct_[RES_WIN_OPEN]

        self.Bind(wx.EVT_SHOW, self.OnOpen)
        # self.Bind(wx.EVT_LEFT_DCLICK, self.OnMouseDblClick)

        # СОбытия органайзера
        if RES_WIN_ORG_OPEN in WinStruct_:
            self._OnOrgOpen = WinStruct_[RES_WIN_ORG_OPEN]
        if RES_WIN_ORG_CLOSE in WinStruct_:
            self._OnOrgClose = WinStruct_[RES_WIN_ORG_CLOSE]

        # Запустить обработку переразмеривания всех дочерних компонентов
        # главного окна для корректного отображения
        self.SendSizeEvent()

    def showSplash(self):
        """
        Вывести на экран окно приглашения к работе.
        """
        # Вывести на экран окно приглашения к работе
        if self._splash:
            ic_splsh.ShowSplash(ic.utils.ic_file.AbsolutePath(self._splash))

    def getIconFilename(self):
        """
        Полное имя файла иконки.
        @return: Полное имя файла иконки.
            None если иконка не определена.
        """
        icon = self.resource.get(RES_WIN_ICON, None) if hasattr(
            self, 'resource') else None
        if icon and type(icon) in (str, unicode):
            return ic.utils.ic_file.AbsolutePath(icon)
        else:
            io_prnt.outWarning(u'Не определена иконка главного окна')
        return None

    def setIcon(self, Icon_):
        """
        Установить иконку.
        @param Icon_: Или имя файла *.ico или объект wx.Icon.
        """
        if type(Icon_) in (str, unicode):
            ico_file_name = ic.utils.ic_file.AbsolutePath(Icon_)
            # Установить иконку (если файл существует)
            if os.path.exists(ico_file_name):
                try:
                    icon = wx.Icon(ico_file_name, wx.BITMAP_TYPE_ICO)
                except:
                    io_prnt.outErr(
                        u'Ошибка инициализации иконки <%s> главного окна. Файл не ICO формата.'
                        % ico_file_name)
                    return None
            else:
                io_prnt.outWarning(u'Иконка главного окна <%s> не найдена' %
                                   ico_file_name)
                return None
        elif isinstance(Icon_, wx.Icon):
            icon = Icon_
        else:
            io_prnt.outWarning(u'Не обрабатываемый тип иконки <%s>' % Icon_)
            return None
        self.SetIcon(icon)
        return icon

    def OnPaint(self, event):
        """
        Обработчик отрисовки фона главного окна.
        """
        try:
            self.RefreshTitle()

            if self._PaintFunc:
                # Если главный органайзер не отображается в данный момент,
                # то выпольнить функцию отрисовки
                if (self._MainNotebook is
                        None) or not self._MainNotebook.IsShown():
                    ic.utils.ic_exec.ExecuteMethod(self._PaintFunc, self)

            # ВНИМАНИЕ!!! НЕОБХОДИМО ОБЯЗАТЕЛЬНО СТАВИТЬ event.Skip()
            #   ИНАЧЕ УЖАСНО ГЛЮЧИТ!!!!

            bmp = None
            if bmp:
                dc = wx.PaintDC(self)
                dc.BeginDrawing()
                fx, fy = (2, 1)
                sx, sy = bmp.GetWidth(), bmp.GetHeight()
                cx, cy = self.GetClientSize()

                nx = cx / (sx * fx) + 1
                ny = cy / (sy * fy) + 1

                x0 = 10
                y0 = (cy - ny * sy * fy) / 2

                for i in xrange(ny):
                    if i % 2:
                        d0 = (sx * fx) / 2
                        nn = nx - 1
                    else:
                        d0 = 0
                        nn = nx

                    for n in xrange(nn):
                        dc.DrawBitmap(common.imgDefis, x0 + d0 + n * sx * fx,
                                      y0 + i * sy * fy, True)

                dc.EndDrawing()
        except:
            io_prnt.outErr(u'Ошибка отрисовки главного окна')

        if event:
            event.Skip()

    def OnSize(self, event):
        """
        Изменение размеров.
        """
        self.Refresh()
        event.Skip()

    def OnOpen(self, event):
        """
        Обработчик открытия главного окна.
        """
        # Если в режиме редактирования...
        if not ic_mode.isRuntimeMode():
            event.Skip()
            return

        try:
            ok = True
            if not ic.utils.ic_exec.IsEmptyMethod(self._OnOpen) and \
                not self._is_opened:
                ok = ic.utils.ic_exec.ExecuteMethod(self._OnOpen, self)
                self._is_opened = True
            if ok:  # Обычное открытие окна
                event.Skip()
            else:
                event.Continue = False
        except:
            io_prnt.outErr(u'Ошибка открытия главного окна')
            event.Skip()

    def OnClose(self, event):
        """
        Обработчик закрытия главного окна.
        """
        # Если в режиме редактирования,
        # то при закрытии окно не закрывать приложение
        if not ic_mode.isRuntimeMode():
            event.Skip()
            return

        try:
            ok = True
            if not ic.utils.ic_exec.IsEmptyMethod(self._OnClose):
                ok = ic.utils.ic_exec.ExecuteMethod(self._OnClose, self)
            if ok:  # Обычное закрытие окна
                if self._MainNotebook:
                    self.DelOrg()
                self._destroyAreaSplitter()

                # Остановить основной цикл выполнения приложения
                if self._RunnerApp:
                    if issubclass(self._RunnerApp.__class__, wx.App):
                        self._RunnerApp.ExitMainLoop()
                event.Skip()
            else:
                event.Continue = False
        except:
            io_prnt.outErr(u'Ошибка закрытия главного окна')
            event.Skip()

    def onStatusBarMouseDblClick(self, event):
        """
        Обработчик двойного щелчка на статусной строке.
        По умолчанию открываем окно <О программе...>
        """
        from ic.dlg import about_box
        about_box.showAbout(parent=self)
        event.Skip()

    def onStatusBarRightMouseClick(self, event):
        """
        Обработчик вызова контекстного меню кликом
            правой мышки на главном окне.
        """
        popup_menu = wx.Menu()
        menuitem_id = wx.NewId()
        popup_menu.Append(menuitem_id, u'Запуск внешней программы')
        popup_menu.Bind(wx.EVT_MENU, self.onRunExternalProg, id=menuitem_id)
        mouse_pos = wx.GetMousePosition()
        self.PopupMenu(popup_menu, mouse_pos)
        event.Skip()

    def onRunExternalProg(self, event):
        """
        Запуск внешней программы из контекстного меню.
        """
        from . import ext_prg
        ext_prg.run_external_programm()
        event.Skip()

    def SetICTitle(self, Title_=''):
        """
        Установить заголовок.
        """
        if Title_ != '':
            if self._TitleReadOnly == 0:
                self.SetTitle(Title_)
        else:
            if self._TitleReadOnly == 0 and self._TitleFunc != {}:
                new_title = ic.utils.ic_exec.ExecuteMethod(
                    self._TitleFunc, self)
                if new_title != '' and new_title is not None:
                    self.SetTitle(new_title)

    def SetTitleFunc(self, TitleFunc_):
        """
        Установить метод заполнения заголовка.
        @param TitleFunc_: Словарь функции метода заполнения заголовка.
        """
        self._TitleFunc = TitleFunc_

    def RefreshTitle(self):
        """
        Обновить заголовок.
        """
        try:
            if not ic.utils.ic_exec.IsEmptyMethod(self._TitleFunc):
                win_title = ic.utils.ic_exec.ExecuteMethod(self._TitleFunc)
                self.SetTitle(win_title)
                self.Refresh()
        except:
            io_prnt.outErr(
                u'Ошибка выполнения функции обновления заголовка главного окна.'
            )

    def SetTitleReadOnly(self, TitleReadOnly_):
        """
        Установить Флаг разрешения/запрещения изменения заголовка окна.
        """
        self._TitleReadOnly = TitleReadOnly_

    def GetMainNotebook(self):
        """
        Определить главный органайзер.
        """
        return self._MainNotebook

    def OpenWin(self):
        """
        Открыть окно.
        """
        self.SetICTitle()
        self.Show(True)

    def CloseWin(self):
        """
        Закрыть окно.
        """
        self.Show(False)

    # --- Методы управления панелями главного окна ---
    def AddOrgPage(self,
                   Page_,
                   Title_,
                   OpenExists_=False,
                   Image_=None,
                   CanClose_=True,
                   OpenScript_=None,
                   CloseScript_=None,
                   DefaultPage_=-1):
        """
        Добавить страницу.
        @param Page_: Страница-объект наследник wx.Window.
        @param Title_: Заголовок страницы.
        @param OpenExists_: Если страница уже создана-открыть ее.
        @param Image_: Файл образа или сам образ в заголовке страницы.
        @param CanClose_: Признак разрешения закрытия страницы при помощи
            стандартного всплывающего меню.
        @param OpenScript_: Блок кода открытия страницы при переключенни
            м/у страницами.
        @param CloseScript_: Блок кода закрытия страницы при переключенни
            м/у страницами.
        @param DefaultPage_: Индекс страницы,  открываемой по умолчанию.
            Если -1, то открывается текущая добавляемая страница.
        """
        if self.content_obj is not None:
            io_prnt.outWarning(
                u'Notebook главного окна заменен объектом-содержанием <%s>' %
                self.content_obj)
            return None
        try:
            # --- Объект главного менеджера системных панелей ---
            if self._MainNotebook is None:
                if self.area_split:
                    if self._h_area_splitter is None:
                        self._createAreaSplitter()
                    self._MainNotebook = ic_note.icMainNotebook(
                        self._h_area_splitter)
                    self.setCentralPanel(self._MainNotebook)
                else:
                    self._MainNotebook = ic_note.icMainNotebook(self)
            # Добавить страницу
            return self._MainNotebook.addPage(Page_, Title_, OpenExists_,
                                              Image_, CanClose_, OpenScript_,
                                              CloseScript_, DefaultPage_)
        except:
            io_prnt.outErr(u'Ошибка добавления страницы в главное окно.')
            return None

    # Можно использовать и другое наименование метода
    AddPage = AddOrgPage

    def DelOrgPage(self, Index_):
        """
        Удалить страницу.
        @param Index_: Индекс страницы.
        """
        if self.content_obj is not None:
            io_prnt.outWarning(
                u'Notebook главного окна заменен объектом-содержанием <%s>' %
                self.content_obj)
            return None
        try:
            # --- Объект главного менеджера системных панелей ---
            if self._MainNotebook is None:
                return
            self._MainNotebook.deletePage(Index_)
            # Если страниц в органайзере больше нет, тогда удалить его из окна
            if self._MainNotebook.GetPageCount() == 0:
                self.DelOrg()
            return self._MainNotebook
        except:
            io_prnt.outErr(u'Ошибка удаления страницы из органайзера.')
            return None

    def DelOrg(self):
        """
        Удалить органайзер(Объект главного менеджера системных панелей).
        @return: Возвращает результат выполнения операции True/False.
        """
        if self.content_obj is not None:
            io_prnt.outWarning(
                u'Notebook главного окна заменен объектом-содержанием <%s>' %
                self.content_obj)
            return None
        try:
            if self.area_split:
                self.delCentralPanel()
            self._MainNotebook.deleteAllPages()
            self._MainNotebook.Close()
            self.RemoveChild(self._MainNotebook)
            self._MainNotebook.Destroy()
            self._MainNotebook = None
            self.Refresh()
            return True
        except:
            io_prnt.outErr(u'Ошибка удаления главного органайзера')
            return False

    def CloseOrgPages(self):
        """
        Закрыть все страницы органайзера(Объект главного менеджера системных панелей).
        @return: Возвращает результат выполнения операции True/False.
        """
        if self.content_obj is not None:
            io_prnt.outWarning(
                u'Notebook главного окна заменен объектом-содержанием <%s>' %
                self.content_obj)
            return None
        try:
            if self.area_split:
                self.delCentralPanel()
            self._MainNotebook.deleteAllPages()
            self.Refresh()
            return True
        except:
            io_prnt.outErr(u'Ошибка закрытия окон главного органайзера')
            return False

    def _createAreaSplitter(self):
        """
        Создать разделитель областей.
        @return: Объект главного вертикального разделителя или 
            None в случае ошибки.
        """
        try:
            if self.area_split:
                # Вертикальный сплиттер
                self._v_area_splitter = MultiSplitterWindow(
                    self, style=wx.SP_LIVE_UPDATE)
                self._v_area_splitter.SetOrientation(wx.VERTICAL)
                # Горизонтальный сплиттер
                self._h_area_splitter = MultiSplitterWindow(
                    self._v_area_splitter, style=wx.SP_LIVE_UPDATE)
                self._h_area_splitter.SetOrientation(wx.HORIZONTAL)
                self._insPanel(self._v_area_splitter, 1, self._h_area_splitter)

                # ВНИМАНИЕ!!!
                # Установить принудительно размер главного сплиттера,
                # а то объект не перерисовывается!!!
                self._v_area_splitter.SetSize(self.GetClientSize())

            return self._v_area_splitter
        except:
            io_prnt.outErr(u'Ошибка создания разделителя областей.')
            return None

    def _destroyAreaSplitter(self):
        """
        Удаление разделителя областей.
        """
        try:
            if self.area_split:
                if self._h_area_splitter:
                    h_win_count = len(self._h_area_splitter._windows)
                    for i in range(h_win_count):
                        self._delPanel(self._h_area_splitter, i)
                if self._v_area_splitter:
                    v_win_count = len(self._v_area_splitter._windows)
                    for i in range(v_win_count):
                        self._delPanel(self._v_area_splitter, i)
                    self._v_area_splitter.Destroy()
                    self.left_panel = None
                    self.right_panel = None
                    self.top_panel = None
                    self.bottom_panel = None
                    self.central_panel = None
            return True
        except:
            io_prnt.outErr(u'Ошибка удаления разделителя областей.')
            return False

    def _insPanel(self, Splitter_, Index_, Panel_):
        """
        Установить панель.
        @param Splitter_: Сплиттер, в который будет устанавливаться панель.
        @param Index_: Индекс в сплиттере.
        @param Panel_: Объект панели. Наследник от wx.Window.
        @return: Возвращает True/False.
        """
        try:
            if Splitter_ is None:
                return False

            win_count = len(Splitter_._windows)
            win = None
            if Index_ < win_count:
                win = Splitter_.GetWindow(Index_)

            if win:
                Splitter_.ReplaceWindow(win, Panel_)
            else:
                if Index_ >= win_count:
                    for i in range(win_count, Index_):
                        Splitter_.AppendWindow(wx.Panel(Splitter_, -1), 0)
                    Splitter_.AppendWindow(Panel_)
                else:
                    Splitter_.InsertWindow(Index_, Panel_, sashPos=-1)

            return True
        except:
            io_prnt.outErr(u'Ошибка установки панели в разделитель областей.')
            return False

    def _delPanel(self, Splitter_, Index_):
        """
        Удалить из области панель с указанным индексом.
        @param Splitter_: Сплиттер, в который устанавленна панель.
        @param Index_: Индекс в сплиттере.
        @return: Возвращает True/False.
        """
        try:
            if Splitter_ is None:
                return False

            win_count = len(Splitter_._windows)
            win = None
            if Index_ < win_count:
                win = Splitter_.GetWindow(Index_)

            if win:
                Splitter_.DetachWindow(win)
                win.Destroy()
            return True
        except:
            io_prnt.outErr(u'Ошибка удаления панели из разделителя областей.')
            return False

    def getLeftPanel(self):
        """
        Левая панель.
        """
        if self.area_split:
            return self.left_panel
        return None

    def setLeftPanel(self, Panel_):
        """
        Установить левую панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.left_panel = Panel_
        return self._insPanel(self._h_area_splitter, 0, self.left_panel)

    def delLeftPanel(self):
        """
        Удалить левую панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.left_panel = None
        return self._delPanel(self._h_area_splitter, 0)

    def getRightPanel(self):
        """
        Правая панель.
        """
        if self.area_split:
            return self.right_panel
        return None

    def setRightPanel(self, Panel_):
        """
        Установить правую панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.right_panel = Panel_
        return self._insPanel(self._h_area_splitter, 2, self.right_panel)

    def delRightPanel(self):
        """
        Удалить правую панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.right_panel = None
        return self._delPanel(self._h_area_splitter, 2)

    def getTopPanel(self):
        """
        Верхняя панель.
        """
        if self.area_split:
            return self.top_panel
        return None

    def setTopPanel(self, Panel_):
        """
        Установить верхнюю панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.top_panel = Panel_
        return self._insPanel(self._v_area_splitter, 0, self.top_panel)

    def delTopPanel(self):
        """
        Удалить верхнюю панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.top_panel = None
        return self._delPanel(self._v_area_splitter, 0)

    def getBottomPanel(self):
        """
        Нижняя панель.
        """
        if self.area_split:
            return self.bottom_panel
        return None

    def setBottomPanel(self, Panel_):
        """
        Установить нижнюю панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.bottom_panel = Panel_
        return self._insPanel(self._v_area_splitter, 2, self.bottom_panel)

    def delBottomPanel(self):
        """
        Удалить нижнюю панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.bottom_panel = None
        return self._delPanel(self._v_area_splitter, 2)

    def getCentralPanel(self):
        """
        Центральная панель.
        """
        if self.area_split:
            return self.central_panel
        return None

    def setCentralPanel(self, Panel_):
        """
        Установить центральную панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.central_panel = Panel_
        return self._insPanel(self._h_area_splitter, 1, self.central_panel)

    def delCentralPanel(self):
        """
        Удалить центральную панель.
        """
        if self._v_area_splitter is None or self._h_area_splitter is None:
            self._createAreaSplitter()

        self.central_panel = None
        return self._delPanel(self._h_area_splitter, 1)

    def setMenuBar(self, MenuBar_):
        """
        Установить горизонтальное меню.
        """
        try:
            self.SetMenuBar(MenuBar_)
            MenuBar_.Refresh()
        except:
            io_prnt.outErr(
                u'Ошибка установки горизонтального меню <%s> в главное окно.' %
                MenuBar_)
Пример #6
0
class MainScreen(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=wx.Size(1280, 800),style=wx.DEFAULT_FRAME_STYLE)
        # 窗口居中
        self.CenterOnScreen()
        # 分割窗口
        self.sp = MultiSplitterWindow(self)
        self.sp.SetOrientation(wx.VERTICAL)
        self.Bind(wx.PyEventBinder(wx.wxEVT_SPLITTER_SASH_POS_CHANGING),self.sashchange)
        # Top窗口:panel
        self.p_top = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
        self.p_top.Hide()
        # 下部分窗口:左右分割的splitter
        self.sp_main = MultiSplitterWindow(self.sp)
        # 上下两部分窗口填充
        self.sp.AppendWindow(self.p_top, sashPos=self.GetSize()[1] / 6)
        self.sp.AppendWindow(self.sp_main)

        # 下部分窗口的left:panel
        self.p_left = LeftPanel(self.sp_main, style=wx.SUNKEN_BORDER)
        self.p_left.Hide()
        # 下部分窗口的right:panel
        self.p_mains = [SearchPanel(self.sp_main, style=wx.SUNKEN_BORDER),
                        CheckPanel(self.sp_main, style=wx.SUNKEN_BORDER),
                        UpdataPanel(self.sp_main, style=wx.SUNKEN_BORDER),
                        SearchPanelByOffline(self.sp_main, style=wx.SUNKEN_BORDER)
                        ]
        for p in self.p_mains:
            p.Hide()

        # 下部分窗口默认填充查询页面
        self.sp_main.SetOrientation(wx.HORIZONTAL)
        self.sp_main.AppendWindow(self.p_left, sashPos=self.GetSize()[0] / 6)
        self.sp_main.AppendWindow(self.p_mains[0])
        self.main_index = 0

        self.Bind(wx.EVT_BUTTON, self.OnClick)

    def OnClick(self, event):
        obj = event.GetEventObject().GetName()
        # print(obj, self.main_index)
        if obj == 'btn_search' and self.main_index != 0:
            self.changePanel(0)
        if obj == 'btn_check' and self.main_index != 1:
            self.changePanel(1)
        if obj == 'btn_updata' and self.main_index != 2:
            self.changePanel(2)
        if obj == 'btn_search_offline' and self.main_index != 3:
            self.changePanel(3)

    def changePanel(self, index):
        # print(index)
        # self.sp_main[self.main_index].Hide()
        # self.sp_main.Unsplit(toRemove=None)
        # self.sp_main.SplitVertically(self.p_left, self.p_mains[index], sashPosition=self.GetSize()[0] / 6)
        self.sp_main.ReplaceWindow(self.p_mains[self.main_index], self.p_mains[index])
        self.p_mains[self.main_index].Hide()
        self.main_index = index

    def sashchange(self,e):
        e.Veto()
Пример #7
0
class TodoFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent=parent, title=title, size=(400, 400))

        self.model = None
        self.parent = parent

        self.edit_window_visible = False

        self.k1 = ''
        self.k2 = ''
        self.k3 = ''
        self.listen()

        self.status_bar = TodoStatusBar(self)
        self.SetStatusBar(self.status_bar)

        self.switch = False

        # Menu entries
        self.button_menu_ID1 = wx.NewId()
        self.button_menu_ID2 = wx.NewId()
        self.button_menu_ID3 = wx.NewId()
        self.button_menu_ID4 = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnMenuEntrySort, id=self.button_menu_ID1)
        self.Bind(wx.EVT_MENU, self.OnMenuEntryInfo, id=self.button_menu_ID2)
        self.Bind(wx.EVT_MENU,
                  self.OnMenuEntryVisualReport,
                  id=self.button_menu_ID3)
        self.Bind(wx.EVT_MENU,
                  self.OnMenuEntryToggleEditWindow,
                  id=self.button_menu_ID4)

        # Multiple keybindings states
        self.state_C_x_ID = wx.NewId()
        self.state_ID2 = wx.NewId()
        self.state_undo_ID = wx.NewId()
        self.Bind(wx.EVT_MENU, self.OnState_C_x, id=self.state_C_x_ID)
        self.Bind(wx.EVT_MENU, self.OnState2, id=self.state_ID2)
        self.Bind(wx.EVT_MENU, self.OnStateUndo, id=self.state_undo_ID)

        self.accelerator_entries = [
            # Single keybindings
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('S'), self.button_menu_ID1),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('I'), self.button_menu_ID2),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('R'), self.button_menu_ID3),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('E'), self.button_menu_ID4),
            # Multiple keybindings
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('x'), self.state_C_x_ID),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('f'), self.state_ID2),
            wx.AcceleratorEntry(wx.ACCEL_CTRL, ord('g'), self.state_undo_ID)
        ]
        self.accelerator_table = wx.AcceleratorTable(self.accelerator_entries)
        self.SetAcceleratorTable(self.accelerator_table)

        # temp_data must not be empty for selection to work correctly
        self.update_temp_data()

        self.main_panel = wx.Panel(self)
        self.main_panel_sizer = wx.BoxSizer(wx.VERTICAL)

        self.main_splitter = MultiSplitterWindow(self.main_panel,
                                                 style=wx.SP_LIVE_UPDATE
                                                 | wx.SP_BORDER)
        self.main_splitter.SetOrientation(wx.HORIZONTAL)

        # self.main_splitter.SetMinimumPaneSize(0)

        self.panel = TodoListCtrlPanel(self.main_splitter)
        self.panel.get_listctr().colorize()
        self.SetBackgroundColour(wx.Colour(255, 119, 0))

        self.edit_window = TodoEditWindow(self.main_splitter)
        self.edit_window.Hide()

        self.main_splitter.AppendWindow(self.panel, self.GetSize()[1] / 3 * 2)

        self.search_box = SearchBox(self)

        self.panel.get_listctr().brother_widget = self.search_box
        # self.Bind(wx.EVT_CHAR_HOOK, self.OnSearch, self.search_box)
        self.search_box.Bind(wx.EVT_TEXT, self.OnSearch, self.search_box)
        # self.Bind(wx.EVT_TEXT_ENTER, self.OnEnter)  #, self.search_box)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnSearch)  #, self.search_box)
        # self.Bind(wx.EVT_CHAR, self.OnBackspace, self.search_box)
        # self.Bind(wx.EVT_CHAR_HOOK, self.OnEnter)  # , self.search_box)
        self.Bind(wx.EVT_SET_FOCUS, self.OnBackspace, self.search_box)
        self.Bind(wx.EVT_KILL_FOCUS, self.OnBackspace, self.search_box)
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnBackspace, self.search_box)
        self.Bind(wx.EVT_SIZE, self.OnSize, self)
        self.search_box.Bind(wx.EVT_CHAR, self.OnChar, self.search_box)

        self.search_box.SetFocus()

        self.main_slider = wx.Slider(
            # self, 100, 25, 1, 100, (30, 60), (250, -1),
            self.status_bar,
            100,
            25,
            1,
            len(temp_data),
            (30, 60),
            (250, -1),
            wx.SL_HORIZONTAL | wx.SL_AUTOTICKS)  # |wx.SL_LABELS)
        self.main_slider.SetTickFreq(5, 1)
        self.main_slider.SetLineSize(5)
        self.main_slider.SetPageSize(5)
        self.main_slider.SetBackgroundColour(wx.Colour(80, 80, 80))
        self.main_slider.Bind(wx.EVT_SLIDER, self.OnSlider, self.main_slider)
        # TODO: Add text for current value or move it somewhere else
        # self.main_slider.SetPosition((self.status_bar.GetFieldRect(1).x+200, 0))

        self.addTaskButton = wx.Button(self, 0,
                                       'Add &task')  # , size=(125, -1))
        self.addTaskButton.SetBackgroundColour(wx.Colour(255, 77, 0))
        self.addTaskButton.Bind(wx.EVT_BUTTON, self.OnClickAddTaskButton,
                                self.addTaskButton)

        self.setPriorityButton = wx.Button(self, 0, 'Set &priority')
        self.setPriorityButton.SetBackgroundColour(wx.Colour(255, 77, 0))
        self.setPriorityButton.Bind(wx.EVT_BUTTON,
                                    self.OnClickSetPriorityButton,
                                    self.setPriorityButton)

        self.deleteTaskButton = wx.Button(self, 0, '&Delete task')
        self.deleteTaskButton.SetBackgroundColour(wx.Colour(255, 77, 0))
        self.deleteTaskButton.Bind(wx.EVT_BUTTON, self.OnClickDeleteTaskButton,
                                   self.deleteTaskButton)

        self.moreButton = wx.Button(self, 0, '&More')
        self.moreButton.SetBackgroundColour(wx.Colour(255, 77, 0))
        self.moreButton.Bind(wx.EVT_BUTTON, self.OnClickMoreButton,
                             self.moreButton)

        self.main_panel_sizer.Add(self.main_splitter, 1, wx.EXPAND | wx.ALL)
        self.main_panel.SetSizer(self.main_panel_sizer)
        self.main_splitter.Layout()
        self.main_panel.Layout()

        self.buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.panel.sizer.Layout()
        # self.buttonSizer.Add(self.main_slider, 0, wx.ALIGN_LEFT|wx.ALL)
        self.buttonSizer.Add(self.addTaskButton, 0, wx.ALIGN_LEFT | wx.ALL)
        self.buttonSizer.Add(self.setPriorityButton, 0,
                             wx.ALIGN_RIGHT | wx.ALL)
        self.buttonSizer.Add(self.deleteTaskButton, 0, wx.ALIGN_RIGHT | wx.ALL)
        self.buttonSizer.Add(self.moreButton, 0, wx.ALIGN_RIGHT | wx.ALL)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.search_box, 0, wx.GROW | wx.ALL, 6)
        # self.sizer.Add(self.addTaskButton, 0, wx.ALIGN_RIGHT|wx.ALL)
        # self.sizer.Add(self.setPriorityButton, 0, wx.ALIGN_RIGHT|wx.ALL)
        self.sizer.Add(self.buttonSizer, 0, wx.ALIGN_RIGHT | wx.ALL)
        self.sizer.Add(self.main_panel, 1, wx.EXPAND | wx.ALL)
        # self.sizer.Add(self.panel, 1, wx.EXPAND|wx.ALL)
        # self.sizer.Add(self.edit_window, 1, wx.EXPAND|wx.ALL)
        # self.sizer.Add(self.main_splitter, 1, wx.EXPAND|wx.ALL)
        self.SetSizer(self.sizer)
        self.SetAutoLayout(True)
        self.Show(True)

    def register(self, model):
        self.model = model

    def OnSlider(self, event):
        print self.main_slider.GetValue()
        self.main_slider.SetRange(1, len(temp_data))

        # previous = 0
        # next = 0
        current = self.main_slider.GetValue()

        # # XXX
        # # This would be more efficient, but it does not check
        # # milliseconds/nanoseconds yet.
        # if current > 0:
        #     previous = self.main_slider.GetValue() - 1
        # else:
        #     previous = self.main_slider.GetMax() - 1
        # if current < self.main_slider.GetMax():
        #     next = self.main_slider.GetValue() + 1
        # else:
        #     next = 0

        # self.panel.get_listctr().SetItemState(previous, 0, -1)
        # self.panel.get_listctr().SetItemState(next, 0, -1)

        # This can become inefficient for large lists.
        item = 0
        while True:
            item = self.panel.get_listctr().GetNextItem(
                item, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
            if item == -1:
                break

            self.panel.get_listctr().SetItemState(
                item, 0, wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED)

        self.panel.get_listctr().SetItemState(
            current - 1, wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED,
            wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED)

        self.panel.get_listctr().EnsureVisible(current)
        self.panel.get_listctr().SetFocus()

        event.Skip()

    def OnSize(self, event):
        # TODO: Make param of SetSashPosition dynamic
        self.main_splitter.SetSashPosition(0, self.GetSize()[0] / 3 * 2)
        event.Skip()

    def OnState_C_x(self, event):
        print 'C-x  -  SWITCH: ', self.switch
        self.switch = True
        event.Skip()

    def OnState2(self, event):
        print 'C-x  -  SWITCH: ', self.switch
        if self.switch:
            self.OnMenuEntrySort(event)
        event.Skip()

    def OnStateUndo(self, event):
        print 'C-x  -  SWITCH: ', self.switch
        self.switch = False
        event.Skip()

    def listen(self):
        # keycode =  event.GetKeyCode()
        self.Bind(wx.EVT_KEY_DOWN, self._OnFirstChar)
        self.Bind(wx.EVT_KEY_DOWN, self._OnSecondChar)
        self.Bind(wx.EVT_KEY_DOWN, self._OnThirdChar)

        # if keycode == wx.WXK_TAB:
        if self.k1 == wx.WXK_TAB:
            if self.k2 == 'x':
                if self.k3 == 'j':
                    self.OnMenuEntrySort()

    def _OnFirstChar(self, event):
        print "foo" * 80
        self.k1 = event.GetKeyCode()

    def _OnSecondChar(self, event):
        self.k2 = chr(event.GetKeyCode())

    def _OnThirdChar(self, event):
        self.k3 = chr(event.GetKeyCode())

    def OnMenuEntrySort(self, event):
        self._sort_temp_data()
        self._reload_view(do_reload_temp_data=False)

    def OnMenuEntryInfo(self, event):
        dialog = wx.MessageDialog(self, 'This is some information. ', 'Info',
                                  wx.OK | wx.ICON_INFORMATION)
        dialog.ShowModal()
        dialog.Destroy()

    def OnMenuEntryVisualReport(self, event):
        VisualReport(title='Report', data=data)
        event.Skip()

    def OnMenuEntryToggleEditWindow(self, event):
        if not self.edit_window_visible:
            self.main_splitter.AppendWindow(self.edit_window)
            self.edit_window.Show()
            self.edit_window_visible = True
        else:
            self.main_splitter.DetachWindow(self.edit_window)
            self.edit_window.Hide()
            self.edit_window_visible = False

    def OnChar(self, event):
        if event.GetKeyCode() == 9:  # TAB
            self.panel.get_listctr().SetFocus()
        elif event.GetKeyCode() == 13:  # ENTER
            print 'ENTER'
        else:
            event.Skip()

    def OnClickAddTaskButton(self, event):
        dialog = wx.TextEntryDialog(self, 'New task:', 'TASK', 'TODO')
        dialog.SetValue('TASK')
        new_task = ''
        if dialog.ShowModal() == wx.ID_OK:
            new_task = dialog.GetValue()

            choice_dialog = wx.SingleChoiceDialog(
                self,
                'Select priority',
                'Priority',
                [str(i) for i in xrange(1, 8)],  # TODO: Make dynamic
                wx.CHOICEDLG_STYLE)
            if choice_dialog.ShowModal() == wx.ID_OK:
                new_priority = int(choice_dialog.GetStringSelection())

                self.model.add_task(new_task,
                                    new_priority)  # Append to the model
                # data.append([new_task, new_priority])  # Append to the views data list

                # Redisplay the list
                self._reload_view()
            choice_dialog.Destroy()

        dialog.Destroy()

    def OnClickSetPriorityButton(self, event):
        # FIXME: Does not set the priority for the right items yet
        # for idx in self.panel.get_listctr().GetSelectedItems():
        # while self.panel.get_listctr().GetNextSelected(0):
        # print "%10s %s" % (idx, self.temp[idx])

        # for idx, item in enumerate(self.panel.get_listctr().temp):
        #     if item.IsSelected:
        #         print item

        print "``````````", self.panel.get_listctr().selected_items

        for sel_item in self.panel.get_listctr().selected_items:
            dialog = wx.SingleChoiceDialog(self, 'Select priority', 'Priority',
                                           [str(i) for i in xrange(1, 8)],
                                           wx.CHOICEDLG_STYLE)
            if dialog.ShowModal() == wx.ID_OK:
                print 'Item: %s; Selection %s' % (sel_item,
                                                  dialog.GetStringSelection())
                for idx, item in enumerate(data.get_as_list()):
                    if sel_item.label == item.label:
                        new_priority = int(dialog.GetStringSelection())
                        print 'INDEX: ', self.model.task_list.get_task_at(idx)
                        self.model.set_priority(
                            idx, new_priority)  # Set for the model
                        data.get_task_at(
                            idx
                        ).priority = new_priority  # Set for the views data list
                        print "NEW: ", item.label, ' - ', new_priority

                        # Redisplay the list
                        self._reload_view()

            dialog.Destroy()

    def OnClickDeleteTaskButton(self, event):
        choice_dlg = wx.SingleChoiceDialog(
            self, 'Really delte the following task(s)?', 'Delete', [
                i[0] + ' (priority: ' + str(i[1]) + ')'
                for i in self.panel.get_listctr().selected_items
            ], wx.CHOICEDLG_STYLE)
        if choice_dlg.ShowModal() == wx.ID_OK:
            # new_priority = int(choice_dlg.GetStringSelection())

            for item in self.panel.get_listctr().selected_items:
                for idx, task in enumerate(data):
                    if item == task:
                        self.model.remove_task(
                            (idx + 1))  # Remove from the model
                        data.pop(idx - 1)  # Remove from the views data list

                        # Redisplay the list
                        self._reload_view()
                        break
        choice_dlg.Destroy()

    def OnClickMoreButton(self, event):
        # self._sort_temp_data()
        # self._reload_view(do_reload_temp_data=False)

        button_menu = wx.Menu()
        button_menu.Append(self.button_menu_ID1, '&Sort\tCtrl+S/C-x C-f')
        button_menu.Append(self.button_menu_ID2, '&Info\tCtrl+I')
        button_menu.Append(self.button_menu_ID3, 'Visual &Report\tCtrl+R')
        button_menu.Append(self.button_menu_ID4, 'Toggle &Edit window\tCtrl+E')
        self.PopupMenu(button_menu, self.moreButton.GetPosition())
        button_menu.Destroy()

    def OnSearch(self, event):
        # value = self.search_box.GetValue()
        # if not value:
        #     print 'Nothing entered'
        #     return
        # keycode = event.GetKeyCode()

        current = str(self.search_box.GetValue())
        # current = str(self.search_box.GetLineText(0))

        # wx.KeyEvent(wx.WXK_RETURN)

        # current = str(self.search_box.GetRange(0, self.search_box.GetInsertionPoint()))
        # current = str(self.search_box.GetValue())

        # self.update_temp_data(current)

        # print 'KEYCODE: ', keycode
        # if keycode == 8:  # Backspace key
        if False:  # TODO: Improve or remove
            self.panel.get_listctr().ClearAll()
            self._clear_temp_data()
        else:
            print 'CURRENT: ', current
            # self.panel.get_listctr().update(current)
            self.panel.get_listctr().ClearAll()
            # self._clear_temp_data()
            self.update_temp_data(current)
            self.panel.get_listctr().Populate(temp_data)
            self.Layout()
        event.Skip()

    def _reload_view(self, do_reload_temp_data=True):
        self.panel.get_listctr().ClearAll()
        if do_reload_temp_data:
            self.update_temp_data()
        self.panel.get_listctr().Populate(temp_data)
        self.Layout()

    def _clear_temp_data(self):
        temp_data.clear()

    def OnBackspace(self, event):
        keycode = event.GetKeyCode()
        print 'KEYCODE: ', keycode
        if keycode == 8:  # Backspace key
            self.panel.get_listctr().ClearAll()
        else:
            self.OnSearch(event)

    def OnEnter(self, event):
        keycode = event.GetKeyCode()
        print 'KEYCODE: ', keycode

    def update_temp_data(self, string=''):
        self._clear_temp_data()
        for item in data.get_as_list():
            if string in item.label or string in str(item.priority):
                # print 'MATCH: ', item
                temp_data.add(item)
        self.status_bar.set_tasks(len(temp_data))

    def _sort_temp_data(self):
        temp_data.sort_alphabetically()
        temp_data.sort_numerically()
Пример #8
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()
Пример #9
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()