예제 #1
0
    def __init__(self, parent, ID):
        MultiSplitterWindow.__init__(self, parent, ID)
        self.SetOrientation( wx.VERTICAL )

        self._controller = eDevController()
        self._controller.setNavigator(self)
        self._panels     = list()
예제 #2
0
파일: EditTab.py 프로젝트: iambus/PyLoad
    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
예제 #3
0
    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)
예제 #4
0
    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
예제 #5
0
    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)
예제 #6
0
    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)
예제 #8
0
 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])
예제 #9
0
 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)
예제 #10
0
    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)
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
파일: EditTab.py 프로젝트: iambus/PyLoad
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()
예제 #14
0
    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)
예제 #15
0
    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
예제 #16
0
    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)
예제 #17
0
파일: test2.py 프로젝트: Maor2871/Code
    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)
예제 #18
0
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)
예제 #20
0
    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)
예제 #21
0
    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)
예제 #22
0
class MainScreen(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=wx.Size(1280, 800),style=wx.DEFAULT_FRAME_STYLE)
        # 窗口居中
        self.CenterOnScreen()
        # 分割窗口
        self.sp = MultiSplitterWindow(self)
        self.sp.SetOrientation(wx.VERTICAL)
        self.Bind(wx.PyEventBinder(wx.wxEVT_SPLITTER_SASH_POS_CHANGING),self.sashchange)
        # Top窗口:panel
        self.p_top = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)
        self.p_top.Hide()
        # 下部分窗口:左右分割的splitter
        self.sp_main = MultiSplitterWindow(self.sp)
        # 上下两部分窗口填充
        self.sp.AppendWindow(self.p_top, sashPos=self.GetSize()[1] / 6)
        self.sp.AppendWindow(self.sp_main)

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

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

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

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

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

    def sashchange(self,e):
        e.Veto()
예제 #23
0
 def _OnMouse(self, evt):
     evt.ShiftDown = lambda: True
     return MultiSplitterWindow._OnMouse(self, evt)
예제 #24
0
class ConcurrentWindow(wx.Panel, Mixin.Mixin):
    __mixinname__ = 'concurrent'
    concurrent_id = 0

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

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

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

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

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

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

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

        self.splitter = MultiSplitterWindow(self, -1)

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

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

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

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

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

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

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

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

    me = property(__get_me)

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

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

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

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

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


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

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

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

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

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

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

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

        self.filelist.PopupMenu(self.filelistpopmenus)

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

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

        self.filelist.PopupMenu(self.userlistpopmenus)

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

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

            wx.CallAfter(f, self)

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

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

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

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

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

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

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

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

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

        self.chatroom.SetReadOnly(1)

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

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

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

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

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

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

        wx.CallAfter(f, self)

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

        wx.CallAfter(f, self)

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

        wx.CallAfter(f, self)

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

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

        wx.CallAfter(f, self)

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

        wx.CallAfter(f, self)

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

        wx.CallAfter(f, self)

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

        wx.CallAfter(f, self)

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

        wx.CallAfter(f, self)

    def ClientClose(self):
        self.OnConnect()

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

    def ChangeUserAction(self, username, action):
        for i in range(self.userlist.GetItemCount()):
            name = self.userlist.GetItem(i, 1).GetText()
            self.userlist.SetStringItem(i, 2, '')
            if name == username:
                self.userlist.SetStringItem(i, 2, 'active')
예제 #25
0
    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
예제 #26
0
class PanelMiners(wx.Panel):
    lock = threading.RLock()

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

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

        self.num_miners = num_miners

        self.devicesJson = self.loadDevices()

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

        self.splitter.SetMinimumPaneSize(1)

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

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

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

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

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

        self.SetSizer(sizer)

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

        return json.loads(data)

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

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

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

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

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

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

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

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

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

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

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

        return ret0 or ret1 or ret2 or ret3

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

        if exit:
            self.stopLoop(self.checkMinersExited)

        elif wait:
            self.stopLoop(self.checkMinersReady)

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

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

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

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

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

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

        from miner import PanelMinerInstance

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

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

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

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

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

            return False

        return True

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

            return True

        return False

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

            return True

        return False

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

            return False

        return True

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

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

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

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

            num_not_ready = self.num_miners - num_ready

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

                factored_total = factored_num_ready + num_not_ready

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

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

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

                if event:
                    event.Skip()

                return

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

        except (PyDeadObjectError, AttributeError):
            pass

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

            if not self.resize_lock:
                self.resize_lock = True

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

                steps = 15

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

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

                    pct = float(w) / steps

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

                    time.sleep(0.01)

                self.resize_lock = False

        except PyDeadObjectError:
            pass

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

    def getExpansionStatus(self):
        return self.collapsePanel.collapseBtn.GetValue()
