c9b3a0e900ad6da3d02b6ebfe6cae96322c0beb8
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / SourcesWin.cpp
1 //
2 // SourcesWin.cpp - Sources tracing window
3 //
4 // by Jean-Paul Mari
5 //
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 //
8 // Who When What
9 // --- ---------- -------------------------------------------------------------
10 // JPM 08/23/2019 Created this file
11
12 // STILL TO DO:
13 //
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include "DBGManager.h"
18 #include "debugger/SourceCWin.h"
19 #include "debugger/SourcesWin.h"
20 #include "m68000/m68kinterface.h"
21
22
23 //
24 SourcesWindow::SourcesWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),
25 layout(new QVBoxLayout),
26 sourcestabWidget(new QTabWidget),
27 sourcesinfostab(0),
28 NbSourcesInfos(0),
29 CurrentTab(0),
30 OldCurrentTab(0),
31 OldCurrentNumLineSrc(0),
32 indexErrorTab(-1),
33 sourceErrorTab(0)
34 {
35 // Prepare layout
36 sourcestabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
37 sourcestabWidget->setTabsClosable(true);
38 layout->addWidget(sourcestabWidget);
39
40 // Set layout
41 setLayout(layout);
42
43 // Connect the signals
44 connect(sourcestabWidget, SIGNAL(currentChanged(const int)), this, SLOT(SelectTab(const int)));
45 connect(sourcestabWidget, SIGNAL(tabCloseRequested(const int)), this, SLOT(CloseTab(const int)));
46 }
47
48
49 // Close tab
50 void SourcesWindow::CloseTab(const int)
51 {
52 CloseCurrentTab();
53 }
54
55
56 // Select tab
57 void SourcesWindow::SelectTab(const int)
58 {
59 #if 0
60 size_t i = 0;
61 QString t = sourcestabWidget->tabText(index);
62 while ((i < NbSourcesInfos) && strcmp(sourcesinfostab[i++].Filename, t.toLatin1().data()));
63
64 if ((i != NbSourcesInfos) && (sourcesinfostab[i - 1].IndexTab != -1) && (CurrentTab == (i - 1)))
65 {
66 sourcesinfostab[(i - 1)].sourceCtab->RefreshContents();
67 }
68 #endif
69 }
70
71
72 // Sources initialisation
73 void SourcesWindow::Init(void)
74 {
75 size_t i, j;
76 char *Ptr, *Ptr1;
77
78 // Get number of sources
79 NbSourcesInfos = DBGManager_GetNbSources();
80 if (NbSourcesInfos)
81 {
82 // Alloc structure for the source informations
83 sourcesinfostab = (SourcesInfos *)calloc(NbSourcesInfos, sizeof(SourcesInfos));
84
85 // Fill sources information
86 for (i = 0; i < NbSourcesInfos; i++)
87 {
88 // Get source filename without misguiding information
89 Ptr = DBGManager_GetNumSourceFilename(i);
90 Ptr1 = sourcesinfostab[i].Filename = (char *)malloc(strlen(Ptr) + 1);
91 while (((*Ptr == '.') || ((*Ptr == '/') || (*Ptr == '\\'))) && Ptr++);
92 strcpy(Ptr1, Ptr);
93 // Get texts dedicated information
94 for (j = 0; j < 2; j++)
95 {
96 sourcesinfostab[i].NbLinesText[j] = DBGManager_GetSrcNbListPtrFromIndex(i, j);
97 }
98 sourcesinfostab[i].NumLinesUsed = DBGManager_GetSrcNumLinesPtrFromIndex(i, true);
99 sourcesinfostab[i].SourceText = DBGManager_GetSrcListPtrFromIndex(i, false);
100 // Get remaining information
101 sourcesinfostab[i].Language = DBGManager_GetSrcLanguageFromIndex(i);
102 sourcesinfostab[i].IndexTab = -1;
103 }
104 }
105 }
106
107
108 // Get the tracing status
109 bool SourcesWindow::GetTraceStatus(void)
110 {
111 if (NbSourcesInfos)
112 {
113 switch (sourcesinfostab[CurrentTab].Language)
114 {
115 case DBG_LANG_VASM_Assembler:
116 break;
117
118 default:
119 return true;
120 break;
121 }
122 }
123
124 return false;
125 }
126
127
128 // Check if line has changed
129 bool SourcesWindow::CheckChangeLine(void)
130 {
131 size_t NumLine;
132
133 if (NumLine = DBGManager_GetNumLineFromAdr(m68k_get_reg(NULL, M68K_REG_PC), DBG_NO_TAG))
134 {
135 if (OldCurrentTab == CurrentTab)
136 {
137 if (OldCurrentNumLineSrc != NumLine)
138 {
139 OldCurrentNumLineSrc = NumLine;
140 return true;
141 }
142 }
143 else
144 {
145 OldCurrentTab = CurrentTab;
146 OldCurrentNumLineSrc = 0;
147 }
148
149 }
150
151 return false;
152 }
153
154
155 //
156 void SourcesWindow::RefreshContents(void)
157 {
158 size_t m68kPC = m68k_get_reg(NULL, M68K_REG_PC);
159 int index = 0;
160 size_t i;
161 DBGstatus Status;
162 char *Filename;
163
164 // Check valid PC
165 if (m68kPC && NbSourcesInfos)
166 {
167 // Get source filename pointed by PC address
168 Filename = DBGManager_GetFullSourceFilenameFromAdr(m68kPC, &Status);
169 if (!Status && Filename)
170 {
171 // Look for a new tab
172 for (i = 0; i < NbSourcesInfos; i++, !index)
173 {
174 if (sourcesinfostab[i].Filename)
175 {
176 if (strstr(Filename, sourcesinfostab[i].Filename))
177 {
178 // Open a new tab for a source code
179 if (sourcesinfostab[i].IndexTab == -1)
180 {
181 sourcesinfostab[i].IndexTab = index = sourcestabWidget->addTab(sourcesinfostab[i].sourceCtab = new(SourceCWindow), tr(sourcesinfostab[i].Filename));
182 sourcesinfostab[i].sourceCtab->FillTab(i, sourcesinfostab[i].SourceText, sourcesinfostab[i].NbLinesText, sourcesinfostab[i].NumLinesUsed);
183 }
184
185 sourcestabWidget->setCurrentIndex(sourcesinfostab[i].IndexTab);
186 sourcesinfostab[CurrentTab].sourceCtab->SetCursorTrace(sourcesinfostab[CurrentTab].CurrentNumLineSrc, true);
187 sourcesinfostab[i].sourceCtab->SetCursorTrace(sourcesinfostab[i].CurrentNumLineSrc = (int)DBGManager_GetNumLineFromAdr(m68kPC, DBG_NO_TAG), false);
188 sourcesinfostab[i].sourceCtab->RefreshContents();
189 CurrentTab = i;
190 }
191 }
192 }
193 }
194 else
195 {
196 // Source file doesn't exist
197 if (indexErrorTab == -1)
198 {
199 indexErrorTab = sourcestabWidget->addTab(sourceErrorTab = new(SourceCWindow), tr("Source file not available"));
200 //sourceErrorTab->hide();
201 }
202 sourcestabWidget->setCurrentIndex(indexErrorTab);
203 }
204 }
205 }
206
207
208 // Close / Remove current tab
209 void SourcesWindow::CloseCurrentTab(void)
210 {
211 size_t i = 0;
212 int Index;
213 QString t = sourcestabWidget->tabText((Index = sourcestabWidget->currentIndex()));
214
215 // Check error tab presence
216 if (indexErrorTab == Index)
217 {
218 // Close the error tab
219 indexErrorTab = -1;
220 }
221 else
222 {
223 // Close source code text tab
224 while ((i < NbSourcesInfos) && strcmp(sourcesinfostab[i++].Filename, t.toLatin1().data()));
225 sourcesinfostab[(i - 1)].IndexTab = -1;
226 }
227
228 // remove the tab
229 sourcestabWidget->removeTab(Index);
230 }
231
232
233 //
234 void SourcesWindow::keyPressEvent(QKeyEvent * e)
235 {
236 // Close/Remove the current tab
237 if (e->key() == Qt::Key_Escape)
238 {
239 CloseCurrentTab();
240 }
241 }
242
243
244 //
245 void SourcesWindow::Reset(void)
246 {
247 // Clear the tabs
248 sourcestabWidget->clear();
249
250 // Clear tab information
251 while (NbSourcesInfos)
252 {
253 free(sourcesinfostab[--NbSourcesInfos].Filename);
254 }
255 free(sourcesinfostab);
256 }
257
258
259 //
260 void SourcesWindow::Close(void)
261 {
262 Reset();
263 }