From d9e97187f53201ae200731a0503448c04acec988 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 10 Jun 2014 19:10:53 -0400 Subject: [PATCH] Debugger: Add file prompt hook to UserInterface. In some circumstances, it may be necessary to ask the user to locate a file from the lower layers. Adds the corresponding hook to UserInterface, and a stub implementation for CommandLineUserInterface. Adds full implementation for GraphicalUserInterface. --- src/apps/debugger/MessageCodes.h | 5 +- .../debugger/user_interface/UserInterface.h | 5 +- .../cli/CommandLineUserInterface.cpp | 9 +- .../cli/CommandLineUserInterface.h | 3 +- .../gui/GraphicalUserInterface.cpp | 148 +++++++++++++++++- .../gui/GraphicalUserInterface.h | 8 + 6 files changed, 172 insertions(+), 6 deletions(-) diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index e0efd00331..ab6d8c55ea 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -72,7 +72,10 @@ enum { MSG_SHOW_WATCH_VARIABLE_PROMPT = 'swvp', MSG_SHOW_CONTAINER_RANGE_PROMPT = 'scrp', MSG_SET_CONTAINER_RANGE = 'chcr', - MSG_GENERATE_DEBUG_REPORT = 'gdrp' + MSG_GENERATE_DEBUG_REPORT = 'gdrp', + + MSG_DEBUG_INFO_NEEDS_USER_INPUT = 'dnui', + MSG_USER_INTERFACE_FILE_CHOSEN = 'uifc' }; diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index cb00459c6d..67fa804b8f 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2013, Rene Gollent, rene@gollent.com. + * Copyright 2013-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef USER_INTERFACE_H @@ -67,6 +67,9 @@ public: = 0; // returns -1, if not implemented or user // cannot be asked + + virtual status_t SynchronouslyAskUserForFile(entry_ref* _ref) + = 0; }; diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp index ab2c8379f8..33a467fdb1 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -201,6 +201,13 @@ CommandLineUserInterface::SynchronouslyAskUser(const char* title, } +status_t +CommandLineUserInterface::SynchronouslyAskUserForFile(entry_ref* _ref) +{ + return B_UNSUPPORTED; +} + + void CommandLineUserInterface::Run() { diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h index 12d479c3b6..b89e634047 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ @@ -43,6 +43,7 @@ public: virtual int32 SynchronouslyAskUser(const char* title, const char* message, const char* choice1, const char* choice2, const char* choice3); + virtual status_t SynchronouslyAskUserForFile(entry_ref* _ref); void Run(); // Called by the main thread, when diff --git a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp index 136c72138f..9fd2c6cbc1 100644 --- a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp +++ b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2011, Rene Gollent, rene@gollent.com. + * Copyright 2011-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -8,16 +8,127 @@ #include "GraphicalUserInterface.h" #include +#include +#include +#include #include "GuiTeamUiSettings.h" +#include "MessageCodes.h" #include "TeamWindow.h" #include "Tracing.h" +// #pragma mark - GraphicalUserInterface::FilePanelHandler + + +class GraphicalUserInterface::FilePanelHandler : public BHandler { +public: + FilePanelHandler(); + virtual ~FilePanelHandler(); + + status_t Init(); + + virtual void MessageReceived(BMessage* message); + + status_t WaitForPanel(); + + void SetCurrentRef(entry_ref* ref); + + BLocker& Locker() + { return fPanelLock; } + +private: + entry_ref* fCurrentRef; + BLocker fPanelLock; + sem_id fPanelWaitSem; +}; + + +GraphicalUserInterface::FilePanelHandler::FilePanelHandler() + : + BHandler("GuiPanelHandler"), + fCurrentRef(NULL), + fPanelLock(), + fPanelWaitSem(-1) +{ +} + + +GraphicalUserInterface::FilePanelHandler::~FilePanelHandler() +{ + if (fPanelWaitSem >= 0) + delete_sem(fPanelWaitSem); +} + + +status_t +GraphicalUserInterface::FilePanelHandler::Init() +{ + fPanelWaitSem = create_sem(0, "FilePanelWaitSem"); + + if (fPanelWaitSem < 0) + return fPanelWaitSem; + + return B_OK; +} + + +void +GraphicalUserInterface::FilePanelHandler::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_USER_INTERFACE_FILE_CHOSEN: + { + entry_ref ref; + if (message->FindRef("refs", &ref) == B_OK + && fCurrentRef != NULL) { + *fCurrentRef = ref; + fCurrentRef = NULL; + } + // fall through + } + + case B_CANCEL: + { + release_sem(fPanelWaitSem); + break; + } + + default: + BHandler::MessageReceived(message); + break; + } +} + + +status_t +GraphicalUserInterface::FilePanelHandler::WaitForPanel() +{ + status_t result = B_OK; + do { + result = acquire_sem(fPanelWaitSem); + } while (result == B_INTERRUPTED); + + return result; +} + + +void +GraphicalUserInterface::FilePanelHandler::SetCurrentRef(entry_ref* ref) +{ + fCurrentRef = ref; +} + + +// #pragma mark - GraphicalUserInterface + + GraphicalUserInterface::GraphicalUserInterface() : fTeamWindow(NULL), - fTeamWindowMessenger(NULL) + fTeamWindowMessenger(NULL), + fFilePanelHandler(NULL), + fFilePanel(NULL) { } @@ -25,6 +136,7 @@ GraphicalUserInterface::GraphicalUserInterface() GraphicalUserInterface::~GraphicalUserInterface() { delete fTeamWindowMessenger; + delete fFilePanel; } @@ -41,6 +153,13 @@ GraphicalUserInterface::Init(Team* team, UserInterfaceListener* listener) try { fTeamWindow = TeamWindow::Create(team, listener); fTeamWindowMessenger = new BMessenger(fTeamWindow); + fFilePanelHandler = new FilePanelHandler(); + status_t error = fFilePanelHandler->Init(); + if (error != B_OK) { + ERROR("Error: Failed to create file panel semaphore!\n"); + return error; + } + fTeamWindow->AddHandler(fFilePanelHandler); // start the message loop fTeamWindow->Hide(); @@ -132,3 +251,28 @@ GraphicalUserInterface::SynchronouslyAskUser(const char* title, return 0; return alert->Go(); } + + +status_t +GraphicalUserInterface::SynchronouslyAskUserForFile(entry_ref* _ref) +{ + BAutolock lock(&fFilePanelHandler->Locker()); + + if (fFilePanel == NULL) { + BMessenger messenger(fFilePanelHandler); + BMessage* message = new(std::nothrow) BMessage( + MSG_USER_INTERFACE_FILE_CHOSEN); + if (message == NULL) + return B_NO_MEMORY; + ObjectDeleter messageDeleter(message); + fFilePanel = new(std::nothrow) BFilePanel(B_OPEN_PANEL, + &messenger, NULL, B_FILE_NODE, false, message); + if (fFilePanel == NULL) + return B_NO_MEMORY; + messageDeleter.Detach(); + } + + fFilePanelHandler->SetCurrentRef(_ref); + fFilePanel->Show(); + return fFilePanelHandler->WaitForPanel(); +} diff --git a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h index 60b7d5b415..ef79cfd160 100644 --- a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h +++ b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef GRAPHICAL_USER_INTERFACE_H @@ -9,6 +10,8 @@ #include "UserInterface.h" +class BFilePanel; +class BHandler; class BMessenger; class TeamWindow; @@ -36,10 +39,15 @@ public: virtual int32 SynchronouslyAskUser(const char* title, const char* message, const char* choice1, const char* choice2, const char* choice3); + virtual status_t SynchronouslyAskUserForFile(entry_ref* _ref); +private: + class FilePanelHandler; private: TeamWindow* fTeamWindow; BMessenger* fTeamWindowMessenger; + FilePanelHandler* fFilePanelHandler; + BFilePanel* fFilePanel; };