2017年2月20日月曜日

わりと良い天気でしたね、日曜だね

本日のマトメは
以下です。

ソースとは、関係がないけど。。。
・気になる、PDBコマンド送出後の対応(待ちますか?)
・setFuncは大丈夫かな? 同期が必要かな






#!/usr/bin/python -u
# -*- coding: utf-8 -*-


import io
import sys,os
import time
import subprocess
import threading
import signal

import editPane
import textCmd
import textSrc
import gridEx

import wx
import wx.lib.newevent

ERR_FILE ="errTrace.log"


'''---------------------------------------------------
  global function
------------------------------------------------------'''
def getErrInfo( s ):
  '''エラー情報を取り出す'''

  data =[]
  errData = s = s.split("\n")
  no =0   #対応する行
  i = 0
  startSw=False
  for line in s:
    i +=1
    print "line",i,line

    if s == "Traceback (most recent call last):": startSw= True
    if "  File " not in line:
      continue
    #print "line2",line

    if "pdb.py"  in line and "main" in line :
      continue
    if "pdb.py" in line and "_runscript"  in line :
      continue
    if "bdb.py"  in line and "run"  in line :
      continue
    if "<string>" in line and "<module>"  in line :
      continue

    print "gaitou",line
    data.append( line + "\n" )
    no =i

  l = len( data )-1
  sss = data[ l ].strip()
  sss = sss.split(", ")
  file = sss[0][5:].strip('"')
  line = sss[1][5:]
  return file,line, no, errData

def getKakData( kigo1,kigo2, lineData):
    '''括弧で包まれた内容を取得する'''

    start= lineData.index( kigo1 ) +1
    end  = lineData.index( kigo2 )
    ct   = end -start

    data= lineData[start:start+ct]
    return data



def hanteiSTD( lineData ):

  '''標準入力が必要かを判定する'''
  cmd     = ""
  stdSW   =True
  fnm     =""
  mnm     =False
  lineNO  = 0


  if lineData == "(Pdb) ":
    stdSW= False

  elif lineData[:3] == "-> ":
    stdSW= False

  elif lineData[:2] == "> ":
    stdSW= False

    start= lineData.index('(') +1
    lineNO= getKakData('(',')', lineData )
    lineNO= int( lineNO )
    fnm  = lineData[2:start-1]
    mnm= "<module>" in lineData

  elif lineData == "--Return--" or lineData == "--Call--":
    stdSW= False

  return stdSW, fnm, lineNO, mnm


hanteiSTD.cmd = ""



class dbgSub(threading.Thread):

    def __init__(self, outS, func, fm  ):
      threading.Thread.__init__(self)
      self.outS = outS
      self.func = func
      self.fm   = fm

      # キューイベント、スレッド処理
      self.queEvent, self.QUE_EVENT = wx.lib.newevent.NewEvent()
      self.QUE_EVENT( self.fm, func)
      self.fm.Bind( self.QUE_EVENT, func)

    def run(self):

        print '  === start sub thread ==='
        dest = bytearray(9000) # all zero bytes
        v = memoryview(dest)
        while True:
          #output= self.outS.read(1)
          nn = self.outS.readinto( v )

          #print "*",nn,dest
          if nn==0: break
          #print(repr(dest))
          #continue


          #self.func( output )
          #print "run Data nasi desu"
          output = str( dest)
          output = output[0:nn]
          evt = self.queEvent( data=output  )
          wx.PostEvent(self.fm, evt)
          """
          sys.stdout.write( output )
          sys.stdout.flush()
          """

        print '  === end sub thread ==='






