1 /* 2 * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. 3 * Copyright 2013-2016, Rene Gollent, rene@gollent.com. 4 * Distributed under the terms of the MIT License. 5 */ 6 #include "TeamsWindow.h" 7 8 9 #include <new> 10 11 #include <stdio.h> 12 #include <string.h> 13 #include <stdarg.h> 14 15 #include <Application.h> 16 #include <Button.h> 17 #include <File.h> 18 #include <FilePanel.h> 19 #include <FindDirectory.h> 20 #include <LayoutBuilder.h> 21 #include <ListView.h> 22 #include <Path.h> 23 #include <Screen.h> 24 #include <ScrollView.h> 25 26 #include "MessageCodes.h" 27 #include "SettingsManager.h" 28 #include "TargetHostInterface.h" 29 #include "TargetHostInterfaceRoster.h" 30 #include "TeamsListView.h" 31 32 33 enum { 34 MSG_TEAM_SELECTION_CHANGED = 'tesc', 35 MSG_CHOSE_CORE_FILE = 'chcf' 36 }; 37 38 39 TeamsWindow::TeamsWindow(SettingsManager* settingsManager) 40 : 41 BWindow(BRect(100, 100, 500, 250), "Teams", B_DOCUMENT_WINDOW, 42 B_ASYNCHRONOUS_CONTROLS), 43 fTargetHostInterface(NULL), 44 fTeamsListView(NULL), 45 fAttachTeamButton(NULL), 46 fCreateTeamButton(NULL), 47 fLoadCoreButton(NULL), 48 fCoreSelectionPanel(NULL), 49 fSettingsManager(settingsManager) 50 { 51 team_info info; 52 get_team_info(B_CURRENT_TEAM, &info); 53 fCurrentTeam = info.team; 54 } 55 56 57 TeamsWindow::~TeamsWindow() 58 { 59 } 60 61 62 /*static*/ TeamsWindow* 63 TeamsWindow::Create(SettingsManager* settingsManager) 64 { 65 TeamsWindow* self = new TeamsWindow(settingsManager); 66 67 try { 68 self->_Init(); 69 } catch (...) { 70 delete self; 71 throw; 72 } 73 74 return self; 75 } 76 77 78 void 79 TeamsWindow::Zoom(BPoint, float, float) 80 { 81 BSize preferredSize = fTeamsListView->PreferredSize(); 82 ResizeBy(preferredSize.Width() - Bounds().Width(), 83 0.0); 84 85 // if the new size would extend us past the screen border, 86 // move sufficiently to the left to bring us back within the bounds 87 // + a bit of extra margin so we're not flush against the edge. 88 BScreen screen; 89 float offset = screen.Frame().right - Frame().right; 90 if (offset < 0) 91 MoveBy(offset - 5.0, 0.0); 92 } 93 94 95 void 96 TeamsWindow::MessageReceived(BMessage* message) 97 { 98 switch (message->what) { 99 case MSG_DEBUG_THIS_TEAM: 100 { 101 TeamRow* row = dynamic_cast<TeamRow*>( 102 fTeamsListView->CurrentSelection()); 103 if (row != NULL) { 104 BMessage message(MSG_DEBUG_THIS_TEAM); 105 message.AddInt32("team", row->TeamID()); 106 message.AddPointer("interface", fTargetHostInterface); 107 be_app_messenger.SendMessage(&message); 108 } 109 break; 110 } 111 112 case MSG_TEAM_SELECTION_CHANGED: 113 { 114 TeamRow* row = dynamic_cast<TeamRow*>( 115 fTeamsListView->CurrentSelection()); 116 bool enabled = false; 117 if (row != NULL) { 118 team_id id = row->TeamID(); 119 if (id != fCurrentTeam && id != B_SYSTEM_TEAM) 120 enabled = true; 121 } 122 123 fAttachTeamButton->SetEnabled(enabled); 124 break; 125 } 126 127 case MSG_SHOW_START_TEAM_WINDOW: 128 { 129 BMessage startMessage(*message); 130 startMessage.AddPointer("interface", fTargetHostInterface); 131 be_app_messenger.SendMessage(&startMessage); 132 break; 133 } 134 135 case MSG_CHOSE_CORE_FILE: 136 case B_CANCEL: 137 { 138 delete fCoreSelectionPanel; 139 fCoreSelectionPanel = NULL; 140 if (message->what == B_CANCEL) 141 break; 142 143 entry_ref ref; 144 if (message->FindRef("refs", &ref) != B_OK) 145 break; 146 147 BMessage coreMessage(MSG_LOAD_CORE_TEAM); 148 coreMessage.AddPointer("interface", fTargetHostInterface); 149 coreMessage.AddRef("core", &ref); 150 be_app_messenger.SendMessage(&coreMessage); 151 break; 152 } 153 154 case MSG_LOAD_CORE_TEAM: 155 { 156 try { 157 BMessenger messenger(this); 158 fCoreSelectionPanel = new BFilePanel(B_OPEN_PANEL, &messenger, 159 NULL, 0, false, new BMessage(MSG_CHOSE_CORE_FILE)); 160 fCoreSelectionPanel->Show(); 161 } catch (...) { 162 delete fCoreSelectionPanel; 163 fCoreSelectionPanel = NULL; 164 } 165 break; 166 } 167 168 default: 169 BWindow::MessageReceived(message); 170 break; 171 } 172 } 173 174 175 bool 176 TeamsWindow::QuitRequested() 177 { 178 _SaveSettings(); 179 180 be_app_messenger.SendMessage(MSG_TEAMS_WINDOW_CLOSED); 181 return true; 182 } 183 184 185 // #pragma mark -- 186 187 188 void 189 TeamsWindow::_Init() 190 { 191 BMessage settings; 192 _LoadSettings(settings); 193 194 fTargetHostInterface = TargetHostInterfaceRoster::Default() 195 ->ActiveInterfaceAt(0); 196 197 BRect frame; 198 if (settings.FindRect("teams window frame", &frame) == B_OK) { 199 MoveTo(frame.LeftTop()); 200 ResizeTo(frame.Width(), frame.Height()); 201 } 202 203 BLayoutBuilder::Group<>(this, B_VERTICAL) 204 .Add(fTeamsListView = new TeamsListView("TeamsList", fCurrentTeam, 205 fTargetHostInterface)) 206 .SetInsets(1.0f, 1.0f, 1.0f, 5.0f) 207 .AddGroup(B_HORIZONTAL) 208 .SetInsets(B_USE_DEFAULT_SPACING) 209 .Add(fAttachTeamButton = new BButton("Attach", new BMessage( 210 MSG_DEBUG_THIS_TEAM))) 211 .AddGlue() 212 .Add(fCreateTeamButton = new BButton("Start new team" 213 B_UTF8_ELLIPSIS, new BMessage(MSG_SHOW_START_TEAM_WINDOW))) 214 .Add(fLoadCoreButton = new BButton("Load core" B_UTF8_ELLIPSIS, 215 new BMessage(MSG_LOAD_CORE_TEAM))) 216 .End() 217 .End(); 218 219 fTeamsListView->SetInvocationMessage(new BMessage(MSG_DEBUG_THIS_TEAM)); 220 fTeamsListView->SetSelectionMessage(new BMessage( 221 MSG_TEAM_SELECTION_CHANGED)); 222 223 fAttachTeamButton->SetEnabled(false); 224 fCreateTeamButton->SetTarget(this); 225 fLoadCoreButton->SetTarget(this); 226 } 227 228 229 status_t 230 TeamsWindow::_OpenSettings(BFile& file, uint32 mode) 231 { 232 BPath path; 233 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 234 return B_ERROR; 235 236 path.Append("Debugger settings"); 237 238 return file.SetTo(path.Path(), mode); 239 } 240 241 242 status_t 243 TeamsWindow::_LoadSettings(BMessage& settings) 244 { 245 BFile file; 246 status_t status = _OpenSettings(file, B_READ_ONLY); 247 if (status < B_OK) 248 return status; 249 250 return settings.Unflatten(&file); 251 } 252 253 254 status_t 255 TeamsWindow::_SaveSettings() 256 { 257 BFile file; 258 status_t status = _OpenSettings(file, 259 B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); 260 261 if (status < B_OK) 262 return status; 263 264 BMessage settings('hdbg'); 265 status = settings.AddRect("teams window frame", Frame()); 266 if (status != B_OK) 267 return status; 268 269 if (status == B_OK) 270 status = settings.Flatten(&file); 271 272 return status; 273 } 274