Added a cartdridge view menu
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / CartFilesListWin.cpp
1 //
2 // CartFilesListWin.cpp - List files in the cartdridge
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // Who When What
9 // --- ---------- -----------------------------------------------------------
10 // JPM 10/26/2018 Created this file
11 //
12
13 // TO DO:
14 // To allow file opening / viewing
15 // Remove/modify the 1st information, named '1', at the top
16 // To add a filter
17 //
18
19 #include "debugger/CartFilesListWin.h"
20 #include "memory.h"
21 #include "settings.h"
22 #include "debugger/DBGManager.h"
23
24
25 //
26 CartFilesListWindow::CartFilesListWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
27 TableView(new QTableView),
28 model(new QStandardItemModel),
29 layout(new QVBoxLayout),
30 treeView(new QTreeView),
31 standardModel(new QStandardItemModel),
32 rootNode(new QStandardItem),
33 CartDirectory(NULL),
34 statusbar(new QStatusBar),
35 fileItems(NULL),
36 nbItem(0),
37 CartUsedBytes(0),
38 CartDirType(CFL_NOTYPE)
39 {
40 setWindowTitle(tr("Cartdridge directory & files"));
41
42 // Set the font
43 QFont fixedFont("Lucida Console", 8, QFont::Normal);
44 fixedFont.setStyleHint(QFont::TypeWriter);
45
46 // Set the new layout with proper identation and readibility
47 #ifdef CFL_BUFFERTREAM
48 model->setColumnCount(5);
49 #else
50 model->setColumnCount(4);
51 #endif
52 model->setHeaderData(0, Qt::Horizontal, QObject::tr("File"));
53 model->setHeaderData(1, Qt::Horizontal, QObject::tr("Address"));
54 model->setHeaderData(2, Qt::Horizontal, QObject::tr("Size"));
55 model->setHeaderData(3, Qt::Horizontal, QObject::tr("Seek"));
56 #ifdef CFL_BUFFERTREAM
57 model->setHeaderData(4, Qt::Horizontal, QObject::tr("Stream"));
58 #endif
59 // Information table
60 TableView->setModel(model);
61 TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
62 TableView->setShowGrid(0);
63 TableView->setFont(fixedFont);
64 TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());
65 TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);
66 layout->addWidget(TableView);
67
68 // Setup root
69 rootNode = standardModel->invisibleRootItem();
70 //register the model
71 treeView->setModel(standardModel);
72 treeView->expandAll();
73 layout->addWidget(treeView);
74
75 // Status bar
76 layout->addWidget(statusbar);
77 setLayout(layout);
78 }
79
80
81 //
82 CartFilesListWindow::~CartFilesListWindow(void)
83 {
84 }
85
86
87 //
88 void CartFilesListWindow::Reset(void)
89 {
90 standardModel->setRowCount(0);
91 model->setRowCount(0);
92 free(CartDirectory);
93 free(fileItems);
94 fileItems = NULL;
95 CartDirectory = NULL;
96 CartUsedBytes = CartNbrFiles = CartDirType = nbItem = 0;
97 }
98
99
100 //
101 void CartFilesListWindow::RefreshContents(void)
102 {
103 size_t Error;
104 char msg[1024];
105
106 if (isVisible())
107 {
108 if (!CartDirectory)
109 {
110 if (CartDirType = GetDirType())
111 {
112 if ((CartNbrFiles = GetNbrFiles()))
113 {
114 if ((CartDirectory = (CARTDIRINFO *)CreateInfos()))
115 {
116 UpdateInfos();
117 sprintf(msg, "%u files | %u bytes in cartdridge", (unsigned int)CartNbrFiles, (unsigned int)CartUsedBytes);
118 Error = CFL_NOERROR;
119 }
120 else
121 {
122 sprintf(msg, "Cannot use directory");
123 Error = CFL_NODIRUSE;
124 }
125 }
126 else
127 {
128 sprintf(msg, "No files");
129 Error = CFL_NOFILESLIST;
130 }
131 }
132 else
133 {
134 sprintf(msg, "No directory found");
135 Error = CFL_NODIRECTORYLIST;
136 }
137
138 // Display status bar
139 if (Error)
140 {
141 if ((Error & CFL_WARNING))
142 {
143 statusbar->setStyleSheet("background-color: lightyellow; font: bold");
144 }
145 else
146 {
147 statusbar->setStyleSheet("background-color: tomato; font: bold");
148 }
149 }
150 else
151 {
152 statusbar->setStyleSheet("background-color: lightgreen; font: bold");
153 }
154 statusbar->showMessage(QString(msg));
155 }
156 else
157 {
158 UpdateInfos();
159 }
160 }
161 }
162
163
164 // Get files number in the directory
165 size_t CartFilesListWindow::GetNbrFiles(void)
166 {
167 switch (CartDirType)
168 {
169 case CFL_OSJAGTYPE:
170 return ((DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory_End") - DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory_Deb"))) / sizeof(long);
171 break;
172
173 default:
174 return 0;
175 break;
176 }
177 }
178
179
180 // Get directory type
181 size_t CartFilesListWindow::GetDirType(void)
182 {
183 if (DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory"))
184 {
185 return CFL_OSJAGTYPE;
186 }
187 else
188 {
189 return CFL_NOTYPE;
190 }
191 }
192
193
194 // Get filename from index (starting from 0)
195 void CartFilesListWindow::GetFileInfos(CARTDIRINFO *Ptr, size_t index)
196 {
197 OSJAGDir *Adr;
198 size_t Offset;
199
200 switch (CartDirType)
201 {
202 case CFL_OSJAGTYPE:
203 Offset = DBGManager_GetAdrFromSymbolName((char *)"OSJAG_Directory_Deb") + (index * sizeof(long));
204 Adr = (OSJAGDir *)&jagMemSpace[Offset = GET32(jagMemSpace, Offset)];
205 if (strlen(Adr->Filename))
206 {
207 Ptr->PtrFilename = Adr->Filename;
208 Ptr->valid = true;
209 }
210 else
211 {
212 Ptr->PtrFilename = (char *)"(null)";
213 }
214 Ptr->PtrDataFile = GET32(jagMemSpace, Offset);
215 Ptr->SizeFile = GET32(jagMemSpace, (Offset + sizeof(long)));
216 break;
217
218 default:
219 break;
220 }
221 }
222
223
224 // Create information from the directory information
225 void *CartFilesListWindow::CreateInfos(void)
226 {
227 CARTDIRINFO *Ptr = (CARTDIRINFO *)calloc(CartNbrFiles, sizeof(CARTDIRINFO));
228 model->setRowCount(0);
229
230 for (int i = 0; i < CartNbrFiles; i++)
231 {
232 GetFileInfos(&Ptr[i], i);
233 AddFilename(Ptr[i].PtrFilename, rootNode, 0);
234 // Display row content
235 model->insertRow(i);
236 model->setItem(i, 0, new QStandardItem(QString("%1").arg(Ptr[i].PtrFilename)));
237 if (!Ptr[i].SizeFile)
238 {
239 //model->setItem(i, 1, new QStandardItem(QString("%1").arg("")));
240 //model->setItem(i, 2, new QStandardItem(QString("%1").arg("")));
241 }
242 else
243 {
244 model->setItem(i, 1, new QStandardItem(QString("0x%1").arg(Ptr[i].PtrDataFile, 6, 16, QChar('0'))));
245 model->setItem(i, 2, new QStandardItem(QString("0x%1").arg(Ptr[i].SizeFile, 6, 16, QChar('0'))));
246 }
247 CartUsedBytes += Ptr[i].SizeFile;
248 }
249
250 return Ptr;
251 }
252
253
254 // Update the variables information (seek and stream buffer)
255 void CartFilesListWindow::UpdateInfos(void)
256 {
257 size_t Offset;
258
259 for (int i = 0; i < CartNbrFiles; i++)
260 {
261 // Check if file validity (exitence)
262 if (CartDirectory[i].valid)
263 {
264 // Get the current seek and tentatively check validity (must be included in the ram zone)
265 Offset = DBGManager_GetAdrFromSymbolName((char *)"OSJAG_SeekPosition") + (i * sizeof(long));
266 if ((CartDirectory[i].CurrentSeek = GET32(jagMemSpace, Offset)) < vjs.DRAM_size)
267 {
268 model->setItem(i, 3, new QStandardItem(QString("0x%1").arg(CartDirectory[i].CurrentSeek, 6, 16, QChar('0'))));
269 }
270 else
271 {
272 //model->setItem(i, 3, new QStandardItem(QString("%1").arg("")));
273 }
274
275 // Get stream buffer address and check validity (must be included in the ram zone)
276 Offset = DBGManager_GetAdrFromSymbolName((char *)"OSJAG_PtrBuffer") + (i * sizeof(long));
277 if (((CartDirectory[i].PtrBufferStream = GET32(jagMemSpace, Offset)) < vjs.DRAM_size) && CartDirectory[i].PtrBufferStream)
278 {
279 #ifdef CFL_BUFFERTREAM
280 model->setItem(i, 4, new QStandardItem(QString("0x%1").arg(CartDirectory[i].PtrBufferStream, 6, 16, QChar('0'))));
281 #else
282 if (!CartDirectory[i].SizeFile)
283 {
284 model->setItem(i, 1, new QStandardItem(QString("0x%1").arg(CartDirectory[i].PtrBufferStream, 6, 16, QChar('0'))));
285 }
286 #endif
287 }
288 else
289 {
290 #ifdef CFL_BUFFERTREAM
291 model->setItem(i, 4, new QStandardItem(QString("%1").arg("")));
292 #else
293 if (!CartDirectory[i].SizeFile)
294 {
295 model->setItem(i, 1, new QStandardItem(QString("%1").arg("")));
296 }
297 #endif
298 }
299 }
300 }
301 }
302
303
304 // Add source code filename in the list
305 void CartFilesListWindow::AddFilename(char *FileName, QStandardItem *root, size_t ItemPos)
306 {
307 char *Ptr = FileName;
308 Sfileitem *PtrNewFile;
309 char Buffer[255];
310 char a;
311
312 while ((a = *Ptr++) && ((a != '\\') && (a != '/')));
313
314 if (a)
315 {
316 strncpy(Buffer, FileName, (Ptr - FileName - 1));
317 Buffer[(Ptr - FileName - 1)] = 0;
318 }
319 else
320 {
321 strcpy(Buffer, FileName);
322 }
323 PtrNewFile = (Sfileitem *)AddItem(Buffer, ItemPos);
324 if (!PtrNewFile->PreviousItem)
325 {
326 PtrNewFile->PreviousItem = root;
327 root->appendRow(PtrNewFile->Item);
328 PtrNewFile->Item->setEditable(false);
329 }
330
331 if (a)
332 {
333 return (AddFilename(Ptr, PtrNewFile->Item, (ItemPos + 1)));
334 }
335 }
336
337
338 // Add item to the list
339 // Return void * on new item or already existing one
340 void *CartFilesListWindow::AddItem(char *ItemName, size_t ItemPos)
341 {
342 Sfileitem *Ptr = fileItems;
343
344 // Look for already existing item
345 for (size_t i = 0; i < nbItem; i++)
346 {
347 if ((Ptr->column == ItemPos) && !strcmp(Ptr->Item->text().toLocal8Bit().constData(), ItemName))
348 {
349 return Ptr;
350 }
351 else
352 {
353 Ptr++;
354 }
355 }
356
357 // Add item in the list
358 fileItems = (Sfileitem *)realloc(fileItems, (sizeof(Sfileitem) * ++nbItem));
359 (fileItems + (nbItem - 1))->column = ItemPos;
360 (fileItems + (nbItem - 1))->PreviousItem = NULL;
361 (fileItems + (nbItem - 1))->Item = new QStandardItem(ItemName);
362 return (fileItems + (nbItem - 1));
363 }
364
365
366 //
367 void CartFilesListWindow::keyPressEvent(QKeyEvent * e)
368 {
369 if (e->key() == Qt::Key_Escape)
370 {
371 hide();
372 }
373 }