class dbg( threading.Thread ):


  def __init__(self, aPara, func, func2,fm ):

    threading.Thread.__init__(self)
    self.arg = ["python","-u","-m","pdb"]
    self.arg.extend( aPara )

    self.func = func
    self.func2= func2
    self.fm   = fm
    dbg.prgSrc = False
    dbg.cmdList=['r','n','s']                #デバッカーコマンド 制御(行移動)あり
    dbg.cmdSave=""                          #エンターのみの場合は、以前のコマンドw実行

  def run(self):

    self.stopFlag = False
    self.proc = subprocess.Popen(
                      self.arg,
                      stdin=subprocess.PIPE,
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE,
                      bufsize=0)


    self.outS    = io.open( self.proc.stdout.fileno(), mode="rb",
                        closefd=False,buffering=0)
    self.outE    = io.open( self.proc.stderr.fileno(), mode="rb",
                        closefd=False,buffering=0)

    self.th     = dbgSub( self.outS, self.func,   self.fm )
    self.thErr  = dbgSub( self.outE, self.func2,  self.fm )

    self.thErr.setDaemon(True)
    self.th.setDaemon(True)
    self.thErr.start()
    self.th.start()

    time.sleep(1)


    print '  === start thread ==='
    while self.stopFlag == False:
      time.sleep(1)

    print '  === end thread ==='
    sys.exit(0)


  def stop(self):
      self.stopFlag = True
      """スレッドを停止させる"""
      """
      self.stop_event.set()
      self.thread.join()    #スレッドが停止するのを待つ
      """

  def cmd( self, cmd, prgSrc=False ):

    dbg.prgSrc = prgSrc

    # CURSOR --wait
    wx.SetCursor ( wx.StockCursor ( wx.CURSOR_WAIT ) )
    self.fm.timer.Start( 1000 )

    #エンターのみの場合は、以前のコマンドだよ
    if cmd =="":
      cmd = dbg.cmdSave
    elif cmd in dbg.cmdList:
      dbg.cmdSave = cmd

    #変数代入の場合
    if cmd[:2]=="fo" or cmd[:2]=="__":
      hanteiSTD.cmd = cmd
    elif "=" in cmd:
      hanteiSTD.cmd = "="
    else:
      hanteiSTD.cmd = cmd

    #print "hanteiSTD.cmd=",hanteiSTD.cmd
    self.proc.stdin.write( cmd + "\n" )

  def end( self ):
    self.stop()




