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