2 // SourcesWin.cpp - Sources tracing window
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
9 // --- ---------- -------------------------------------------------------------
10 // JPM 08/23/2019 Created this file
11 // JPM Apr./2021 Fixed potential crash with the tabs reset
14 // Use the CloseTab signal's value instead to close the current tab
19 #include "DBGManager.h"
20 #include "debugger/SourceCWin.h"
21 #include "debugger/SourcesWin.h"
22 #include "m68000/m68kinterface.h"
26 SourcesWindow::SourcesWindow(QWidget
* parent
/*= 0*/) : QWidget(parent
, Qt::Dialog
),
27 layout(new QVBoxLayout
),
28 sourcestabWidget(new QTabWidget
),
33 OldCurrentNumLineSrc(0),
38 sourcestabWidget
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Expanding
);
39 sourcestabWidget
->setTabsClosable(true);
40 layout
->addWidget(sourcestabWidget
);
45 // connect the signals
46 connect(sourcestabWidget
, SIGNAL(currentChanged(const int)), this, SLOT(SelectTab(const int)));
47 connect(sourcestabWidget
, SIGNAL(tabCloseRequested(const int)), this, SLOT(CloseTab(const int)));
52 void SourcesWindow::CloseTab(const int)
59 void SourcesWindow::SelectTab(const int)
63 QString t
= sourcestabWidget
->tabText(index
);
64 while ((i
< NbSourcesInfos
) && strcmp(sourcesinfostab
[i
++].Filename
, t
.toLatin1().data()));
66 if ((i
!= NbSourcesInfos
) && (sourcesinfostab
[i
- 1].IndexTab
!= -1) && (CurrentTab
== (i
- 1)))
68 sourcesinfostab
[(i
- 1)].sourceCtab
->RefreshContents();
74 // Sources initialisation
75 // Prepare tabs for every available source code file
76 void SourcesWindow::Init(void)
81 // get number of sources
82 NbSourcesInfos
= DBGManager_GetNbSources();
85 // alloc structure for the source informations
86 sourcesinfostab
= (SourcesInfos
*)calloc(NbSourcesInfos
, sizeof(SourcesInfos
));
88 // fill sources information
89 for (i
= 0; i
< NbSourcesInfos
; i
++)
91 // get source filename without misguiding information
92 Ptr
= DBGManager_GetNumSourceFilename(i
);
93 Ptr1
= sourcesinfostab
[i
].Filename
= (char *)malloc(strlen(Ptr
) + 1);
94 while (((*Ptr
== '.') || ((*Ptr
== '/') || (*Ptr
== '\\'))) && Ptr
++);
96 // get texts dedicated information
97 for (j
= 0; j
< 2; j
++)
99 sourcesinfostab
[i
].NbLinesText
[j
] = DBGManager_GetSrcNbListPtrFromIndex(i
, j
);
101 sourcesinfostab
[i
].NumLinesUsed
= DBGManager_GetSrcNumLinesPtrFromIndex(i
, true);
102 sourcesinfostab
[i
].SourceText
= DBGManager_GetSrcListPtrFromIndex(i
, false);
103 // get remaining information
104 sourcesinfostab
[i
].Language
= DBGManager_GetSrcLanguageFromIndex(i
);
105 sourcesinfostab
[i
].IndexTab
= -1;
110 // no source files exist
111 sourcesinfostab
= NULL
;
116 // Get the tracing status
117 bool SourcesWindow::GetTraceStatus(void)
121 switch (sourcesinfostab
[CurrentTab
].Language
)
123 case DBG_LANG_VASM_Assembler
:
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
138 bool SourcesWindow::CheckChangeLine(void)
142 // get the line number based on the current M68K PC address
143 if (NumLine
= DBGManager_GetNumLineFromAdr(m68k_get_reg(NULL
, M68K_REG_PC
), DBG_NO_TAG
))
145 if (OldCurrentTab
== CurrentTab
)
147 if (OldCurrentNumLineSrc
!= NumLine
)
149 OldCurrentNumLineSrc
= NumLine
;
155 OldCurrentTab
= CurrentTab
;
156 OldCurrentNumLineSrc
= 0;
165 // Open a new tab for a file source code
166 // Set a unique tab for unavailable source code
167 void SourcesWindow::RefreshContents(void)
169 size_t m68kPC
= m68k_get_reg(NULL
, M68K_REG_PC
);
175 // check valid M68K PC address
176 if (m68kPC
&& NbSourcesInfos
)
178 // get source filename pointed by PC address
179 Filename
= DBGManager_GetFullSourceFilenameFromAdr(m68kPC
, &Status
);
180 if (!Status
&& Filename
)
182 // look for a new tab
183 for (i
= 0; i
< NbSourcesInfos
; i
++, !index
)
185 if (sourcesinfostab
[i
].Filename
)
187 if (strstr(Filename
, sourcesinfostab
[i
].Filename
))
189 // open a new tab for a source code
190 if (sourcesinfostab
[i
].IndexTab
== -1)
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
);
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();
207 // source file doesn't exist
208 if (indexErrorTab
== -1)
210 indexErrorTab
= sourcestabWidget
->addTab(sourceErrorTab
= new(SourceCWindow
), tr("Source file not available"));
211 //sourceErrorTab->hide();
213 sourcestabWidget
->setCurrentIndex(indexErrorTab
);
219 // Close / Remove current tab
220 void SourcesWindow::CloseCurrentTab(void)
224 QString t
= sourcestabWidget
->tabText((Index
= sourcestabWidget
->currentIndex()));
226 // check error tab presence
227 if (indexErrorTab
== Index
)
229 // close the error tab
234 // close source code text tab
235 while ((i
< NbSourcesInfos
) && strcmp(sourcesinfostab
[i
++].Filename
, t
.toLatin1().data()));
236 sourcesinfostab
[(i
- 1)].IndexTab
= -1;
240 sourcestabWidget
->removeTab(Index
);
245 void SourcesWindow::keyPressEvent(QKeyEvent
* e
)
247 // close/remove the current tab
248 if (e
->key() == Qt::Key_Escape
)
255 // Reset all source files tab
256 void SourcesWindow::Reset(void)
259 sourcestabWidget
->clear();
261 // clear tab information
262 while (NbSourcesInfos
)
264 free(sourcesinfostab
[--NbSourcesInfos
].Filename
);
266 free(sourcesinfostab
);
271 void SourcesWindow::Close(void)