'''
---------------------------------------------------
  debug-core main
---------------------------------------------------
'''
class DbgC():
  """ debug core class """


  inst =None

  def __init__(self):

    DbgC.inst = self          # instance save
    self.rcvData=""
    self.frame  = None
    self.timer  = None
    self.editPane= None
    self.panel  = PanelEx.inst
    self.txt    = textCmd.TextCmd.inst
    self.pSrc   = textSrc.TextSrc.inst

    self.pdb = None
    self.app = None

    self.dbgVal1 ="__x=locals();; del __x['__builtins__']"
    self.dbgVal2 ="for __key in __x.iterkeys(): print  __key "
    self.dbgVal3 ="__keylist="
    self.dbgVal4 ="for  __key in __keylist: print '%s,%s,%s'  %( __key, type(__x[ __key ] ), __x[ __key ] )  "
    self.bpTbl ={}


  def setAppInst( self, inst ):
      self.app = inst

  def setEditPaneInst( self, inst ):
    self.editPane= inst
    self.editPane.setFunc( self.cmdSrcFunction )


  def cmdSrcFunction( self, inst ):
    self.pSrc   = self.editPane.fileInst
    self.pSrc.setFunc( self.cmdFunc )

  def setFrameInst( self, fm ):
    self.frame  = fm.inst
    self.timer  = fm.timer


  def toolBarEnable( self, st,n, flg):

    for i in range( n ):
      self.frame.toolbar.EnableTool( st+i, flg)


  def dbgStart( self ):
      ''' debug start functione '''

      self.frame.SetStatusText( "debug start" )

      # setting breakPoint table
      self.bpTbl.clear()
      # プログラムソース画面のインスタンス
      self.pSrc   = self.editPane.fileInst
      args        =[ self.editPane.fileName ]


      #ここでは、ツールバー以外からよびだされた場合、イメージをONする
      if self.frame.toolbar.GetToolState( 900 )== False:
        self.frame.toolbar.ToggleTool(900, True)


      self.rcvData =""                     #エラー時に、大丈夫かな

      #os.remove( ERR_FILE )
      f = open( ERR_FILE, 'w')
      f.write( "" )
      f.close()

      #self.pSrc.setDbgMode(True)
      for fnInst in self.editPane.instList:
        fnInst.setDbgMode(True)

      self.pdb = dbg( args, self.rcv, self.rcvErr, self.frame )
      self.pdb.setDaemon(True)
      self.pdb.start()
      self.pSrc.SetFocus()
      print "start pdb"
      #self.panel.SetBackgroundColour("green")

      self.txt.start()
      self.toolBarEnable(800,3,False)      #ツールバーの無効
      self.toolBarEnable(901,6,True)

  def dbgEnd( self ):
      ''' debug end '''

      #ここでは、ツールバー以外からよびだされた場合、イメージをオフする
      if self.frame.toolbar.GetToolState( 900 ):
        self.frame.toolbar.ToggleTool(900, False)
      else:
        self.pdb.cmd( "q" )

      self.pdb.stop()
      for fnInst in self.editPane.instList:
        fnInst.setDbgMode(False)

      #マウスポインターを通常にする
      wx.SetCursor ( wx.StockCursor ( wx.CURSOR_ARROW ) )
      self.timer.Stop()

      print "stop pdb"
      self.rcvData =""                     #エラー時に、大丈夫かな
      #self.panel.SetBackgroundColour("#AFAFAF")
      self.txt.end()
      self.toolBarEnable(800,3,True)      #ツールバーの無効
      self.toolBarEnable(901,6,False)




  def rcvErr( self, event ):
    ''' pdbからの出力(エラー出力)'''

    data = event.data

    #マウスポインターを通常にする
    wx.SetCursor ( wx.StockCursor ( wx.CURSOR_ARROW ) )
    self.timer.Stop()

    f = open( ERR_FILE, 'a')
    f.write( data )
    f.close()



  def cmdInput( self, cmd ):
    '''self.pdbへのコマンド送出'''



    prgSrc = dbg.prgSrc       #コマンドはソースウインドウから入力されて、フォーカス移動あり
    print "commdin", cmd, "command-out"

    self.pdb.cmd( cmd )
    if cmd =="q":
      self.dbgEnd()
      return

    #元のフォーカスへもどしますよん
    if prgSrc:
      #self.pSrc.SetFocus()
      self.app.chgFocus(0)



  def cmdFunc( self, ch, lineNo ):
    ''' デバッカーのソース画面からの、1文字コマンド '''

    print "cmdFunc",ch
    if ch =="R":
      self.dbgStart()       # debug start -----
      return
    if ch =="q":
      self.pdb.cmd( ch )
      self.dbgEnd()
      return

    # jump command
    if ch=="j":
      ch = "%s %d" %( ch,lineNo )

    # GO command
    if ch=="g":
      ch = "tbreak %d;;c" %( lineNo )

    #ブレークポイント
    s ="%s:%d" %( self.editPane.fileName, lineNo )
    if ch =="b":
      if s in self.bpTbl:
        ch="cl %s" % self.bpTbl[ s ]
        del self.bpTbl[ s ]
      else:
        ch = "b %d" %( lineNo )

    print "cmdFunc", ch,s
    self.pdb.cmd( ch, prgSrc=True )

    xyLast = self.txt.GetLastPosition()
    self.txt.Remove( xyLast-6, xyLast)








  '''
  ----------------------------------------
  ローカル変数の対応
  ----------------------------------------
  '''
  def localVal( self ):
      # ローカル変数の処理


      # --- dbgVal1
      if hanteiSTD.cmd[0:5] == self.dbgVal1[0:5]:

        self.pdb.cmd( self.dbgVal2 )
        self.rcvData =""
        return True

      # --- dbgVal2

      if hanteiSTD.cmd[0:5]== self.dbgVal2[0:5]:

        self.rcvData = self.rcvData.replace("\n(Pdb) ","" )
        self.rcvData = self.rcvData.split("\n")
        #print "1=====>\n",self.rcvData,len(self.rcvData)


        keyList =[]
        for s in self.rcvData :
          #print "ですよ",s,type(s),"[",s[0:2],"]"
          if s != "__return__":
            if s[0:2] == "__" or s[0:17] == "*** RuntimeError:":
              #print "該当しました",s
              continue

          keyList.append( "'%s'" %s )

        if len( keyList )==0:
          #print "該当キーはありませんよ",keyList
          self.rcvData =""
          return True



        keys = self.dbgVal3 + "[%s]" %( ','.join( keyList ) )

        #print 'keys', keys
        self.pdb.cmd( keys )

        self.rcvData =""
        return True


      # --- dbgVal3

      if hanteiSTD.cmd[0:5]== self.dbgVal3[0:5]:

        cmd = self.dbgVal4

        #print 'dbgVal3.cmd', cmd
        self.pdb.cmd( cmd )

        self.rcvData =""
        return True


      # --- dbgVal4

      if hanteiSTD.cmd[0:5]== self.dbgVal4[0:5]:

        self.rcvData = self.rcvData.replace("\n(Pdb) ","" )

        self.rcvData = self.rcvData.split("\n")
        #print "444444=====>\n",self.rcvData,len(self.rcvData)

        localVal={}
        localVal.clear()


        #いらないモジュールや関数は削除する

        for s in self.rcvData:
          if "<type 'function'>" in s or "<type 'module'>" in s:
            continue

          #print "for s==>",s

          item = s.split(",")
          #print "dbg-item", item

          key = str( item[0] )
          ty  = str( item[1] )
          del item[0]
          del item[0]
          s = ",".join( item )
          val = str( s )
          #localVal[ key ] = ty
          localVal[ key ]  = {"val":val, "type":ty }

        #print "--------------------- start ----------"
        #print localVal
        g = gridEx.GridEx.inst
        g.setCell(localVal)
        #print "--------------------- end ----------"

        self.rcvData =""
        return True

      return False




  def errAndNml( self, s ):

    # 正常終了
    if s=="The program finished and will be restarted" \
        or s == "> <string>(1)<module>()->None":
      self.dbgEnd()
      self.frame.SetStatusText( "正常終了" )
      return True

    #致命的なエラー
    if s =='Uncaught exception. Entering post mortem debugging':
        return False

    if s=="Running 'cont' or 'step' will restart the program":
      self.dbgEnd()

      f = open( ERR_FILE, 'r')
      data= f.read()
      f.close()

      #os.remove( ERR_FILE )
      f = open( ERR_FILE, 'w')
      f.write( "" )
      f.close()

      print "致命的なエラーです"
      self.frame.SetStatusText( "致命的なエラーです" )

      f,l,no,errData = getErrInfo( data )
      self.pSrc.goLine( int(l) )

      for i in range( len(errData) ):
        col ="black"
        sss= errData [i]

        if sss[:1] != " ": col ="red"
        if i==no: col ="red"

        self.txt.ColorLine( sss+"\n", col  )
        print "lInfo",sss,col

      self.rcvData =""
      return True

    return False




  def rcv( self, event ):
    '''self.pdbからの受信ですよ'''

    data = event.data
    self.rcvData += data
    chkLen= len( self.rcvData )


    print "*",self.rcvData[-6:-1],"*"

    if self.rcvData[-6:-1] == "(Pdb)":

      #マウスポインターを通常にする
      wx.SetCursor ( wx.StockCursor ( wx.CURSOR_ARROW ) )
      self.timer.Stop()

      #ローカル変数の処理
      st = self.localVal()
      if st:  return

      #print "print",self.rcvData
      self.rcvData = self.rcvData.split("\n")


      for s in self.rcvData:
        print "+", s
        xyLast = self.txt.GetLastPosition()
        self.txt.SetInsertionPoint(xyLast)

        #正常、致命的なエラーの場合
        st = self.errAndNml( s )
        if st:  return

        if s== "(Pdb) ":
          self.txt.AppendColorLine( s+ "" )       # コマンドプロンプトを表示するばあい
          #self.txt.cmdPos = self.txt.GetInsertionPoint()
          #変数表示コマンド(変数の代入)
          if hanteiSTD.cmd == "=":
            # 変数を表示の為に
            self.pdb.cmd( self.dbgVal1 )
          continue

        elif s[:4] == "*** ":
          self.frame.SetStatusText( "エラー:" +s )
          continue

        elif s[:3] == "-> ":
          # デバッカーからの行内容は表示しない "-> "
          continue

        elif s[:2] == "> ":
          self.txt.AppendColorLine( s+ "\n" )
          #self.txt.cmdPos = self.txt.GetInsertionPoint()
        else:
          self.txt.AppendColorLine( s+ "\n" )

        # breakpoint
        #Breakpoint 2 at /home/koba/fx/pdb/1st.py:32

        if hanteiSTD.cmd[:1] == "b":
          item = s.split(" ")
          if item[0] == "Breakpoint":
            self.bpTbl[ item[3] ] = item[1]
          print "break---", self.bpTbl

        stdSW, fnm, lineNo, mnm =  hanteiSTD( s )
        print "hanteiSTD==>",stdSW, fnm, lineNo, mnm

        if stdSW==False:
          if fnm != "":
            # デバックソースでカーソル移動して、変数取得の為にコマンドを送る

            # ここでは、ファイル名がない場合は、notebookにファイルを追加する
            if self.editPane.fileName != fnm:

              #self.pSrc.setDbgMode(False)       # 前のソースは、編集可能
              self.pSrc = self.editPane.setFile( fnm )
              print "************** file chnage ***********************"
              self.pSrc.setDbgMode(True)
              #self.pSrc.setFunc( self.cmdFunc )
              #self.pSrc.SetFocus()


            self.pSrc.goLine( lineNo )
            # 変数を表示の為に
            self.pdb.cmd( self.dbgVal1 )

      self.rcvData =""

    return













