ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/ns_dev/Python/NinoCode/Active_prgs/Gromulus/Gromulus_UI.py
Revision: 910
Committed: Sun Jun 8 03:14:57 2025 UTC (9 months, 2 weeks ago) by nino.borges
Content type: text/x-python
File size: 13121 byte(s)
Log Message:
More changes to the MyApp class to fix the issue I'm having with db.close.

File Contents

# Content
1 """
2 Created by Emanuel Borges
3 05.19.2023
4
5 This is the main UI for Gromulus, which is a catalog inventory for roms, games and maybe one day applications.
6 Like most of my GUI programs, this will import a separate library with my methods for doing the actual work.
7
8 """
9
10
11 import sys, os, wx
12 #import wx.lib.buttons as buttons
13 import Gromulus_Lib
14
15
16
17 class MyFrame(wx.Frame):
18 def __init__(self, parent, ID, title, pos=wx.DefaultPosition):
19 wx.Frame.__init__(self, parent, ID, title, pos, size = (1450,525))
20 self.db = Gromulus_Lib.DatabaseManager()
21 self.dbConnection = self.dbConnection.get_connection()
22 self.panel = wx.Panel(self,-1)
23 self.gamesListMatrix = Gromulus_Lib.GetGameListBySystem('snes', self.dbConnection)
24 gamesList = list(self.gamesListMatrix.keys())
25 gamesList.sort()
26 self.gamesCount = len(gamesList)
27 unmatchedGamesList=[i for i in gamesList if "." in i]
28 self.unmatchedGamesCount = len(unmatchedGamesList)
29 print(f"{self.gamesCount} total games for this system. {self.gamesCount - self.unmatchedGamesCount} matched and {self.unmatchedGamesCount} unmatched.")
30
31 self.CreateSystemButtonSection()
32 self.gameSelectionListBox = wx.ListBox(self.panel, 60, (100, 50), (490, 320), gamesList , wx.LB_SINGLE|wx.LB_OWNERDRAW)
33 self.CreateFieldsFirstRow()
34
35
36
37 mainSizer = wx.BoxSizer(wx.HORIZONTAL)
38 mainSizer.Add(self.buttonSizer, 0, wx.ALIGN_TOP|wx.LEFT|wx.TOP,25)
39 mainSizer.Add(self.gameSelectionListBox, 0, wx.ALIGN_TOP|wx.LEFT|wx.TOP,25)
40 mainSizer.Add(self.fieldsFirstRowSizer, 0, wx.ALIGN_TOP|wx.LEFT|wx.TOP,25)
41 self.panel.SetSizer(mainSizer)
42
43
44 self.CreateStatusBar()
45 self.SetStatusText("Ready.")
46 self.CreateMenuBar()
47
48 self.Bind(wx. EVT_TOGGLEBUTTON, self.OnSystemSelected, self.snesSystemButton)
49 self.Bind(wx. EVT_TOGGLEBUTTON, self.OnSystemSelected, self.nesSystemButton)
50 self.Bind(wx. EVT_TOGGLEBUTTON, self.OnSystemSelected, self.genesisSystemButton)
51 self.Bind(wx. EVT_TOGGLEBUTTON, self.OnSystemSelected, self.fz1SystemButton)
52 self.Bind(wx. EVT_TOGGLEBUTTON, self.OnSystemSelected, self.ps1SystemButton)
53
54 self.Bind(wx.EVT_LISTBOX, self.OnGameSelected, self.gameSelectionListBox)
55
56
57 def CreateSystemButtonSection(self):
58 #systemsList = ['SNES','NES','Genisys']
59 #for system in systemsList:
60 #self.snesSystemButton = buttons.GenToggleButton(self.panel, -1, "SNES")
61 #self.nesSystemButton = buttons.GenToggleButton(self.panel, -1, "NES")
62 #self.genesisSystemButton = buttons.GenToggleButton(self.panel, -1, "Genesis")
63 #self.ps1SystemButton = buttons.GenToggleButton(self.panel, -1, "Playstation")
64
65 ## Create a dictionary that holds the button instances by label text, so that you can toggle the other ones off in the bind event.
66 self.systemButtonDict = {}
67 self.snesSystemButton = wx.ToggleButton(self.panel, -1, "SNES")
68 self.systemButtonDict[self.snesSystemButton.GetLabelText()] = self.snesSystemButton
69
70 self.nesSystemButton = wx.ToggleButton(self.panel, -1, "NES")
71 self.systemButtonDict[self.nesSystemButton.GetLabelText()] = self.nesSystemButton
72
73 self.genesisSystemButton = wx.ToggleButton(self.panel, -1, "Genesis")
74 self.systemButtonDict[self.genesisSystemButton.GetLabelText()] = self.genesisSystemButton
75
76 self.fz1SystemButton = wx.ToggleButton(self.panel, -1, "3DO")
77 self.systemButtonDict[self.fz1SystemButton.GetLabelText()] = self.fz1SystemButton
78
79 self.ps1SystemButton = wx.ToggleButton(self.panel, -1, "Playstation")
80 self.systemButtonDict[self.ps1SystemButton.GetLabelText()] = self.ps1SystemButton
81
82
83 self.buttonSizer = wx.BoxSizer(wx.VERTICAL)
84 self.buttonSizer.Add(self.snesSystemButton, 0, wx.ALL,10)
85 self.buttonSizer.Add(self.nesSystemButton,0,wx.ALL,10)
86 self.buttonSizer.Add(self.genesisSystemButton,0,wx.ALL,10)
87 self.buttonSizer.Add(self.fz1SystemButton,0,wx.ALL,10)
88 self.buttonSizer.Add(self.ps1SystemButton,0,wx.ALL,10)
89
90 def CreateFieldsFirstRow(self):
91 self.gameNameStaticText = wx.StaticText(self.panel, -1, "Game Name:")
92 self.gameNameTextCtrl = wx.TextCtrl(self.panel, -1, size=(325, -1))
93
94 self.gameHashStaticText = wx.StaticText(self.panel, -1, "Game Hash:")
95 self.gameHashTextCtrl = wx.TextCtrl(self.panel, -1, size=(325, -1))
96
97 self.gameFileNameStaticText = wx.StaticText(self.panel, -1, "Game File Name:")
98 self.gameFileNameTextCtrl = wx.TextCtrl(self.panel, -1, size=(325, -1))
99
100 self.gameFilePathStaticText = wx.StaticText(self.panel, -1, "Game File Path:")
101 self.gameFilePathTextCtrl = wx.TextCtrl(self.panel, -1, size=(425, -1))
102
103 self.noIntroGameNameStaticText = wx.StaticText(self.panel, -1, "No Intro Game Name:")
104 self.noIntroGameNameTextCtrl = wx.TextCtrl(self.panel, -1, size=(325, -1))
105
106 self.noIntroSystemNameStaticText = wx.StaticText(self.panel, -1, "No Intro System:")
107 self.noIntroSystemNameTextCtrl = wx.TextCtrl(self.panel, -1, size=(380, -1))
108
109 self.gameNameSizer = wx.BoxSizer(wx.HORIZONTAL)
110 self.gameNameSizer.Add(self.gameNameStaticText,0,wx.ALL, 10)
111 self.gameNameSizer.Add(self.gameNameTextCtrl,0,wx.ALL, 10)
112
113 self.gameHashSizer = wx.BoxSizer(wx.HORIZONTAL)
114 self.gameHashSizer.Add(self.gameHashStaticText,0,wx.ALL, 10)
115 self.gameHashSizer.Add(self.gameHashTextCtrl,0,wx.ALL, 10)
116
117 self.gameFileNameSizer = wx.BoxSizer(wx.HORIZONTAL)
118 self.gameFileNameSizer.Add(self.gameFileNameStaticText,0,wx.ALL, 10)
119 self.gameFileNameSizer.Add(self.gameFileNameTextCtrl,0,wx.ALL, 10)
120
121 self.gameFilePathSizer = wx.BoxSizer(wx.HORIZONTAL)
122 self.gameFilePathSizer.Add(self.gameFilePathStaticText,0,wx.ALL, 10)
123 self.gameFilePathSizer.Add(self.gameFilePathTextCtrl,0,wx.ALL, 10)
124
125 self.noIntroGameNameSizer = wx.BoxSizer(wx.HORIZONTAL)
126 self.noIntroGameNameSizer.Add(self.noIntroGameNameStaticText,0,wx.ALL, 10)
127 self.noIntroGameNameSizer.Add(self.noIntroGameNameTextCtrl,0,wx.ALL, 10)
128
129 self.noIntroSystemNameSizer = wx.BoxSizer(wx.HORIZONTAL)
130 self.noIntroSystemNameSizer.Add(self.noIntroSystemNameStaticText,0,wx.ALL, 10)
131 self.noIntroSystemNameSizer.Add(self.noIntroSystemNameTextCtrl,0,wx.ALL, 10)
132
133 self.fieldsFirstRowSizer = wx.BoxSizer(wx.VERTICAL)
134 self.fieldsFirstRowSizer.Add(self.gameNameSizer,0,wx.ALL, 10)
135 self.fieldsFirstRowSizer.Add(self.gameHashSizer,0,wx.ALL, 10)
136 self.fieldsFirstRowSizer.Add(self.gameFileNameSizer,0,wx.ALL, 10)
137 self.fieldsFirstRowSizer.Add(self.gameFilePathSizer,0,wx.ALL, 10)
138 self.fieldsFirstRowSizer.Add(self.noIntroGameNameSizer,0,wx.ALL, 10)
139 self.fieldsFirstRowSizer.Add(self.noIntroSystemNameSizer,0,wx.ALL, 10)
140
141
142 def MenuData(self):
143 return(("&Tools",
144 ("&Add Roms","Adds new Roms to a selected system.", self.OnAddNewRoms),
145 ("Import &NoIntro DAT", "Allows for the import of any of the No Intro DAT files.", self.OnImportNewNoIntroDat),
146 ("Import &TOSEC DAT", "Allows for the import of any of the TOSEC DAT files.", self.OnImportNewTosecDat)),
147 ("&Reports",
148 ("&Duplicates Report","Generates a report detailing duplicates that exist in your collection.", self.NothingYet)),
149 ("&Help",
150 ("&About", "Displays the About Window", self.NothingYet)))
151
152 def CreateMenuBar(self):
153 menuBar = wx.MenuBar()
154 for eachMenuData in self.MenuData():
155 menuLabel = eachMenuData[0]
156 menuItems = eachMenuData[1:]
157 menuBar.Append(self.CreateMenu(menuItems), menuLabel)
158 self.SetMenuBar(menuBar)
159
160 def CreateMenu(self, menuData):
161 menu = wx.Menu()
162 for eachLabel, eachStatus, eachHandler in menuData:
163 if not eachLabel:
164 menu.AppendSeparator()
165 continue
166 menuItem = menu.Append(-1, eachLabel, eachStatus)
167 self.Bind(wx.EVT_MENU, eachHandler, menuItem)
168 return menu
169
170 def OnSystemSelected(self, evt):
171 systemsButtonNamesList = list(self.systemButtonDict.keys())
172 #print(list(self.systemButtonDict.keys()))
173 systemsButtonNamesList.remove(evt.GetEventObject().GetLabelText())
174 #print(evt.GetEventObject().GetLabelText())
175 for i in systemsButtonNamesList:
176 self.systemButtonDict[i].SetValue(False)
177
178 self.gamesListMatrix = Gromulus_Lib.GetGameListBySystem('snes', self.dbConnection)
179 gamesList = list(self.gamesListMatrix.keys())
180 gamesList.sort()
181
182 self.gameSelectionListBox.Clear()
183 self.gameSelectionListBox.AppendItems(gamesList)
184
185
186 def OnGameSelected(self, evt):
187 print(self.gameSelectionListBox.GetStringSelection())
188 gameTuple = Gromulus_Lib.GetSingleGameById(self.gamesListMatrix[self.gameSelectionListBox.GetStringSelection()], self.dbConnection)
189
190 if gameTuple[0]:
191 self.gameNameTextCtrl.SetValue(gameTuple[0])
192 else:
193 self.gameNameTextCtrl.SetValue("")
194 if gameTuple[1]:
195 self.gameHashTextCtrl.SetValue(gameTuple[1])
196 else:
197 self.gameHashTextCtrl.SetValue("")
198 if gameTuple[2]:
199 self.gameFileNameTextCtrl.SetValue(gameTuple[2])
200 else:
201 self.gameFileNameTextCtrl.SetValue("")
202 if gameTuple[3]:
203 self.gameFilePathTextCtrl.SetValue(gameTuple[3])
204 else:
205 self.gameFilePathTextCtrl.SetValue("")
206 if gameTuple[4]:
207 self.noIntroGameNameTextCtrl.SetValue(gameTuple[4])
208 else:
209 self.noIntroGameNameTextCtrl.SetValue("")
210 if gameTuple[5]:
211 self.noIntroSystemNameTextCtrl.SetValue(gameTuple[5])
212 else:
213 self.noIntroSystemNameTextCtrl.SetValue("")
214
215 def NothingYet(self, event):
216 diag = wx.MessageDialog(self, "Nothing here yet!", "Disabled...", wx.OK | wx.ICON_INFORMATION)
217 diag.ShowModal()
218 diag.Destroy()
219
220 def OnImportNewNoIntroDat(self,event):
221 dlg = wx.FileDialog(
222 self, message="Import New NoIntro DAT ...", defaultDir=os.getcwd(),
223 defaultFile="", wildcard="DAT files (*.dat)|*.dat", style=wx.FD_OPEN | wx.FD_CHANGE_DIR
224 )
225 if dlg.ShowModal() == wx.ID_OK:
226 datPath = dlg.GetPath()
227 Gromulus_Lib.ImportNewNoIntroDat(datPath, self.dbConnection)
228 doneDiag = wx.MessageDialog(self, "NoIntro DAT imported","All Done!",wx.OK | wx.ICON_INFORMATION)
229 doneDiag.ShowModal()
230 doneDiag.Destroy()
231
232 def OnImportNewTosecDat(self,event):
233 dlg = wx.FileDialog(
234 self, message="Import New Tosec DAT ...", defaultDir=os.getcwd(),
235 defaultFile="", wildcard="DAT files (*.dat)|*.dat", style=wx.FD_OPEN | wx.FD_CHANGE_DIR
236 )
237 if dlg.ShowModal() == wx.ID_OK:
238 datPath = dlg.GetPath()
239 Gromulus_Lib.ImportNewTosecDat(datPath, self.dbConnection)
240 doneDiag = wx.MessageDialog(self, "Tosec DAT imported","All Done!",wx.OK | wx.ICON_INFORMATION)
241 doneDiag.ShowModal()
242 doneDiag.Destroy()
243
244
245 def OnAddNewRoms(self,event):
246 systemMatrix = Gromulus_Lib.GetSystemList(self.dbConnection)
247 systemsList = list(systemMatrix.keys())
248 dlg = wx.SingleChoiceDialog(self,
249 "Select system for new ROMs",
250 "List of systemss", systemsList)
251 if (dlg.ShowModal() == wx.ID_OK):
252 dlg2 = wx.DirDialog(self, "Choose a directory:",
253 style=wx.DD_DEFAULT_STYLE)
254 if (dlg2.ShowModal() == wx.ID_OK):
255 romsToImportPath = dlg2.GetPath()
256 systemID = systemMatrix[dlg.GetStringSelection()][0]
257 importedCount, alreadyExistsCount, errImportCount = Gromulus_Lib.AddNewRoms(romsToImportPath, systemID, self.dbConnection)#, testOnly=True)
258 #print(systemMatrix[dlg.GetStringSelection()])
259 #print(dlg2.GetPath())
260 doneDiag = wx.MessageDialog(self, f"{str(importedCount)} files imported.\n{str(alreadyExistsCount)} files not imported because you already have them.\n{str(errImportCount)} files imported because of errors.", "Rom import process complete",wx.OK | wx.ICON_INFORMATION)
261 doneDiag.ShowModal()
262 doneDiag.Destroy()
263
264
265
266 class MyApp(wx.App):
267 def OnInit(self):
268 self.frame = MyFrame(None, -1, "Gromulus v1.2")
269 self.frame.Show(True)
270 self.SetTopWindow(self.frame)
271 return True
272 def OnExit(self):
273 if hasattr(self, "frame") and hasattr(self.frame, "db"):
274 self.frame.db.close()
275 print("Closed DB")
276 return 0
277
278
279 if __name__ == '__main__':
280 app = MyApp(0)
281 app.MainLoop()