1 /* 2 * Copyright 2016, Rene Gollent, rene@gollent.com. 3 * Distributed under the terms of the MIT License. 4 */ 5 #include "ConnectionConfigWindow.h" 6 7 #include <Application.h> 8 #include <Button.h> 9 #include <GroupView.h> 10 #include <MenuField.h> 11 #include <LayoutBuilder.h> 12 13 #include <AutoDeleter.h> 14 #include <AutoLocker.h> 15 16 #include "AppMessageCodes.h" 17 #include "ConnectionConfigHandlerRoster.h" 18 #include "TargetHostInterfaceInfo.h" 19 #include "TargetHostInterfaceRoster.h" 20 #include "TargetHostInterface.h" 21 22 23 enum { 24 MSG_SWITCH_CONNECTION_TYPE = 'swct', 25 MSG_CREATE_CONNECTION = 'crco' 26 }; 27 28 29 ConnectionConfigWindow::ConnectionConfigWindow() 30 : 31 BWindow(BRect(), "Create new connection", B_TITLED_WINDOW, 32 B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), 33 ConnectionConfigView::Listener(), 34 fConnectionTypeField(NULL), 35 fConfigGroupView(NULL), 36 fCloseButton(NULL), 37 fConnectButton(NULL) 38 { 39 } 40 41 42 ConnectionConfigWindow::~ConnectionConfigWindow() 43 { 44 } 45 46 47 ConnectionConfigWindow* 48 ConnectionConfigWindow::Create() 49 { 50 ConnectionConfigWindow* self = new ConnectionConfigWindow(); 51 52 try { 53 self->_Init(); 54 } catch (...) { 55 delete self; 56 throw; 57 } 58 59 return self; 60 61 } 62 63 64 void 65 ConnectionConfigWindow::Show() 66 { 67 CenterOnScreen(); 68 BWindow::Show(); 69 } 70 71 72 bool 73 ConnectionConfigWindow::QuitRequested() 74 { 75 return be_app_messenger.SendMessage(MSG_CONNECTION_CONFIG_WINDOW_CLOSED) 76 == B_OK; 77 } 78 79 80 void 81 ConnectionConfigWindow::ConfigurationChanged(Settings* settings) 82 { 83 // TODO: implement 84 } 85 86 87 void 88 ConnectionConfigWindow::MessageReceived(BMessage* message) 89 { 90 switch (message->what) { 91 default: 92 BWindow::MessageReceived(message); 93 break; 94 } 95 } 96 97 98 void 99 ConnectionConfigWindow::_Init() 100 { 101 BMenu* menu = _BuildTypeMenu(); 102 103 fConfigGroupView = new BGroupView(B_HORIZONTAL); 104 105 BLayoutBuilder::Group<>(this, B_VERTICAL) 106 .SetInsets(B_USE_DEFAULT_SPACING) 107 .Add(fConnectionTypeField = new BMenuField("Type:", menu)) 108 .AddGroup(fConfigGroupView) 109 // this group is a placeholder to contain 110 // the actual config view 111 .End() 112 .AddGroup(B_HORIZONTAL) 113 .SetInsets(B_USE_SMALL_SPACING) 114 .AddGlue() 115 .Add(fCloseButton = new BButton("Close", 116 new BMessage(B_QUIT_REQUESTED))) 117 .Add(fConnectButton = new BButton("Connect", 118 new BMessage(MSG_CREATE_CONNECTION))) 119 .End(); 120 121 fConnectionTypeField->Menu()->SetLabelFromMarked(true); 122 fConnectionTypeField->Menu()->SetTargetForItems(this); 123 124 fCloseButton->SetTarget(this); 125 fConnectButton->SetTarget(this); 126 fConnectButton->SetEnabled(false); 127 128 if (menu->CountItems() > 0) { 129 BMenuItem* item = menu->ItemAt(0); 130 BMessage* message = item->Message(); 131 TargetHostInterfaceInfo* info = NULL; 132 if (message->FindPointer("info", reinterpret_cast<void**>(&info)) 133 == B_OK) { 134 _UpdateActiveConfig(info); 135 menu->ItemAt(0)->SetMarked(true); 136 } 137 } 138 } 139 140 141 BMenu* 142 ConnectionConfigWindow::_BuildTypeMenu() 143 { 144 BMenu* menu = new BMenu("Types"); 145 TargetHostInterfaceRoster* roster = TargetHostInterfaceRoster::Default(); 146 147 AutoLocker<TargetHostInterfaceRoster> rosterLocker(roster); 148 149 for (int32 i = 0; i < roster->CountInterfaceInfos(); i++) { 150 TargetHostInterfaceInfo* info = roster->InterfaceInfoAt(i); 151 if (info->IsLocal()) 152 continue; 153 154 BMenuItem* item = new BMenuItem(info->Name(), new BMessage( 155 MSG_SWITCH_CONNECTION_TYPE)); 156 item->Message()->AddPointer("info", info); 157 menu->AddItem(item); 158 } 159 160 return menu; 161 } 162 163 164 void 165 ConnectionConfigWindow::_UpdateActiveConfig(TargetHostInterfaceInfo* info) 166 { 167 if (fConfigGroupView->CountChildren() > 0) { 168 BView* view = fConfigGroupView->ChildAt(0); 169 fConfigGroupView->RemoveChild(view); 170 delete view; 171 } 172 173 ConnectionConfigHandlerRoster* roster 174 = ConnectionConfigHandlerRoster::Default(); 175 176 if (roster->HasHandlerFor(info)) { 177 ConnectionConfigView* view = NULL; 178 status_t error = roster->CreateConfigView(info, this, view); 179 if (error != B_OK) 180 return; 181 182 ObjectDeleter<ConnectionConfigView> viewDeleter(view); 183 BLayoutItem* item = fConfigGroupView->GroupLayout()->AddView(view); 184 if (item != NULL) { 185 viewDeleter.Detach(); 186 } 187 } 188 189 fConfigGroupView->InvalidateLayout(); 190 } 191