def onActive(event):

  id = event.GetId()
  #print "onActive", id

  event.Skip()
  if id ==1000:
    onActive.focusNo=1
    txt.SetFocus()
    return

    txt.SetEditable(True)

    pSrc.StyleSetBackground( wx.stc.STC_STYLE_DEFAULT,"gray")
    pSrc.StyleSetSpec( wx.stc.STC_P_DEFAULT,"back:gray")
    txt.SetBackgroundColour("white")
    #txt.SetForegroundColour( "white" )

  if id ==1001:
    onActive.focusNo=2
    pSrc.SetFocus()
    return

    pSrc.StyleSetBackground( wx.stc.STC_STYLE_DEFAULT,"white")
    pSrc.StyleSetSpec( wx.stc.STC_P_DEFAULT,"back:white")
    txt.SetBackgroundColour("MEDIUM GREY")
    #txt.SetForegroundColour( "GREY" )
    lastPos = txt.GetLastPosition()
    #txt.SetStyle(0 , lastPos, wx.TextAttr("", ""))
    #txt.clear()
    txt.SetEditable(False)
    #txt.SetBackgroundColour((255,23,23))




onActive.focusNo=0
onActive.focusSv=0


debugCmd ={
      901:"n"
      ,902:"s"
      ,903:"r"
      ,905:"b"
      ,906:"c"
      ,2007:"g"
      }


