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)
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')
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()
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_)
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()
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()
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()
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()