2 * Copyright 2015-2016, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
7 #include "ReportUserInterface.h"
12 #include <FindDirectory.h>
15 #include <AutoLocker.h>
17 #include "MessageCodes.h"
21 ReportUserInterface::ReportUserInterface(thread_id targetThread
,
22 const char* reportPath
)
26 fTargetThread(targetThread
),
27 fReportPath(reportPath
),
36 ReportUserInterface::~ReportUserInterface()
38 if (fShowSemaphore
>= 0)
39 delete_sem(fShowSemaphore
);
41 fTeam
->RemoveListener(this);
46 ReportUserInterface::ID() const
48 return "ReportUserInterface";
53 ReportUserInterface::Init(Team
* team
, UserInterfaceListener
* listener
)
55 fShowSemaphore
= create_sem(0, "show report");
56 if (fShowSemaphore
< 0)
57 return fShowSemaphore
;
59 fReportSemaphore
= create_sem(0, "report generator wait");
60 if (fReportSemaphore
< 0)
61 return fReportSemaphore
;
66 fTeam
->AddListener(this);
73 ReportUserInterface::Show()
76 release_sem(fShowSemaphore
);
81 ReportUserInterface::Terminate()
88 ReportUserInterface::Clone() const
90 // the report interface does not support cloning, since
91 // it won't ever be asked to interactively restart.
97 ReportUserInterface::IsInteractive() const
104 ReportUserInterface::LoadSettings(const TeamUiSettings
* settings
)
111 ReportUserInterface::SaveSettings(TeamUiSettings
*& settings
) const
118 ReportUserInterface::NotifyUser(const char* title
, const char* message
,
119 user_notification_type type
)
125 ReportUserInterface::NotifyBackgroundWorkStatus(const char* message
)
131 ReportUserInterface::SynchronouslyAskUser(const char* title
,
132 const char* message
, const char* choice1
, const char* choice2
,
140 ReportUserInterface::SynchronouslyAskUserForFile(entry_ref
* _ref
)
142 return B_UNSUPPORTED
;
147 ReportUserInterface::Run()
149 // Wait for the Show() semaphore to be released.
152 error
= acquire_sem(fShowSemaphore
);
153 } while (error
== B_INTERRUPTED
);
158 bool waitNeeded
= false;
159 if (fTargetThread
> 0) {
160 AutoLocker
< ::Team
> teamLocker(fTeam
);
161 ::Thread
* thread
= fTeam
->ThreadByID(fTargetThread
);
164 else if (thread
->State() != THREAD_STATE_STOPPED
) {
166 fListener
->ThreadActionRequested(fTargetThread
, MSG_THREAD_STOP
);
172 error
= acquire_sem(fShowSemaphore
);
173 } while (error
== B_INTERRUPTED
);
180 if (fReportPath
!= NULL
&& fReportPath
[0] == '/') {
181 error
= get_ref_for_path(fReportPath
, &ref
);
183 char filename
[B_FILE_NAME_LENGTH
];
184 if (fReportPath
!= NULL
)
185 strlcpy(filename
, fReportPath
, sizeof(filename
));
187 UiUtils::ReportNameForTeam(fTeam
, filename
, sizeof(filename
));
190 error
= find_directory(B_DESKTOP_DIRECTORY
, &path
);
192 error
= path
.Append(filename
);
194 error
= get_ref_for_path(path
.Path(), &ref
);
198 printf("Unable to get ref for report path %s\n", strerror(error
));
200 fListener
->DebugReportRequested(&ref
);
203 error
= acquire_sem(fReportSemaphore
);
204 } while (error
== B_INTERRUPTED
);
207 fListener
->UserInterfaceQuitRequested(
208 UserInterfaceListener::QUIT_OPTION_ASK_KILL_TEAM
);
213 ReportUserInterface::ThreadAdded(const Team::ThreadEvent
& event
)
215 ::Thread
* thread
= event
.GetThread();
216 if (thread
->ID() != fTargetThread
)
219 if (thread
->State() != THREAD_STATE_STOPPED
)
220 fListener
->ThreadActionRequested(thread
->ID(), MSG_THREAD_STOP
);
222 release_sem(fShowSemaphore
);
227 ReportUserInterface::ThreadStateChanged(const Team::ThreadEvent
& event
)
229 ::Thread
* thread
= event
.GetThread();
230 if (thread
->ID() != fTargetThread
)
232 else if (thread
->State() == THREAD_STATE_STOPPED
)
233 release_sem(fShowSemaphore
);
238 ReportUserInterface::DebugReportChanged(const Team::DebugReportEvent
& event
)
240 if (event
.GetFinalStatus() == B_OK
)
241 printf("Debug report saved to %s\n", event
.GetReportPath());
243 fprintf(stderr
, "Failed to write debug report: %s\n", strerror(
244 event
.GetFinalStatus()));
246 release_sem(fReportSemaphore
);