'''-----------------------------------
クラス定義 フレーム
--------------------------------------'''
class FrameExDbg(wx.Frame):
    ''' クラス定義 フレーム '''

    inst=None

    def __init__(self, *args, **kwargs):
        ''' コンストラクター '''

        wx.Frame.__init__(self, title="kobayashi -title",*args, **kwargs)

        #インスタンスを保持する
        FrameExDbg.inst = self

        # setting up toolbar
        self.toolbar = self.CreateToolBar( wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT | wx.TB_TEXT )
        #self.toolbar.AddSimpleTool(801, wx.Bitmap('icons/stock_new.png'), 'New', '')
        self.toolbar.AddSimpleTool(800, wx.Bitmap('Document-Blank-icon.png'), 'New', '')

        self.toolbar.AddSimpleTool(801, wx.Bitmap('open-file-icon.png'), 'Open', '')
        self.toolbar.AddSimpleTool(802, wx.Bitmap('Actions-document-save-icon.png'), 'Save', '')
        self.toolbar.AddSeparator()

        self.toolbar.AddCheckLabelTool(900, "", wx.Bitmap('Halloween-Bug-icon.png') )
        #self.toolbar.AddCheckLabelTool(900, "",wx.Bitmap('Halloween-Bug-icon.png'), 'Ctrl+R  Debug', '')
        self.toolbar.AddSimpleTool(901, wx.Bitmap('Button-Download-icon.png'), 'n next', '')
        self.toolbar.AddSimpleTool(902, wx.Bitmap('Inbox-Into-icon.png'), 's step', '')
        self.toolbar.AddSimpleTool(903, wx.Bitmap('Inbox-Out-icon.png'), 'r return', '')
        self.toolbar.AddSimpleTool(904, wx.Bitmap('Actions-go-jump-icon.png'), 'j jump', '')
        self.toolbar.AddSeparator()

        self.toolbar.AddSimpleTool(905, wx.Bitmap('Actions-process-stop-icon.png'), 'B  breakPoint', '')
        self.toolbar.AddSimpleTool(906, wx.Bitmap('download-icon.png'), 'C  continue', '')
        self.toolbar.Realize()


        # timer
        self.timer = wx.Timer( self )
        self.Bind(wx.EVT_TIMER, self.onTimer)




    def onTimer( self, event):
      '''タイマーです、はじめまして'''

      global txt

      print "timeput"

      #マウスポインターを通常にする
      wx.SetCursor ( wx.StockCursor ( wx.CURSOR_ARROW ) )
      self.timer.Stop()
      txt.SetFocus()



