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