1. Opinions how to make it look better ?
2. How to make path for Linux ? using user ?
3. For Linux .
What the difference between ( #! = user/bin/python , #! = user/bin/env python) ?
4. Anything i forgot or should consider ?
# ----- ----- ----- ----- ----- --*-- ----- ----- ----- ----- ----- #
# Drake's Database
# Version 0.1
# Simple Python Database
# Copyright (C) July/2009 , DrakeMagi
# License: GPL version 3
# currently under development
# ----- ----- ----- ----- ----- --*-- ----- ----- ----- ----- ----- #
import wx , anydbm , os , sys
HelpTxt = """ Right click on background to create fields.
Hold left mouse down on fields background to move them around.
Right click on fields background to get popup menu.
Search: do New Search. Record Number will be 0 .Fill in Fields.
Search is case sensitive."""
IdNew = wx.NewId()
IdClose = wx.NewId()
IdOpen = wx.NewId()
IdExit = wx.NewId()
IdEdit = wx.NewId()
IdT10 = wx.NewId()
IdT12 = wx.NewId()
IdT14 = wx.NewId()
IdF10 = wx.NewId()
IdF12 = wx.NewId()
IdF14 = wx.NewId()
IdNrec = wx.NewId()
IdNxrec = wx.NewId()
IdPrec = wx.NewId()
IdSrec = wx.NewId()
IdNSrec = wx.NewId()
IdSnxrec = wx.NewId()
IdSpvrec = wx.NewId()
IdRename = wx.NewId()
IdOptions = wx.NewId()
IdDelete = wx.NewId()
IdSize = wx.NewId()
class MainFrame(wx.Frame):
def __init__(self,parent,Id,title,siz):
wx.Frame.__init__(self,parent,Id,title,size = siz)
self.Sz = siz
self.Pane = None
self.Pane1 = None
# ----- ----- ----- Menu ----- ----- ----- #
File = wx.Menu()
Options = wx.Menu()
TextSize = wx.Menu()
FieldSize = wx.Menu()
TextSize.Append(IdT10,'10')
TextSize.Append(IdT12,'12')
TextSize.Append(IdT14,'14')
FieldSize.Append(IdF10,'10')
FieldSize.Append(IdF12,'12')
FieldSize.Append(IdF14,'14')
File.Append(IdNew,'New')
File.Append(IdOpen,'Open')
File.Append(IdClose,'Close')
File.Append(IdExit,'Exit')
Options.AppendSubMenu(TextSize,'TextBox Size')
Options.AppendSubMenu(FieldSize,'FieldName Size')
MenuBar = wx.MenuBar()
MenuBar.Append(File,'File')
MenuBar.Append(Options,'Options')
self.SetMenuBar(MenuBar)
wx.EVT_MENU(self,IdNew,self.Mnew)
wx.EVT_MENU(self,IdClose,self.Mclose)
wx.EVT_MENU(self,IdOpen,self.Mopen)
wx.EVT_MENU(self,IdExit,self.Mexit)
wx.EVT_MENU(self,IdT10,self.MT10)
wx.EVT_MENU(self,IdT12,self.MT12)
wx.EVT_MENU(self,IdT14,self.MT14)
wx.EVT_MENU(self,IdF10,self.MF10)
wx.EVT_MENU(self,IdF12,self.MF12)
wx.EVT_MENU(self,IdF14,self.MF14)
def MT10(self,evt):
self.Change(10,0)
def MT12(self,evt):
self.Change(12,0)
def MT14(self,evt):
self.Change(14,0)
def MF10(self,evt):
self.Change(10,1)
def MF12(self,evt):
self.Change(12,1)
def MF14(self,evt):
self.Change(14,1)
def Change(self,Size,Code):
global T_Font , F_Font
if Code == 0:
T_Font = wx.Font(Size,wx.DEFAULT,wx.NORMAL,wx.NORMAL)
elif Code == 1:
F_Font = wx.Font(Size,wx.DEFAULT,wx.NORMAL,wx.NORMAL)
if not self.Pane == None:
if len(self.Pane.Fields) > 0:
if not self.Pane.Fields[0] == '':
for n in self.Pane.Fields:
n[1].lab.SetFont(F_Font)
w,h = n[1].lab.GetTextExtent(n[1].Name)
n[1].lab.SetPosition((5,17 - h/2))
x,y = n[1].lab.GetSizeTuple()
width = n[1].Size[0] - x - 25
n[1].txt.SetPosition((x+10,5))
n[1].txt.SetSize((width,25))
n[1].txt.SetFont(T_Font)
def Mnew(self,evt):
dlg = Field(self,-1,'FileName',(150,110),0,2)
val = dlg.ShowModal()
if not FileName == '' and not FileName == '.dat':
self.Panels()
def Mclose(self,evt):
global DataBase
if self.Pane != None:
self.Pane1.Destroy()
self.Pane.Destroy()
self.Pane = None
def Mopen(self,evt):
global FileName
dlg = wx.FileDialog(self,'Open DataBase',SavePath,'.dat',
style = wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
Check = True
FileName = dlg.GetFilename()
if not '.dat' in FileName:
Check = False
if len(FileName) < 5:
Check = False
if Check == True:
LoadDataBase(FileName)
self.Panels()
Data = DataBase[DrakeData[2]].split('>>')[:-1]
Posx = DataBase[DrakeData[0]].split('>>')[:-1]
Posy = DataBase[DrakeData[1]].split('>>')[:-1]
sx = DataBase[DrakeData[5]].split('>>')[:-1]
sy = DataBase[DrakeData[6]].split('>>')[:-1]
loop = 0
Go = True
if len(Data) == 1:
if Data[0] == '':
Go = False
if len(Data) > 0 and Go == True:
for n in Data:
self.Pane.Fields.append([n])
Pos = int(Posx[loop]),int(Posy[loop])
Sz = int(sx[loop]),int(sy[loop])
self.Pane.NewField(n,Pos,loop,True,Sz)
loop += 1
self.Pane.LoadRec()
def Mexit(self,evt):
self.Destroy()
def Panels(self):
if not self.Pane == None:
self.Pane.Destroy()
self.Pane1.Destroy()
self.Pane1 = TopPanel(self,-1)
self.Pane = DataPanel(self,-1)
vbox = wx.BoxSizer(wx.VERTICAL) # wx.HORIZONTAL , wx.VERTICAL
vbox.Add(self.Pane1,0,wx.EXPAND)
vbox.Add(self.Pane,5,wx.EXPAND)
self.SetSizer(vbox)
# ----- Just to make it show ----- #
x , y = self.GetSize()
self.SetSize((x,y + 1))
self.SetSize((x,y))
# ----- ----- ----- --*-- ----- ----- ----- #
# TopPanel
# ----- ----- ----- --*-- ----- ----- ----- #
class TopPanel(wx.Panel):
def __init__(self,parent,Id):
wx.Panel.__init__(self,parent,Id)
self.NewRecord = wx.Button(self,IdNrec,'New Record',(120,5),(100,20))
self.PrevRecord = wx.Button(self,IdPrec,'<<',(240,5),(40,20))
self.NextRecord = wx.Button(self,IdNxrec,'>>',(290,5),(40,20))
self.NewSearchRecord = wx.Button(self,IdNSrec,'New Search',(120,35),(100,20))
self.PrevSearchRecord = wx.Button(self,IdSpvrec,'<<',(240,35),(40,20))
self.NextSearchRecord = wx.Button(self,IdSnxrec,'>>',(290,35),(40,20))
self.SearchLabel = wx.StaticText(self,-1,'0 of 0',pos = (5,35))
self.SearchRecord = None
self.SearchList = []
self.SearchPos = -1
wx.EVT_BUTTON(self,IdNrec,self.NewRecd)
wx.EVT_BUTTON(self,IdPrec,self.PrevRec)
wx.EVT_BUTTON(self,IdNxrec,self.NextRec)
wx.EVT_BUTTON(self,IdNSrec,self.NewSearchRec)
wx.EVT_BUTTON(self,IdSrec,self.SearchRec)
wx.EVT_BUTTON(self,IdSpvrec,self.SearchRecPv)
wx.EVT_BUTTON(self,IdSnxrec,self.SearchRecNx)
def NewRecd(self,evt):
global DataBase
for n in frame.Pane.Fields:
DataBase[n[0]+str(frame.Pane.Rec_on)] = str(n[1].txt.GetValue())
n[1].txt.SetValue('')
frame.Pane.Rec_Max += 1
frame.Pane.Rec_on = frame.Pane.Rec_Max
DataBase[DrakeData[4]] = str(frame.Pane.Rec_Max)
self.RecordUpdate()
def PrevRec(self,evt):
self.GotoRec(frame.Pane.Rec_on,frame.Pane.Rec_on - 1)
def NextRec(self,evt):
self.GotoRec(frame.Pane.Rec_on,frame.Pane.Rec_on + 1)
def GotoRec(self,old,cur):
global DataBase
frame.Pane.Rec_on = cur
if cur < 1:
frame.Pane.Rec_on = cur = frame.Pane.Rec_Max
elif cur > frame.Pane.Rec_Max:
frame.Pane.Rec_on = cur = 1
for n in frame.Pane.Fields:
DataBase[n[0]+str(old)] = str(n[1].txt.GetValue())
try:
Data = DataBase[n[0]+str(cur)]
except:
Data = ''
n[1].txt.SetValue(Data)
self.RecordUpdate()
def RecordUpdate(self,start = None,Load = False):
if not self.SearchRecord == None:
self.SearchRecord.Destroy()
self.SearchRecord = None
if start == None:
txt = str(frame.Pane.Rec_on) + ' of ' + str(frame.Pane.Rec_Max)
else:
txt = str(start[0]) + ' of ' + str(start[1])
try:
self.Record.Destroy()
except: pass
try:
self.SearchLabel.Destroy()
except: pass
self.Record = wx.StaticText(self,-1,txt,pos = (5,5))
if len(self.SearchList) > 0:
stxt = str(self.SearchPos+1) + ' of ' + str(len(self.SearchList))
self.SearchLabel = wx.StaticText(self,-1,stxt,pos = (5,35))
if Load == False:
if len(frame.Pane.Fields) > 0:
if not frame.Pane.Fields[0] == '':
LoadDataBase(FileName)
def NewSearchRec(self,evt):
global DataBase
self.SearchPos = -1
for n in frame.Pane.Fields:
DataBase[n[0]+str(frame.Pane.Rec_on)] = str(n[1].txt.GetValue())
n[1].txt.SetValue('')
frame.Pane.Rec_on = 0
self.RecordUpdate()
self.SearchRecord = wx.Button(self,IdSrec,'Search',(350,35),(100,20))
def SearchRecPv(self,evt):
if len(self.SearchList) > 0:
self.SearchPos -= 1
if self.SearchPos < 0:
self.SearchPos = len(self.SearchList)-1
self.GotoRec(frame.Pane.Rec_on,self.SearchList[self.SearchPos])
def SearchRecNx(self,evt):
if len(self.SearchList) > 0:
self.SearchPos += 1
if self.SearchPos > len(self.SearchList)-1:
self.SearchPos = 0
self.GotoRec(frame.Pane.Rec_on,self.SearchList[self.SearchPos])
def SearchRec(self,evt):
global DataBase
self.SearchList = []
SearchWords = []
MaxWords = 0
for n in frame.Pane.Fields:
DataBase[n[0]+str(frame.Pane.Rec_on)] = str(n[1].txt.GetValue())
SearchWords.append(str(n[1].txt.GetValue()))
if str(n[1].txt.GetValue()) > "": MaxWords += 1
if MaxWords > 0:
for num in xrange(1,frame.Pane.Rec_Max+1):
Count = 0
loop = 0
for n in DataBase[DrakeData[2]].split('>>')[:-1]:
if SearchWords[loop] > "":
if self.FindWord(SearchWords[loop],DataBase[n + str(num)]) == True:
Count += 1
loop += 1
if Count == MaxWords:
self.SearchList.append(num)
self.RecordUpdate()
self.SearchRecord = wx.Button(self,IdSrec,'Search',(350,35),(100,20))
def FindWord(self,Key,Word):
K = Key.split()
MaxCount = len(K)
Count = 0
for n in K:
if n in Word:
Count += 1
if Count == MaxCount:
return True
return False
# ----- ----- ----- --*-- ----- ----- ----- #
# DataPanel
# ----- ----- ----- --*-- ----- ----- ----- #
class DataPanel(wx.Panel):
def __init__(self,parent,Id):
wx.Panel.__init__(self,parent,Id)
self.Fields = []
try:
self.Rec_Max = int(DataBase[DrakeData[4]])
if self.Rec_Max == 0:
self.Rec_Max = 1
except:
self.Rec_Max = 1
self.Rec_on = 1
frame.Pane1.RecordUpdate((self.Rec_on,self.Rec_Max),True)
wx.EVT_RIGHT_DOWN(self,self.MouseR)
def LoadRec(self):
try:
for n in self.Fields:
try:
Data = DataBase[n[0]+str(self.Rec_on)]
n[1].txt.SetValue(Data)
except:
pass
except:
pass
def MouseR(self,evt):
evt.Skip()
ps = evt.GetPositionTuple()
dlg = Field(self,-1,'Enter Field Name',(150,110),ps)
val = dlg.ShowModal()
def NewField(self,Name,PPos,it,Load,Sz):
Csz = self.GetClientSize()
self.Fields[it].append(createfield(self,-1,Name,PPos,Load,Sz,Csz))
# ----- ----- ----- --*-- ----- ----- ----- #
# Create Fields
# ----- ----- ----- --*-- ----- ----- ----- #
# some reason i couldn't get sizer to work in this area.
class createfield(wx.Panel):
def __init__(self,parent,Id,Name,PPos,Load,Sz,Csz):
global DataBase
wx.Panel.__init__(self,parent,Id,PPos,Sz)
self.Size = Sz
self.Csize = Csz
PPos = Snap(PPos,self.Csize)
# ----- ----- ----- PopupMenu ----- ----- ----- #
self.PopMenu = wx.Menu()
self.PopMenu.Append(IdRename,'Rename')
self.PopMenu.Append(IdSize,'Size')
self.PopMenu.Append(IdDelete,'Delete')
self.SetBackgroundColour((200,220,250))
self.Movex = None
self.Name = Name
self.lab = wx.StaticText(self,-1,Name,pos=(5,4))
self.lab.SetFont(F_Font)
w,h = self.lab.GetTextExtent(self.Name)
self.lab.SetPosition((5,17 - h/2))
x,y = self.lab.GetSizeTuple()
width = self.Size[0] - x - 25
self.txt = wx.TextCtrl(self,-1,pos=(x+10,5),size=(width,25))
self.txt.SetFont(T_Font)
wx.EVT_RIGHT_DOWN(self,self.MouseRdown)
wx.EVT_LEFT_DOWN(self,self.MouseLdown)
wx.EVT_LEFT_UP(self,self.MouseLup)
wx.EVT_MOTION(self,self.MouseMot)
wx.EVT_MENU(self,IdRename,self.Rname)
wx.EVT_MENU(self,IdDelete,self.Delete)
wx.EVT_MENU(self,IdSize,self.ReSize)
if Load == False:
DataBase[DrakeData[2]] += Name + '>>'
DataBase[DrakeData[0]] += str(PPos[0]) + '>>'
DataBase[DrakeData[1]] += str(PPos[1]) + '>>'
DataBase[DrakeData[5]] += str(self.Size[0]) + '>>'
DataBase[DrakeData[6]] += str(self.Size[1]) + '>>'
def ReSize(self,evt):
loop = 0
for n in frame.Pane.Fields:
if n[0] == self.Name:
it = loop
loop += 1
dlg = Field(self,-1,'Field Size',(150,110),it,3,self.Size[0])
val = dlg.ShowModal()
def ReSizeit(self,x,it):
if x < 70:
x = 70
self.Size = (x,35)
self.SetSize(self.Size)
x,y = self.lab.GetSizeTuple()
width = self.Size[0] - x - 25
self.txt.SetPosition((x+10,5))
self.txt.SetSize((width,25))
NewData = DataBase[DrakeData[5]].split('>>')[:-1]
NewData[it] = str(self.Size[0])
DataBase[DrakeData[5]] = '>>'.join(NewData) + '>>'
NewData = DataBase[DrakeData[6]].split('>>')[:-1]
NewData[it] = str(self.Size[1])
DataBase[DrakeData[6]] = '>>'.join(NewData) + '>>'
def MouseRdown(self,evt):
self.PopupMenu(self.PopMenu,evt.GetPosition())
# ----- ----- ----- Mouse Grab and Drag ----- ----- ----- #
def MouseLdown(self,evt):
self.CaptureMouse()
x,y = self.ClientToScreen(evt.GetPosition())
orgx,orgy = self.GetPosition()
self.Movex = (x - orgx,y - orgy)
def MouseLup(self,evt):
global DataBase
if self.HasCapture():
self.ReleaseMouse()
self.Movex = None
self.Move(Snap(self.GetPosition(),self.Csize))
x , y = self.GetPosition()
Data = DataBase[DrakeData[2]].split('>>')[:-1]
Item = Data.index(self.Name)
NewData = DataBase[DrakeData[0]].split('>>')[:-1]
NewData1 = DataBase[DrakeData[1]].split('>>')[:-1]
NewData[Item] = str(x)
NewData1[Item] = str(y)
DataBase[DrakeData[0]] = '>>'.join(NewData) + '>>'
DataBase[DrakeData[1]] = '>>'.join(NewData1) + '>>'
def MouseMot(self,evt):
if self.Movex != None:
if evt.Dragging() and evt.LeftIsDown():
x,y = self.ClientToScreen(evt.GetPosition())
move_xy = x - self.Movex[0] , y - self.Movex[1]
self.Move(move_xy)
# ^^--- ----- ---^^ Mouse Grab and Drag ^^--- ----- ---^^ #
def Rname(self,evt):
loop = 0
for n in frame.Pane.Fields:
if n[0] == self.Name:
it = loop
loop += 1
dlg = Field(self,-1,'Rename Field',(150,110),it,1)
val = dlg.ShowModal()
def Renameit(self,word,item):
global DataBase
for n in xrange(1,frame.Pane.Rec_Max + 1):
Junk = str(self.Name)+str(n)
NewJunk = str(word)+str(n)
try:
DataBase[NewJunk] = DataBase[Junk]
del DataBase[Junk]
except:
pass
NewData = DataBase[DrakeData[2]].split('>>')[:-1]
NewData[item] = str(word)
DataBase[DrakeData[2]] = '>>'.join(NewData) + '>>'
frame.Pane.Fields[item][0] = str(word)
self.lab.SetLabel(word)
x,y = self.lab.GetSizeTuple()
width = self.Size[0] - x - 25
self.txt.SetPosition((x+10,5))
self.txt.SetSize((width,25))
self.Name = str(word)
def Delete(self,evt):
global DataBase
loop = 0
for n in frame.Pane.Fields:
if n[0] == self.Name:
it = loop
loop += 1
self.DelItem(2,it)
self.DelItem(1,it)
self.DelItem(0,it)
self.DelItem(5,it)
self.DelItem(6,it)
for n in xrange(1,frame.Pane.Rec_Max + 1):
Junk = str(self.Name)+str(n)
try:
del DataBase[Junk]
except:
pass
self.Destroy()
del frame.Pane.Fields[it]
def DelItem(self,num,it):
global DataBase
NewData = DataBase[DrakeData[num]].split('>>')[:-1]
del NewData[it]
if len(NewData) > 0:
DataBase[DrakeData[num]] = '>>'.join(NewData) + '>>'
else:
DataBase[DrakeData[num]] = ''
# ----- ----- ----- --*-- ----- ----- ----- #
# ask for Field name
# ----- ----- ----- --*-- ----- ----- ----- #
class Field(wx.Dialog):
def __init__(self,parent,Id,title,Sz,Mpos,code = 0,var = 0):
wx.Dialog.__init__(self,parent,Id,title,size = Sz)
self.Mpos = Mpos
vbox = wx.BoxSizer(wx.VERTICAL) # wx.HORIZONTAL , wx.VERTICAL
InName = 'Field Name'
if code == 2:
InName = 'File Name'
elif code == 3:
InName = 'Field Width'
self.lab = wx.StaticText(self,-1,InName)
if code == 3:
self.txt = wx.TextCtrl(self,-1,str(var))
else:
self.txt = wx.TextCtrl(self,-1)
IdTemp = wx.NewId()
self.ok = wx.Button(self,IdTemp,'OK')
vbox.Add((-1,5))
vbox.Add(self.lab,0,wx.CENTER |wx.LEFT |wx.RIGHT,10)
vbox.Add((-1,5))
vbox.Add(self.txt,1,wx.CENTER |wx.LEFT |wx.RIGHT, 10)
vbox.Add((-1,5))
vbox.Add(self.ok,0,wx.CENTER|wx.LEFT |wx.RIGHT,10)
vbox.Add((-1,5))
self.SetSizer(vbox)
if code == 0:
wx.EVT_BUTTON(self,IdTemp,self.PushOk)
elif code == 1:
wx.EVT_BUTTON(self,IdTemp,self.PushOk2)
elif code == 2:
wx.EVT_BUTTON(self,IdTemp,self.PushOk3)
elif code == 3:
wx.EVT_BUTTON(self,IdTemp,self.PushOk4)
# ----- ----- ----- New Field ----- ----- ----- #
def PushOk(self,evt):
global DataBase
word = str(self.txt.GetValue())
if not '>' in word:
if not word in DataBase[DrakeData[2]]:
if word > '':
frame.Pane.Fields.append([word])
x = len(frame.Pane.Fields) -1
frame.Pane.NewField(word,self.Mpos,x,False,(200,35))
self.Destroy()
# ----- ----- ----- Rename Field ----- ----- ----- #
def PushOk2(self,evt):
global DataBase
word = str(self.txt.GetValue())
if not '>' in word:
if not word in DataBase[DrakeData[2]]:
frame.Pane.Fields[self.Mpos][1].Renameit(word,self.Mpos)
self.Destroy()
# ----- ----- ----- New DataBase----- ----- ----- #
def PushOk3(self,evt):
global FileName
word = str(self.txt.GetValue())
FileName = word + '.dat'
LoadDataBase(word + '.dat')
self.Destroy()
# ----- ----- ----- Resize Field ----- ----- ----- #
def PushOk4(self,evt):
try:
num = int(self.txt.GetValue())
except:
num = var
frame.Pane.Fields[self.Mpos][1].ReSizeit(num,self.Mpos)
self.Destroy()
# ----- ----- ----- --*-- ----- ----- ----- #
# Snap to Grid
# ----- ----- ----- --*-- ----- ----- ----- #
def Snap(Pos,lth):
x = int(round(Pos[0] *0.1)) * 10
y = int(round(Pos[1] *0.1)) * 10
if x < 0: x = 0
if x > lth[0]-20: x = lth[0]-40
if y < 0: y = 0
if y > lth[1]-15: y = lth[1]-25
return (x,y)
# ----- ----- ----- --*-- ----- ----- ----- #
# Load Database
# ----- ----- ----- --*-- ----- ----- ----- #
def LoadDataBase(File):
global DataBase
try:
DataBase.close()
except:
pass
DataBase = anydbm.open(os.path.join(SavePath,File),'c')
try:
temp = DataBase[DrakeData[0]]
except:
for n in DrakeData:
DataBase[n] = ''
# ----- ----- ----- --*-- ----- ----- ----- #
# Start
# ----- ----- ----- --*-- ----- ----- ----- #
if __name__ == '__main__':
FileName = ''
CurrentPath = os.getcwd()
try:
# ----- ----- ----- Create Path ----- ----- ----- #
os.mkdir(os.path.join(CurrentPath,'Save'))
except:
pass
sys.path.append(os.path.join(CurrentPath,'Save'))
SavePath = os.path.join(CurrentPath,'Save')
DataBase = ''
DrakeData = ['D__Drake_X__','D__Drake_Y__','D__Drake_Fields_List__',
'D__Drake_Option__','D__Drake_Rec_Max__','D__Drake_Size_X__',
'D__Drake_Size_Y__']
app = wx.App()
T_Font = wx.Font(12,wx.DEFAULT,wx.NORMAL,wx.NORMAL)
F_Font = wx.Font(12,wx.DEFAULT,wx.NORMAL,wx.NORMAL)
frame = MainFrame(None,-1,'Drake\'s Database',(600,600))
frame.Center()
frame.Show(1)
app.MainLoop()
try:
DataBase.close()
except:
pass