'''-----------------------------------
    パネルクラス
--------------------------------------'''
class PanelEx(wx.Panel):

    inst = None

    def __init__(self, parent,id):

        PanelEx.inst = self
        wx.Panel.__init__(self, parent,id)



"""
---------------------------------------------------
    GUIのメイン
---------------------------------------------------
"""

class MyApp(wx.App):

  inst =None
  def OnInit(self):

    #os.remove( ERR_FILE )         #trace-error-log
    f = open( ERR_FILE, 'w')
    f.write( "" )
    f.close()

    self.frame = FrameExDbg( None,50, pos=(1,1),size=(1000,600))
    self.panel = PanelEx( self.frame, 51)
    self.frame.CreateStatusBar()
    self.panel.SetBackgroundColour("#AFAFAF")

    self.txt = textCmd.TextCmd( self.panel, id=1000, pos=(500,10), size=(400,250) )
    #self.pSrc= textSrc.TextSrc( self.panel, id=1001, pos=(10, 50), size=(400,500))

    dbgClass = dbgC()
    #self.pSrc.setFunc( dbgC.inst.cmdFunc )
    self.txt.setFunc(  dbgC.inst.cmdInput )       # from dbg-text window

    self.panelG = wx.Panel( self.frame, 60, pos=(500,300),size=(400,250))
    self.g = gridEx.GridEx( self.panelG, wx.ID_ANY)

    """
    txt.Bind(wx.EVT_ENTER_WINDOW, onActive)
    pSrc.Bind(wx.EVT_ENTER_WINDOW, onActive)
    """

    self.frame.Bind(wx.EVT_TOOL, self.evtTool)
    self.toolBarEnable(901,6,False)    #最初は、デバックでないから、ツールボタンはみえない



    args = sys.argv
    del args[0]
    if len( args ) ==1:
      fileName = args[0]
    else:
      fileName = "1st.py"
      args.append( fileName)

    textSrc.TextSrc.inst.fileName = fileName
    self.pSrc.LoadFile(fileName)


    self.frame.Show()
    return True






  def fileNew(self):
      fn =""
      textSrc.TextSrc.inst.fileName =fn
      self.frame.SetTitle( '(' + fn + ') wpdb')
      textSrc.TextSrc.inst.ClearAll()

  def fileOpen(self):

      #ファイル選択ダイアログの表示
      dirName = ''
      dialog = wx.FileDialog( self.frame, "Choose a file", dirName, "", "*.*", wx.OPEN)
      #OKボタンが押されるまで表示
      if dialog.ShowModal() == wx.ID_OK:
          fileName = dialog.GetFilename()
          dirName = dialog.GetDirectory()
          #file = open(os.path.join( dirName, fileName), 'r')
          #ファイルデータ読み込み
          #file.close()

          fn = textSrc.TextSrc.inst.fileName = os.path.join( dirName, fileName)
          textSrc.TextSrc.inst.LoadFile( fn )

          print "fileOpen-new-ver", fn
          self.frame.SetTitle( '(' + fn + ') wpdb')
      #ダイアログの破棄
      dialog.Destroy()



  def fileSave( self ):
        wildcard = "Python source (*.py)|*.py|" \
              "All files (*.*)|*.*"
        fn = textSrc.TextSrc.inst.fileName.strip()
        if fn == "":
          """
          Create and show the Save FileDialog
          """
          dlg = wx.FileDialog(
              self.frame, message="Save file as ...",
              defaultDir= os.getcwd(),
              defaultFile="", wildcard=wildcard, style=wx.SAVE
              )
          if dlg.ShowModal() == wx.ID_OK:
              fn = dlg.GetPath()
              print "You chose the following filename: %s" % fn

              textSrc.TextSrc.inst.fileName = fn
              self.frame.SetTitle( '(' + fn + ') wpdb')

          dlg.Destroy()

        self.pSrc.SaveFile( fn )
        self.pSrc.SetFocus()
        self.pSrc.GotoLine( 0 )



  def toolBarEnable( self, st,n, flg):
    for i in range( n ):
      FrameEx.inst.toolbar.EnableTool( st+i, flg)






  def evtTool( self, e ):

      global th,frame,dbgMode

      id = e.GetId()
      print "onTool", id

      if id == 800:
        self.fileNew()

      elif id == 801:
        self.fileOpen()

      elif id == 802:
        self.fileSave()

      elif id == 900:
        dbgMode = FrameEx.inst.toolbar.GetToolState( id )
        if dbgMode:
          # file save and Debug start
          self.fileSave()
          dbgC.inst.dbgStart()
          self.toolBarEnable(901,6,True)

        else:
          dbgC.inst.dbgEnd()
          self.toolBarEnable(901,6,False)
      else:
        dbgC.inst.pdb.cmd( debugCmd[id]  )