예제 #27
0
 def __init__(self, parent, ID, name):
     MultiSplitterWindow.__init__(self, parent, ID,
         style = wx.SP_LIVE_UPDATE, name = name)
예제 #28
0
 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])
예제 #29
0
class TodoFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent=parent, title=title, size=(400, 400))

        self.model = None
        self.parent = parent

        self.edit_window_visible = False

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

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

        self.switch = False

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

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

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

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

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

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

        # self.main_splitter.SetMinimumPaneSize(0)

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

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

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

        self.search_box = SearchBox(self)

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

        self.search_box.SetFocus()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        event.Skip()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        dialog.Destroy()

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

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

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

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

                        # Redisplay the list
                        self._reload_view()

            dialog.Destroy()

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

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

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

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

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

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

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

        # wx.KeyEvent(wx.WXK_RETURN)

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

        # self.update_temp_data(current)

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

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

    def _clear_temp_data(self):
        temp_data.clear()

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

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

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

    def _sort_temp_data(self):
        temp_data.sort_alphabetically()
        temp_data.sort_numerically()
예제 #30
0
 def _OnMouse(self, evt):
     evt.ShiftDown = lambda: True
     return MultiSplitterWindow._OnMouse(self, evt)
예제 #31
0
class PanelPresences(wx.Panel):
    def __init__(self, parent, ID=-1):
        wx.Panel.__init__(self, parent, ID, name="panel_presences")
        self.init = False

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

        self.splitterH.SetMinimumPaneSize(100)

        self.__do_layout()

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

        self.init = True

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


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

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

    def GetSelectionDates(self):
        return selectionDates

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

    def GetSelectionPersonnes(self):
        return selectionPersonnes

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

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

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

        if "planning" in listeElements or listeElements == []:
            self.panelPlanning.DCplanning.Init_valeurs_defaut()
            self.panelPlanning.RechargeDictCategories()
            self.MAJpanelPlanning(reinitSelectionPersonnes=True)
        if "listCtrl_personnes" in listeElements or listeElements == []:
            self.panelPersonnes.MAJpanel()
        if "legendes" in listeElements or listeElements == []:
            self.panelLegendes.MAJpanel()
        if "calendrier" in listeElements or listeElements == []:
            self.panelCalendrier.MAJpanel()
예제 #32
0
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()
예제 #33
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
예제 #34
0
class icMainWindow(wx.Frame):
    """
    Класс окна системы.
    """
    def __init__(self,
                 Name_,
                 WinStruct_,
                 ResFile_='',
                 Parent_=None,
                 Runner_=None):
        """
        Конструктор.
        @param Name_: Имя окна.
        @param WinStruct_: Словарь, описывающий окно.
        @param ResFile_: Имя ресурсного файла.
        @param Parent_: Родительское окно.
        @param Runner_: Родительский ДВИЖОК.
        """
        # --- Свойства класса ---
        # Иденитификатор числовой
        self._ID = 0
        # Имя
        self._Name = ''
        # Имя ресурсного файла
        self._ResFile = ''
        # Флаг разрешения/запрещения изменения заголовка окна
        self._TitleReadOnly = 1
        # Выражение для формирования заголовка окна
        self._TitleFunc = {}
        # Объект главного менеджера системных панелей
        self._MainNotebook = None
        # Функция вызываемая каждй раз при отрисовке главного окна.
        self._PaintFunc = None
        # Движок
        self._RunnerApp = Runner_
        # Открытие органайзера
        self._OnOrgOpen = None
        # Закрытие органайзера
        self._OnOrgClose = None

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if event:
            event.Skip()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def setMenuBar(self, MenuBar_):
        """
        Установить горизонтальное меню.
        """
        try:
            self.SetMenuBar(MenuBar_)
            MenuBar_.Refresh()
        except:
            io_prnt.outErr(
                u'Ошибка установки горизонтального меню <%s> в главное окно.' %
                MenuBar_)
예제 #35
0
    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)
예제 #36
0
class PanelPersonnes(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, name="Personnes")
        self.parent = parent
        self.init = False

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

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

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

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

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

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

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

        self.__set_properties()
        self.__do_layout()

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

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

        self.AffichePanelResume(False)

        self.init = True

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

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

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

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

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

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

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

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

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

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

        self.grid_sizer_D = grid_sizer_D

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

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

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

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

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

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

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

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

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

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

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

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

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

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