def __init__(self, parent, ID): MultiSplitterWindow.__init__(self, parent, ID) self.SetOrientation( wx.VERTICAL ) self._controller = eDevController() self._controller.setNavigator(self) self._panels = list()
def __init__(self, parent): wx.Panel.__init__(self, parent, -1) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) self.leftsplitter = wx.SplitterWindow(self.splitter, style=wx.BORDER_NONE) p1 = ControllersPanel(self.leftsplitter) p2 = RecordPanel(self.leftsplitter, True) self.leftsplitter.SplitHorizontally(p1, p2, -300) p3 = SpecialsPanel(self.splitter) p4 = DetailsPanel(self.splitter) self.splitter.AppendWindow(self.leftsplitter, 180) self.splitter.AppendWindow(p3, 180) self.splitter.AppendWindow(p4, 150) self.controllersPanel = p1 self.specialsPanel = p3 self.detailsPanel = p4 self.recordPanel = p2 # layout import Layout Layout.SingleLayout(self, self.splitter) # bindings self.Bind(wx.EVT_BUTTON, self.OnPlay, self.detailsPanel.testButton) self.specialsPanel.onSelChangedCallback = self.detailsPanel.Load
def __init__(self, parent, id): wx.Frame.__init__(self, parent, id, 'Profile Generation', size=(1400, 800)) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) self.control_panel = ControlPanel(self.splitter) self.field_panel = FieldPanel(self.splitter) self.field_panel.control_panel = self.control_panel self.control_panel.field_panel = self.field_panel self.splitter.AppendWindow(self.field_panel, sashPos=self.field_panel.w) self.splitter.AppendWindow(self.control_panel) # Window dressings like status and menu bars; not wired to anything status_bar = self.CreateStatusBar() menubar_main = wx.MenuBar() file_menu = wx.Menu() edit_menu = wx.Menu() file_menu.Append(wx.NewIdRef(), 'Open Profile...', 'Open an existing profile') file_menu.Append(wx.NewIdRef(), 'Close', 'Quit the application') menubar_main.Append(file_menu, 'File') menubar_main.Append(edit_menu, 'Edit') self.SetMenuBar(menubar_main) self.SetStatusBar(status_bar)
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 __init__(self, parent, id): wx.Frame.__init__(self, parent, id, 'Planet Hunt', size=(1400, 600)) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) # The passing references to panels and controsl to each other # seems a bit sloppy and I want to do away with it. Not sure how yet. data_display_panel = DataDisplayPanel(self.splitter) data_modify_panel = DataModifyPanel(self.splitter, data_display_panel) data_search_panel = DataSearchPanel(self.splitter, data_display_panel, data_modify_panel) self.splitter.AppendWindow(data_search_panel, sashPos=150) self.splitter.AppendWindow(data_display_panel, sashPos=1050) self.splitter.AppendWindow(data_modify_panel) status_bar = self.CreateStatusBar() menubar_main = wx.MenuBar() file_menu = wx.Menu() edit_menu = wx.Menu() file_menu.Append(wx.NewIdRef(), 'Connect...', 'Connect to a new server') file_menu.Append(wx.NewIdRef(), 'Close', 'Quit the application') menubar_main.Append(file_menu, 'File') menubar_main.Append(edit_menu, 'Edit') self.SetMenuBar(menubar_main) self.SetStatusBar(status_bar)
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 __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)
def __init__(self, place, orientation, **kwds): self.orientation = orientation MultiSplitterWindow.__init__(self, place[0], style=wx.SP_LIVE_UPDATE) Widget.__init__(self, place, **kwds) Container.__init__(self) self.SetOrientation({ 'horizontal': wx.HORIZONTAL, 'vertical': wx.VERTICAL }[orientation])
def __init__(self, parent, player, artists_list): MultiSplitterWindow.__init__(self, parent) self.panel = ArtistPanel(self, player, artists_list) self.album_panel = Panel(self, "Choose an album to listen") self.song_panel = SongPanel(self, player) self.AppendWindow(self.panel) self.AppendWindow(self.album_panel) self.AppendWindow(self.song_panel) self.SetSashPosition(0, 200) self.SetSashPosition(1, 200) self.SetSashPosition(2, 200)
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 _SizeSizeWindows(self): total_window_w = self.GetClientSize()[self.orientation == 'vertical'] \ - 2*self._GetBorderSize() - self._GetSashSize()*(len(self._windows)-1) for win, sash in zip(self._windows, self._sashes): if win._stretch == 0: total_window_w -= sash total_stretch = sum(w._stretch for w in self._windows) for i, win in enumerate(self._windows): if win._stretch != 0: self._sashes[i] = total_window_w*win._stretch/total_stretch MultiSplitterWindow._SizeWindows(self)
def _SizeSizeWindows(self): total_window_w = self.GetClientSize()[self.orientation == 'vertical'] \ - 2*self._GetBorderSize() - self._GetSashSize()*(len(self._windows)-1) for win, sash in zip(self._windows, self._sashes): if win._stretch == 0: total_window_w -= sash total_stretch = sum(w._stretch for w in self._windows) for i, win in enumerate(self._windows): if win._stretch != 0: self._sashes[i] = total_window_w * win._stretch / total_stretch MultiSplitterWindow._SizeWindows(self)
class EditTab(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, -1) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) self.leftsplitter = wx.SplitterWindow(self.splitter, style=wx.BORDER_NONE) p1 = ControllersPanel(self.leftsplitter) p2 = RecordPanel(self.leftsplitter, True) self.leftsplitter.SplitHorizontally(p1, p2, -300) p3 = SpecialsPanel(self.splitter) p4 = DetailsPanel(self.splitter) self.splitter.AppendWindow(self.leftsplitter, 180) self.splitter.AppendWindow(p3, 180) self.splitter.AppendWindow(p4, 150) self.controllersPanel = p1 self.specialsPanel = p3 self.detailsPanel = p4 self.recordPanel = p2 # layout import Layout Layout.SingleLayout(self, self.splitter) # bindings self.Bind(wx.EVT_BUTTON, self.OnPlay, self.detailsPanel.testButton) self.specialsPanel.onSelChangedCallback = self.detailsPanel.Load def OnPlay(self, event): tree = self.specialsPanel.tree player = tree.GetPyData(tree.GetSelected()) player.play() # XXX: why I need this? def ResetSize(self): self.leftsplitter.SetSashPosition(180) def Unload(self): self.specialsPanel.Unload() self.recordPanel.Unload() self.detailsPanel.Unload() def Reload(self): self.specialsPanel.Reload() self.controllersPanel.Reload()
def __init__(self, parent): MultiSplitterWindow.__init__(self, parent) self.SetOrientation(wx.VERTICAL) self.p1 = TestPanel(self, "aaaaaaaaa") btn = wx.Button(self.p1, label='btn', pos=(300, -1)) self.Bind(wx.EVT_BUTTON, self.OnClick, btn) self.p2 = TestPanel(self, "bbbbbbbbb") self.p3 = TestPanel(self, "ccccccccc") self.p4 = TestPanel(self, "ddddddddd") # p1.Hide() # p2.Hide() # p3.Hide() self.AppendWindow(self.p1, parent.GetSize()[1] / 4) self.AppendWindow(self.p2, parent.GetSize()[1] / 4) self.AppendWindow(self.p3, parent.GetSize()[1] / 2)
def __init__(self, title, pos=(-1, -1), size=(700, 500), minsize=(700, 500)): """Setup window and sub-panels.""" logging.debug("in PuzzleWindow __init__") BaseWindow.__init__(self, title, pos, size=size) logging.debug("done base") UndoRedoMixin.__init__(self) ClipboardMixin.__init__(self) ShareWindowMixin.__init__(self) PrintMixin.__init__(self) logging.debug("done mixins") self.SetMenuBar(PuzzleMenuBar(self)) logging.debug("done menubar") # self.ShowFullScreen(True) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) logging.debug("made splitter") self.share_panel = SharingPanel(self.splitter) self.puzzle_panel = wx.Panel(self.splitter, wx.ID_ANY) logging.debug("done panels") if wx.Platform == "__WXMAC__": # This seems a little self-evident, but it needed to workaround # display bug in OSX Mountain Lion self.puzzle_panel.SetBackgroundColour(self.GetBackgroundColour()) elif wx.Platform == "__WXGTK__": self.puzzle_panel.SetBackgroundColour("White") self.clues_panel = CluesPanel(self.splitter) self.splitter.AppendWindow(self.share_panel, 280) self.splitter.AppendWindow(self.puzzle_panel, 250) self.splitter.DetachWindow(self.share_panel) self.share_panel.Hide() logging.debug("done splitter") minw, minh = minsize if wx.GetApp().config.show_clues: self.splitter.AppendWindow(self.clues_panel, 180) minw += 180 else: self.clues_panel.Hide() self.SetMinSize((minw, minh)) # Events for general window stuff self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnChangingSplitter) self.Bind(wx.EVT_SIZE, self.OnSize) self.splitter.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) # These get instantiated in setupPuzzle self.cluetext = self.puzzletitle = self.puzzlecopyright = self.pen_button \ = self.timer_button = None
def __init__(self,parent,id): #Fenster initialiseren wx.Frame.__init__(self, parent=parent, id=id, title='Remote', size=(200,200)) #Fenster aufteilen in mehrere Unterfenster splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) #Unterfenster initialisieren (in jeweiligen Klassen) und anhaengen panel1=Controlpanel(splitter) graph1=MatplotPanel1(splitter) graph2=MatplotPanel2(splitter) graph3=MatplotPanel3(splitter) splitter.AppendWindow(panel1) splitter.AppendWindow(graph1) splitter.AppendWindow(graph2) splitter.AppendWindow(graph3) #setzt Trennlinie splitter.SetSashPosition(1,600) splitter.SetSashPosition(0,170) #verbindet Schliessen-Knopf mit Funktion self.Bind(wx.EVT_CLOSE,self.closewindow)
def __init__(self, parent, log): self.log = log wx.Panel.__init__(self, parent, -1) cp = ControlPane(self) splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) self.splitter = splitter sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(cp) sizer.Add(splitter, 1, wx.EXPAND) self.SetSizer(sizer) p1 = SamplePane(splitter, "pink", "Panel One") p1.SetOtherLabel("There are two sash\n" "drag modes. Try\n" "dragging with and\n" "without the Shift\n" "key held down.") splitter.AppendWindow(p1, 140) p2 = SamplePane(splitter, "sky blue", "Panel Two") p2.SetOtherLabel("This window\nhas a\nminsize.") p2.SetMinSize(p2.GetBestSize()) splitter.AppendWindow(p2, 150) p3 = SamplePane(splitter, "yellow", "Panel Three") splitter.AppendWindow(p3, 125) p4 = SamplePane(splitter, "Lime Green", "Panel Four") splitter.AppendWindow(p4) self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnChanged) self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnChanging)
class MainWindow(wx.Frame): def __init__(self, parent, id): wx.Frame.__init__(self, parent, id, 'Planet Hunt', size=(1400, 600)) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) # The passing references to panels and controsl to each other # seems a bit sloppy and I want to do away with it. Not sure how yet. data_display_panel = DataDisplayPanel(self.splitter) data_modify_panel = DataModifyPanel(self.splitter, data_display_panel) data_search_panel = DataSearchPanel(self.splitter, data_display_panel, data_modify_panel) self.splitter.AppendWindow(data_search_panel, sashPos=150) self.splitter.AppendWindow(data_display_panel, sashPos=1050) self.splitter.AppendWindow(data_modify_panel) status_bar = self.CreateStatusBar() menubar_main = wx.MenuBar() file_menu = wx.Menu() edit_menu = wx.Menu() file_menu.Append(wx.NewIdRef(), 'Connect...', 'Connect to a new server') file_menu.Append(wx.NewIdRef(), 'Close', 'Quit the application') menubar_main.Append(file_menu, 'File') menubar_main.Append(edit_menu, 'Edit') self.SetMenuBar(menubar_main) self.SetStatusBar(status_bar) def force_update(self): # Jiggle the splitter 'sash' around to force a redraw. # No, I don't like having to do this but I can't figure out the # proper way to make the matplotlib graphs actually show up. sp = self.splitter.GetSashPosition(0) self.splitter.SetSashPosition(0, sp+1) self.splitter.SetSashPosition(0, sp+0) def close_window(self, event): self.Destroy()
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, 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 __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)
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()
def _OnMouse(self, evt): evt.ShiftDown = lambda: True return MultiSplitterWindow._OnMouse(self, evt)
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')
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
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()
def __init__(self, parent, ID, name): MultiSplitterWindow.__init__(self, parent, ID, style = wx.SP_LIVE_UPDATE, name = name)
def __init__(self, place, orientation, **kwds): self.orientation = orientation MultiSplitterWindow.__init__(self, place[0], style=wx.SP_LIVE_UPDATE) Widget.__init__(self, place, **kwds) Container.__init__(self) self.SetOrientation({'horizontal':wx.HORIZONTAL, 'vertical':wx.VERTICAL}[orientation])
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 PuzzleWindow(BaseWindow, UndoRedoMixin, ClipboardMixin, GameTimerMixin, ShareWindowMixin, PrintMixin): """A window with a puzzle in it.""" no_autowin = False pencil = False fullscreen = False def __init__(self, title, pos=(-1, -1), size=(700, 500), minsize=(700, 500)): """Setup window and sub-panels.""" logging.debug("in PuzzleWindow __init__") BaseWindow.__init__(self, title, pos, size=size) logging.debug("done base") UndoRedoMixin.__init__(self) ClipboardMixin.__init__(self) ShareWindowMixin.__init__(self) PrintMixin.__init__(self) logging.debug("done mixins") self.SetMenuBar(PuzzleMenuBar(self)) logging.debug("done menubar") # self.ShowFullScreen(True) self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE) logging.debug("made splitter") self.share_panel = SharingPanel(self.splitter) self.puzzle_panel = wx.Panel(self.splitter, wx.ID_ANY) logging.debug("done panels") if wx.Platform == "__WXMAC__": # This seems a little self-evident, but it needed to workaround # display bug in OSX Mountain Lion self.puzzle_panel.SetBackgroundColour(self.GetBackgroundColour()) elif wx.Platform == "__WXGTK__": self.puzzle_panel.SetBackgroundColour("White") self.clues_panel = CluesPanel(self.splitter) self.splitter.AppendWindow(self.share_panel, 280) self.splitter.AppendWindow(self.puzzle_panel, 250) self.splitter.DetachWindow(self.share_panel) self.share_panel.Hide() logging.debug("done splitter") minw, minh = minsize if wx.GetApp().config.show_clues: self.splitter.AppendWindow(self.clues_panel, 180) minw += 180 else: self.clues_panel.Hide() self.SetMinSize((minw, minh)) # Events for general window stuff self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnChangingSplitter) self.Bind(wx.EVT_SIZE, self.OnSize) self.splitter.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) # These get instantiated in setupPuzzle self.cluetext = self.puzzletitle = self.puzzlecopyright = self.pen_button \ = self.timer_button = None # self.Show() def size_clue_text(self): """Set size of clue text, partially based on window size.""" size = font_scale(20) scale = max(self.puzzle_panel.GetSize()[0] / 1000.0, 0.6) logging.debug("clue_text size scale = %s", scale) self.cluetext.SetFont(wx.Font(int(size * scale), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)) def setupPuzzle(self, puzzle, as_unsolved=False): """Setup puzzle sub-panes, board, and clues. This sets up all the appearance/binding/wx stuff; for logical things having to do with the beginning of the play of the puzzle, put that is startPuzzle (ie, if you wanted to note the time when a puzzle-solving session began). startPuzzle is called if we choose to restart a puzzle, this is called only open opening of a puzzle in the GUI. """ # Panel where board & labels will go self.puzzle_panel.puzzle = self.puzzle = puzzle puzzle.gui = self # Current clue text appears at top of puzzle in bold # (actual text is dynamically filled in) self.cluetext = wx.StaticText(self.puzzle_panel) self.cluetext.SetForegroundColour("#444444") # Puzzle title appear below grid if puzzle.author: title = "{0.title} - {0.author}".format(puzzle) else: title = puzzle.title self.puzzletitle = wx.StaticText(self.puzzle_panel, label=title) self.puzzletitle.SetFont(wx.Font(font_scale(11), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) self.puzzletitle.SetForegroundColour("#222222") # Puzzle copyright is below that any tiny self.puzzlecopyright = wx.StaticText(self.puzzle_panel, label=puzzle.copyright) self.puzzlecopyright.SetFont(wx.Font(font_scale(9), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)) self.puzzlecopyright.SetForegroundColour("#222222") # Add pen button self.pen_button = PenButton(self.puzzle_panel) # Add timer self.timer_button = TimerButton(self.puzzle_panel) # Add board, and labels to main panel self.board = Board(self.puzzle_panel) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.cluetext, 0, wx.TOP | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) sizer.Add(self.board, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 10) self.bottomsizer = bottomsizer = wx.BoxSizer(wx.HORIZONTAL) blsizer = wx.BoxSizer(wx.VERTICAL) blsizer.Add(self.puzzletitle) blsizer.Add(self.puzzlecopyright) bottomsizer.Add(blsizer, 1, wx.EXPAND) bottomsizer.Add(self.pen_button, 0, wx.ALIGN_RIGHT) bottomsizer.Add(self.timer_button, 0, wx.ALIGN_RIGHT) sizer.Add(bottomsizer, 0, wx.LEFT | wx.RIGHT | wx.TOP | wx.EXPAND, 10) self.puzzle_panel.SetSizer(sizer) # Fill clues into lists clues = self.puzzle.clues[1:] self.across_clues.populate([(c.num, c.across) for c in clues if c.across]) self.down_clues.populate([(c.num, c.down) for c in clues if c.down]) # Show puzzle and get started if as_unsolved: self.restartPuzzle() else: self.startPuzzle() sizer.Fit(self.puzzle_panel) # Puzzle-related events self.Bind(wx.EVT_IDLE, self.OnIdle) self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateSave) self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateSpecialAnswer) self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCluesOptions) self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateGoogle) self.Show() self.board.SetFocus() self.board.updateClueHighlight() self.tournamentSettings() config = wx.GetApp().config self.puzzle.grey_filled_clues = config.grey_filled_clues self.puzzle.on_any_change(skip_check_finished=True) self.need_show_locked = self.puzzle.pfile.is_solution_locked() self.size_clue_text() # Add Balloon help to clue text self.cluetext.Bind(wx.EVT_ENTER_WINDOW, self.hover_clue) self.cluetext.Bind(wx.EVT_LEAVE_WINDOW, self.end_hover_clue) def on_any_change(self): """Called by underlying puzzle when anything changes.""" if wx.GetApp().config.flash_correct: self.flash_correct() def flash_correct(self): """If our change makes current word correct, flash it.""" # True if word is correct; False if completed but wrong, None if not completed correct = self.puzzle.is_curr_word_correct() if correct is True or correct is False: for cell in self.puzzle.curr_word(): cell.flash_correct = correct self.board.DrawNow() wx.CallLater(100, self.flash_clear) def flash_clear(self): """Clear flash.""" for row in self.puzzle.grid: for cell in row: cell.flash_correct = None self.board.DrawNow() def hover_clue(self, event): """Show clue when you hover over clue text above grid. This is useful when the clue is too large to be completely readable in that space. """ logging.debug("hover on clue") self.hoverclue = hc = wx.StaticText(self.puzzle_panel, wx.ID_ANY, self.cluetext.GetLabel(), pos=(10, 10), style=wx.BORDER_SIMPLE) hc.SetBackgroundColour("#FFFFEE") hc.SetFont(wx.Font(font_scale(14), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.BOLD)) hc.Wrap(self.puzzle_panel.GetSize()[0] - 10) def end_hover_clue(self, event): """Hide clue when you leave hover over clue text above grid.""" logging.debug("hover off clue") try: assert self.hoverclue.Destroy() except Exception: pass def setupScrambled(self): """If puzzle is scrambled, hide check/reveal links.""" for i in [self.ID_CHECK_LETTER, self.ID_CHECK_WORD, self.ID_CHECK_PUZZLE, self.ID_REVEAL_LETTER, self.ID_REVEAL_WORD, self.ID_REVEAL_PUZZLE, self.ID_REVEAL_WRONG, self.ID_LOCK, ]: self.GetMenuBar().FindItemById(i).Enable(False) dlg = wx.MessageDialog( None, "This puzzle has a scrambled solution, so it is not possible to use the functions " "for checking or revealing correct letters.\n\n" "You can unlock the solution with the 'Unlock Puzzle' option in the Puzzle menu.", "Scrambled Puzzle", style=wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() assert dlg.Destroy() if not wx.GetApp().config.no_unlock: self.GetMenuBar().FindItemById(self.ID_UNLOCK).Enable(True) self.need_show_locked = False def startPuzzle(self): """Called at start (or restart) of puzzle. Technical stuff having to do with the GUI setup of a puzzle should be put in setupPuzzle; that is not called when we restart a puzzle. """ self.need_show_note = False if self.puzzle.note: logging.debug("Has note: =%s=", self.puzzle.note) self.GetMenuBar().Enable(self.ID_SHOW_NOTE, True) # test config = wx.GetApp().config if config.note_on_open: self.need_show_note = True else: self.GetMenuBar().Enable(self.ID_SHOW_NOTE, False) # test self.puzzle.initPuzzleCursor() GameTimerMixin.__init__(self, self.puzzle.timer_start, not self.puzzle.timer_start_paused) def restartPuzzle(self): """Restart puzzle. Called on open-as-unsolved, by using clear in menu, or by partner choosing clear. """ for x in self.puzzle.grid: for y in x: if not y.black: y.reset() self.startPuzzle() self.board.DrawNow() self.puzzle.add_undo() def tournamentSettings(self): """Set tournament settings.""" config = wx.GetApp().config find = self.GetMenuBar().FindItemById for i in [self.ID_CHECK_LETTER, self.ID_CHECK_WORD, self.ID_CHECK_PUZZLE, self.ID_REVEAL_LETTER, self.ID_REVEAL_WORD, self.ID_REVEAL_PUZZLE, self.ID_REVEAL_WRONG, ]: find(i).Enable(not config.no_cheats) find(self.ID_ONEACROSS).Enable(not config.no_oneacross) if config.no_unlock: find(self.ID_UNLOCK).Enable(False) else: find(self.ID_UNLOCK).Enable(self.puzzle.pfile.is_solution_locked()) self.no_autowin = config.no_autowin self.timer_button.Enable(not config.no_timerpause) find(self.ID_TIMER_TOGGLE).Enable(not config.no_timerpause) find(self.ID_TIMER_CLEAR).Enable(not config.no_timerpause) if config.no_timerpause: self.start_timer() def showNote(self): """Show puzzle note.""" # dlg = wx.lib.dialogs.ScrolledMessageDialog(None, self.puzzle.note, # "Puzzle Note", # size=(500, 800)) # dlg.ShowModal() # dlg.Destroy() note = NoteWindow(self.puzzle.note) self.need_show_note = False def UpdatePrefs(self): """Prefs were updated; make any needed changes.""" self.board.setupColors() self.board.setupSkipLetters() self.tournamentSettings() self.board.DrawNow() config = wx.GetApp().config self.puzzle.grey_filled_clues = config.grey_filled_clues # If we now no longer want to see clues changed when filled in, reset this everywhere-- # then we'll see this switch back to all black if not self.puzzle.grey_filled_clues: append = self.puzzle.clues_completed_queue.append for clue in self.puzzle.clues[1:]: if clue.across_filled: append(('across', clue.across_idx, False)) if clue.down_filled: append(('down', clue.down_idx, False)) # If we now do want to see greyed-out clues, we need # manually ask for this everywhere. else: self.puzzle.check_clue_fill_change(force=True) # ---------------- MENU EVENTS # # Menu items specific to a puzzle are defined here; ones that are not # (eg open puzzle, quit, etc) are in gui/app.py. # --------- File Menu def DoClose(self): """Check if we're dirty and, if so, prompt to save.""" if self.puzzle.dirty: dlg = wx.MessageDialog(self, ('The document "%s" has unsaved changes.\n\n' 'Would you like to save your changes before closing?\n') % self.puzzle.filename, 'Save Changes?', wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION) result = dlg.ShowModal() assert dlg.Destroy() if result == wx.ID_CANCEL: return False elif result == wx.ID_YES: self._save_puzzle() # Remove this window's menu from updating recent files wx.GetApp().config.filehistory.RemoveMenu(self.RecentMenu) # Close & destroy window self.stop_timer() if self.xmpp: self.XMPPDisconnect() assert self.Destroy() wx.GetApp().windows.remove(self) def OnClose(self, event): """Close puzzle.""" logging.debug("On close") self.DoClose() # If no windows open, show dummy if not wx.GetApp().windows: logging.debug("reopening dummy after puzzle close") wx.GetApp().OpenDummy() logging.debug("On close done") def _save_puzzle(self, path=None): """Save puzzle, showing errors. Called by DoClose, OnQuit, OnSave, and OnSaveAs. """ try: self.puzzle.save_puzzle(path) except IOError as e: dlg = wx.MessageDialog(None, "Fail saved: %s" % e, "Save Error", wx.OK | wx.ICON_ERROR) dlg.ShowModal() assert dlg.Destroy() return def OnSave(self, event): """Save puzzle.""" self._save_puzzle() def OnSaveAs(self, event): """Save-as puzzle.""" wildcard = "Across Lite Puzzle (*.puz)|*.puz" fname = suggestSafeFilename(self.puzzle.dirname, self.puzzle.filename) dlg = wx.FileDialog( self, message="Save puzzle as ...", defaultDir=self.puzzle.dirname, defaultFile=fname, wildcard=wildcard, style=wx.SAVE ) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self._save_puzzle(path=path) assert dlg.Destroy() def OnRevert(self, event): """Revert to saved version of puzzle.""" self.puzzle.revert_puzzle() self.board.DrawNow() # --------- Edit Menu def OnStartOver(self, event): """Start puzzle over. Often called by """ dlg = wx.MessageDialog(self, "Are you sure you want to clear the entire grid?", "Clear Grid?", wx.OK | wx.CANCEL) result = dlg.ShowModal() assert dlg.Destroy() if result == wx.ID_CANCEL: return self.restartPuzzle() if self.xmpp is not None: self.xmpp.send_clear([("*", "*")]) def OnSpecialAnswer(self, event): """Enter special answer in cell.""" self.board.SpecialAnswer() def OnTogglePen(self, event): """Toggle pencil/pen""" self.pencil = not self.pencil tool = "Pen" if self.pencil else "Pencil" self.GetMenuBar().FindItemById(self.ID_TOGGLE_PEN).SetText("Use %s\tCtrl-E" % tool) self.pen_button.SetValue(self.pencil) # --------- Puzzle Menu def OnShowNote(self, event): """Show puzzle note.""" self.showNote() def OnCheckLetter(self, event): """Check letter under cursor.""" if self.puzzle.check_letter(): self.board.DrawNow() def OnCheckWord(self, event): """Check current word.""" if self.puzzle.check_word(): self.board.DrawNow() def OnCheckPuzzle(self, event): """Check entire puzzle.""" if self.puzzle.check_puzzle(): self.board.DrawNow() def OnRevealLetter(self, event): """Reveal current letter.""" if self.puzzle.reveal_letter(): self.board.DrawNow() def OnRevealWord(self, event): """Reveal curent word.""" if self.puzzle.reveal_word(): self.board.DrawNow() def OnRevealPuzzle(self, event): """Reveal entire puzzle.""" if self.puzzle.reveal_puzzle(): self.board.DrawNow() def OnRevealWrong(self, event): """Reveal incorrect letters.""" if self.puzzle.reveal_incorrect(): self.board.DrawNow() def OnUnlock(self, event): """Unlock puzzle.""" # This might be able to use the speed C-based unlocker or the Python one. We could treat # them the same but the C one is so much faster that it doesn't make sense to show all the # dialog boxes. if FAST_UNLOCK: key = self.puzzle.break_encryption() else: dlg = wx.MessageDialog(self, "Depending on the speed of your computer, unlocking a" " puzzle can take several seconds. Once unlocked, you" " can use the check and reveal features of the puzzle." "\n\nUnlock puzzle?", "Unlock Puzzle?", wx.OK | wx.CANCEL) result = dlg.ShowModal() assert dlg.Destroy() if result != wx.ID_OK: return dlg = wx.ProgressDialog( "Unlocking", "Unlocking puzzle. This may take a moment.", maximum=8999, # num of possibilities parent=self, style=(wx.PD_APP_MODAL | wx.PD_CAN_ABORT | wx.PD_ELAPSED_TIME | wx.PD_AUTO_HIDE)) # Key is from 1000-9999 keep_going = True key = 1000 unlocked = False unlock_solution = self.puzzle.pfile.unlock_solution while keep_going and key < 10000: if unlock_solution(key): unlocked = True break if key % 25 == 0: # Updating dlg for every key attempt slows down loop; # Do once every 25 times and it's still nicely responsive # to canceling and updating time. (keep_going, skip) = dlg.Update(key - 1000) key += 1 assert dlg.Destroy() # busy = PBI.PyBusyInfo("Decrypting; please wait...") # wx.Yield() # del busy if not key: wx.MessageBox("Puzzle could not be unlocked.") return # Reload puzzle self.board.DrawNow() # Mark as dirty so Save is enabled self.puzzle.dirty = True wx.MessageBox("Puzzle successfully unlocked. Key was: %s" % key) if not wx.GetApp().config.no_cheats: for i in [self.ID_CHECK_LETTER, self.ID_CHECK_WORD, self.ID_CHECK_PUZZLE, self.ID_REVEAL_LETTER, self.ID_REVEAL_WORD, self.ID_REVEAL_PUZZLE, self.ID_REVEAL_WRONG, ]: self.GetMenuBar().FindItemById(i).Enable(True) self.GetMenuBar().FindItemById(self.ID_LOCK).Enable(True) self.GetMenuBar().FindItemById(self.ID_UNLOCK).Enable(False) def OnLock(self, event): """Lock puzzle.""" dlg = wx.TextEntryDialog(self, "Enter a numeric code between 1000 and 9999 to lock puzzle.", "Lock Puzzle") dlg.SetValue(str(random.randint(1000, 9999))) fail = False result = dlg.ShowModal() if result == wx.ID_OK: try: key = int(dlg.GetValue()) except ValueError: fail = True else: if key < 1000 or key > 9999 or len(dlg.GetValue()) != 4: fail = True if fail: wx.MessageBox("Invalid key. Lock operation failed.") return self.puzzle.pfile.lock_solution(key) # Reload puzzle self.puzzle.updateAnswers() self.board.DrawNow() # Mark as dirty so Save is enabled self.puzzle.dirty = True wx.MessageBox("Puzzle successfully locked.") for i in [self.ID_CHECK_LETTER, self.ID_CHECK_WORD, self.ID_CHECK_PUZZLE, self.ID_REVEAL_LETTER, self.ID_REVEAL_WORD, self.ID_REVEAL_PUZZLE, self.ID_REVEAL_WRONG, self.ID_LOCK, ]: self.GetMenuBar().FindItemById(i).Enable(False) if not wx.GetApp().config.no_unlock: self.GetMenuBar().FindItemById(self.ID_UNLOCK).Enable(True) def _cluesFontChange(self, delta): """Change font size of clue list.""" for cl in [self.across_clues, self.down_clues]: cl.font_size += delta cl.changeFontSize() def OnCluesFontBigger(self, event): """Increase font size of clue list.""" self._cluesFontChange(+1) def OnCluesFontSmaller(self, event): """Decrease font size of clue list.""" self._cluesFontChange(-1) def OnShowClues(self, event): """Toggle visibility of clue lists.""" minw = self.puzzle.width * 22 minh = self.puzzle.height * 22 + 25 w, h = self.Size if event.IsChecked(): self.splitter.InsertWindow(2, self.clues_panel, 200) minw += 150 self.SetSize((w + 250, h)) else: self.splitter.DetachWindow(self.clues_panel) self.clues_panel.Hide() self.SetSize((max(w - 250, minw), h)) logging.debug("Min size w=%s, h=%s", minw, minh) self.SetMinSize((minw, minh)) self.OnSize(None) def OnOneAcross(self, event): """Lookup current clue in oneacross.com.""" clue = self.puzzle.curr_clue() word = self.puzzle.curr_word_text() # Sometimes, using key shortcut keeps Puzzle highlit # Let's make sure this happens out-of-band. wx.CallAfter(OpenOneAcross, clue, word) def OnGoogle(self, event): """Lookup current clue in google.com.""" clue = self.puzzle.curr_clue() word = self.puzzle.curr_word_text() # Sometimes, using key shortcut keeps Puzzle highlit # Let's make sure this happens out-of-band. wx.CallAfter(OpenGoogle, clue, word) def OnFullScreen(self, event): """Switch to full-screen.""" logging.debug("fullscreen") self.fullscreen = not self.fullscreen self.bottomsizer.Clear() self.ShowFullScreen(self.fullscreen) # ---------------- OTHER EVENTS def OnIdle(self, event): """Idle activities. Things go here if: - they need to happen after setup once all the rendering is done. - they need to react to changes in the underlying puzzle that don't flow through the GUI code (like seeing if the puzzle is dirty or solved) """ # We don't want to show these notes until the entire screen has been rendered and sized # and this window is brought to the front, so we can't put in the setupPuzzle-style places. # It will only be done once. if self.IsActive() and self.need_show_note: self.showNote() if self.IsActive() and self.need_show_locked: self.setupScrambled() # Check if puzzle-is-correct flag is set and, if so, announce congratulations. if self.puzzle.puzzle_correct_flag and not self.no_autowin: self.stop_timer() self.puzzle.puzzle_correct_flag = False dlg = wx.MessageDialog(self, 'Good work!', 'Puzzle Finished', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() assert dlg.Destroy() for direction, idx, filled in self.puzzle.clues_completed_queue: if direction == "across": self.across_clues.update_filled(idx, filled) else: self.down_clues.update_filled(idx, filled) self.puzzle.clues_completed_queue = [] # On OSX, this puts a black dot in the close button when puzzle # is dirty (a common OSX UI thing to do). On other systems, this # is a no-op. self.OSXSetModified(self.puzzle.dirty) def OnUpdateGoogle(self, event): """Update Google menu options to reflect state of system. In order to use the Google lookup, the word you're on needs to be completed. """ event_id = event.GetId() if event_id == self.ID_GOOGLE: event.Enable(self.puzzle.curr_word_complete()) else: event.Skip() def OnUpdateSave(self, event): """Update save menu options to reflect state of system.""" event_id = event.GetId() if event_id == self.ID_SAVE: event.Enable(self.puzzle.dirty) else: event.Skip() def OnUpdateSpecialAnswer(self, event): """Only allow special answers in rebus squares.""" event_id = event.GetId() if event_id == self.ID_ENTER_REBUS: event.Enable(bool(self.puzzle.curr_cell.rebus_answer)) else: event.Skip() def OnUpdateCluesOptions(self, event): """Only allow font +/- if clues visible.""" event_id = event.GetId() if event_id == self.ID_CLUES_BIGGER or event_id == self.ID_CLUES_SMALLER: event.Enable(self.clues_panel.Shown) else: event.Skip() def OnMouse(self, evt): """Mouse used in window.""" # THIS IS A DREADFUL HACK. # # Normally, if user resizes a splitter, it add/takes away space from the edge window # (ie, if user resizes splitter between sharing + board, the clues window changes width # to match). We want the "nearer neighbor" to change (the board window). wxWindows handles # this automatically if the shift key is held down during resize. # # There does not appear to be a way to get this behavior except by tricking it into # thinking the shift key is held down during all mouse movement. So, set shift key down # and then delegate to the underlying wx call for mousing on the splitter. logging.debug("on mouse") if hasattr(evt, 'SetShiftDown'): # Not present in wx2.8 evt.SetShiftDown(True) self.splitter._OnMouse(evt) def OnChangingSplitter(self, evt): """Changing splitters between windows.""" logging.debug("on changing splitter") if evt.GetSashPosition() < 180: # Minimum size for each splitter evt.Veto() self.size_clue_text() def OnSize(self, evt=None): """Resizing window.""" # Keep proportions of splits logging.debug("On size") if evt: w = evt.GetSize()[0] else: w = self.GetSize()[0] if self.share_panel.IsShown() and self.clues_panel.IsShown(): self.splitter.SetSashPosition(0, 180) self.splitter.SetSashPosition(1, ((w - 180) * .65)) elif self.share_panel.IsShown(): self.splitter.SetSashPosition(0, 180) elif self.clues_panel.IsShown(): self.splitter.SetSashPosition(0, w * .55) else: # self.splitter.SetSashPosition(0, w) pass self.splitter.SizeWindows() if evt: evt.Skip() self.size_clue_text()
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
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_)
def __init__(self, parent): self.parent = parent wx.Panel.__init__(self, parent, -1) sizer = wx.BoxSizer(wx.VERTICAL) sizer1 = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(sizer1, 0, wx.EXPAND | wx.ALL, 2) regex_title = wx.StaticBox(self, -1, tr("Regular expression")) box1 = wx.StaticBoxSizer(regex_title, wx.VERTICAL) self.text = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE) box1.Add(self.text, 1, wx.EXPAND | wx.ALL, 2) sizer1.Add(box1, 1, wx.EXPAND | wx.RIGHT, 4) box = wx.BoxSizer(wx.VERTICAL) self.btnRun = wx.Button(self, -1, tr('Run')) box.Add(self.btnRun, 0, wx.ALL, 2) self.btnCreate = wx.Button(self, -1, tr('Create')) box.Add(self.btnCreate, 0, wx.ALL, 2) sizer1.Add(box, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 4) find_title = wx.StaticBox(self, -1, tr("Methods")) box2 = wx.StaticBoxSizer(find_title, wx.VERTICAL) self.rdoFindFirst = wx.RadioButton(self, -1, tr("Find First"), style=wx.RB_GROUP) self.rdoFindAll = wx.RadioButton(self, -1, tr("Find All")) box2.Add(self.rdoFindFirst, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) box2.Add(self.rdoFindAll, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) sizer1.Add(box2, 0, wx.EXPAND | wx.RIGHT, 4) from_title = wx.StaticBox(self, -1, tr("From")) box3 = wx.StaticBoxSizer(from_title, wx.VERTICAL) self.rdoFromBeginning = wx.RadioButton(self, -1, tr("From beginning"), style=wx.RB_GROUP) self.rdoFromCaret = wx.RadioButton(self, -1, tr("From caret")) self.rdoInSelection = wx.RadioButton(self, -1, tr("In Selection")) box3.Add(self.rdoFromBeginning, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) box3.Add(self.rdoFromCaret, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) box3.Add(self.rdoInSelection, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) sizer1.Add(box3, 0, wx.EXPAND | wx.RIGHT, 4) flag_title = wx.StaticBox(self, -1, tr("Flags")) box4 = wx.StaticBoxSizer(flag_title, wx.VERTICAL) grid1 = wx.FlexGridSizer(0, 2, 0, 0) box4.Add(grid1, 1, wx.EXPAND | wx.ALL, 2) sizer1.Add(box4, 0, wx.EXPAND | wx.RIGHT, 4) groups = [ ('ignore', tr("Ignore Case(I)"), re.I, 're.I'), ('locale', tr("Locale(L)"), re.L, 're.L'), ('multiline', tr("Multi Line(M)"), re.M, 're.M'), ('dotall', tr("Dot All(S)"), re.S, 're.S'), ('unicode', tr("Unicode(U)"), re.U, 're.U'), ('verbose', tr("Verbose(V)"), re.X, 're.X'), ] self.checks = {} k = 0 for i, v in enumerate(groups): ctrl_name, label, flag, strflag = v obj = wx.CheckBox(self, -1, label) wx.EVT_CHECKBOX(obj, obj.GetId(), self.OnChange) self.checks[ctrl_name] = obj, flag, strflag grid1.Add(obj, k, wx.ALL, 2) if i % 2 == 0: k += 1 self.splitter = splitter = MultiSplitterWindow(self) self.result = CheckList.List(splitter, columns=[ (tr("Items"), 150, 'left'), (tr("Values"), 300, 'left'), ], style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_SINGLE_SEL) splitter.AppendWindow(self.result, 450) self.matches = wx.TextCtrl(splitter, -1, "", style=wx.TE_MULTILINE | wx.TE_RICH2) splitter.AppendWindow(self.matches, 150) splitter.SetOrientation(wx.HORIZONTAL) sizer.Add(splitter, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 4) self.load() wx.EVT_BUTTON(self.btnRun, self.btnRun.GetId(), self.OnChange) wx.EVT_BUTTON(self.btnCreate, self.btnCreate.GetId(), self.OnCreateExpression) wx.EVT_TEXT(self.text, self.text.GetId(), self.OnChange) self.SetSizer(sizer) self.SetAutoLayout(True)
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()