if __name__ == "__main__":

  app =MyApp()
  app.MainLoop()

2017年2月14日火曜日

小春日和ですな〜

本日の成果です。


以下がソースです。

#!/usr/bin/python
# -*- coding: utf-8 -*-


# Editor
import wx
import wx.lib.agw.flatnotebook as fnb
import wx.stc as stc
import sys,os
import textCmd
import textSrc



class EditPane(wx.Panel):

    def __init__( self, parent, id, pos, size):
        """ 画面右、タブごとに編集ページを表示する """

        wx.Panel.__init__( self, parent, id, pos, size )

        self.curTabNo = 0
        self.fileName = ""
        self.fileList =[]
        self.instList =[]
        self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CHANGED, self.OnPageChanged)
        self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING, self.OnPageClosing)


        self.book = fnb.FlatNotebook(self, 100,
                                  agwStyle=fnb.FNB_X_ON_TAB |
                                  fnb.FNB_NO_NAV_BUTTONS |
                                  fnb.FNB_NO_X_BUTTON )




        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add( self.book, proportion=1, flag=wx.GROW| wx.ALL,  border=10 )
        self.SetSizer(layout)

    def OnPageChanged(self, event):
        ''' get for current tabno '''

        self.curTabNo = event.GetSelection()
        self.fileName = self.fileList[ self.curTabNo ]

        print "Page Changed start ----"
        print "*:curTabNo",self.curTabNo
        print "fileName",self.fileName
        print "fileList",self.fileList
        #print "instList",self.instList
        print("Page Changed To %d" % event.GetSelection())
        event.Skip()


    def OnPageClosing(self, event):
        '''
            delete tab
            proc1. remove array of fileList, instList
        '''
        tabNo = event.GetSelection()
        del self.instList[ tabNo ]
        del self.fileList[ tabNo ]

        self.cutTabNo = event.GetSelection()
        if self.cutTabNo == 0:  self.fileName = ""
        #else:                   self.fileName = self.fileList[ self.cutTabNo ]

        print "close start ------"
        print "*:curTabNo",self.curTabNo
        print "fileName",self.fileName
        print "fileList",self.fileList
        #print "instList",self.instList
        print("Page Closing, Selection: %d" % event.GetSelection())
        print "close end"
        event.Skip()


    def addPage( self, dirName, fileName ):
        """ ページを追加する、ファイル内容をリードして表示タブを作成しています"""

        notePane = wx.Panel( self, wx.ID_ANY)
        notePane.SetBackgroundColour( "black" )

        #text = stc.StyledTextCtrl(notePane, wx.ID_ANY)
        text = textSrc.TextSrc(notePane, wx.ID_ANY)
        text.LoadFile( self.fileName )
        self.fileList.append( self.fileName )
        self.instList.append( text )



        layout = wx.BoxSizer(wx.VERTICAL)
        layout.Add( text, proportion=1, flag=wx.GROW  | wx.ALL,  border=10 )
        notePane.SetSizer( layout )

        self.book.AddPage( notePane, fileName )
        self.curTabNo = len( self.fileList )-1
        self.book.SetSelection( self.curTabNo )

        print "addPage  start ------"
        print "*:curTabNo",self.curTabNo
        print "addPage:fileName",self.fileName
        print "addPage:fileList",self.fileList
        #print "addPage:instList",self.instList

        return


    def OnOpenFile( self ):

        dirName = ''
        dialog = wx.FileDialog( self, "Choose a file", dirName, "", "*.*", wx.OPEN)

        if dialog.ShowModal() == wx.ID_OK:
            fileName = dialog.GetFilename()
            dirName = dialog.GetDirectory()

            self.fileName = os.path.join( dirName, fileName)
            self.addPage( dirName, fileName )
        return


    def OnSaveFile( self ):
        self.SetTitle( '(' + self.fileName + ') wpdb')
        print "*:curTabNo",self.curTabNo
        print "*:fileName",self.fileName
        print "*:fileList",self.fileList
        print "*:instList",self.instList
        return





class Main(wx.Frame):

    def __init__(self, parent, id, title):
        """ レイアウトの作成 """

        wx.Frame.__init__(self, parent, id, title, size=(800, 600))



        # メインのレイアウトの作成
        panel = wx.Panel( self, wx.ID_ANY )

        #right= Right(panel, wx.ID_ANY)
        self.right = right = EditPane( panel, wx.ID_ANY,pos=(0,0), size=(500,800) )
        left = wx.Panel( panel, wx.ID_ANY,pos=(350,350), size=(500,100) )
        right.SetBackgroundColour(wx.GREEN)
        left.SetBackgroundColour(wx.RED)

        # メニューの作成
        self.CreateStatusBar()
        menu_file = wx.Menu()
        save_item = menu_file.Append(0, u"開く")
        save_item = menu_file.Append(1, u"保存")
        exit_item = menu_file.Append(2, u"終了")

        menu_edit = wx.Menu()
        copy_item  = menu_edit.Append(3, u"コピー")
        paste_item = menu_edit.Append(4, u"貼り付け")

        menu_bar = wx.MenuBar()
        menu_bar.Append(menu_file, u"ファイル")
        menu_bar.Append(menu_edit, u"編集")

        self.Bind(wx.EVT_MENU, self.selectMenu)

        self.SetMenuBar(menu_bar)


    def selectMenu( self,event):
        self.SetStatusText("MenuSelected! " + str(event.GetId()))
        id = event.GetId()
        if id==0: self.right.OnOpenFile()
        if id==1: self.right.OnSaveFile()




if __name__ == "__main__":
    app = wx.App()
    f = Main(None, wx.ID_ANY )
    f.Centre()
    f.Show(True)
    app.MainLoop()