ClientWindow.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. /*
  2. * The contents of this file are subject to the Mozilla Public
  3. * License Version 1.1 (the "License"); you may not use this file
  4. * except in compliance with the License. You may obtain a copy of
  5. * the License at http://www.mozilla.org/MPL/
  6. *
  7. * Software distributed under the License is distributed on an "AS
  8. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9. * implied. See the License for the specific language governing
  10. * rights and limitations under the License.
  11. *
  12. * The Original Code is Vision.
  13. *
  14. * The Initial Developer of the Original Code is The Vision Team.
  15. * Portions created by The Vision Team are
  16. * Copyright (C) 1999, 2000, 2001 The Vision Team. All Rights
  17. * Reserved.
  18. *
  19. * Contributor(s): Wade Majors <wade@ezri.org>
  20. * Rene Gollent
  21. * Todd Lair
  22. * Andrew Bazan
  23. * Jamie Wilkinson
  24. */
  25. #include <ScrollView.h>
  26. #include <Menu.h>
  27. #include <MenuItem.h>
  28. #include <MenuBar.h>
  29. #include <Rect.h>
  30. #include <MessageRunner.h>
  31. #include <Roster.h>
  32. #include <stdio.h>
  33. #include "ChannelAgent.h"
  34. #include "ClientAgent.h"
  35. #include "ClientWindow.h"
  36. #include "ClientWindowDock.h"
  37. #include "IconMenu.h"
  38. #include "ListAgent.h"
  39. #include "Names.h"
  40. #include "NetworkMenu.h"
  41. #include "NotifyList.h"
  42. #include "ResizeView.h"
  43. #include "ServerAgent.h"
  44. #include "SettingsFile.h"
  45. #include "StatusView.h"
  46. #include "Vision.h"
  47. #include "VTextControl.h"
  48. #include "WindowList.h"
  49. /*
  50. -- #beos was here --
  51. <Electroly> kurros has a l33t ass projector, I saw a picture of it just once
  52. and I've been drooling ever since
  53. <T-ball> nice...
  54. <T-ball> I don't have room for a projector... :/
  55. <Brazilian> I have a monkey who draws on my wall really fast
  56. */
  57. #ifdef __HAIKU__
  58. static const char *skTermSig = "application/x-vnd.Haiku-Terminal";
  59. #else
  60. static const char *skTermSig = "application/x-vnd.Be-SHEL";
  61. #endif
  62. //////////////////////////////////////////////////////////////////////////////
  63. /// Begin BWindow functions
  64. //////////////////////////////////////////////////////////////////////////////
  65. // small dynamic menu that sets the enabled/disabled states of its items on the fly when the user invokes it
  66. // needed to correctly show the state of cut/copy/paste/select all
  67. class DynamicEditMenu : public BMenu
  68. {
  69. public:
  70. DynamicEditMenu (void);
  71. virtual ~DynamicEditMenu (void);
  72. virtual void AllAttached (void);
  73. virtual void DetachedFromWindow (void);
  74. };
  75. DynamicEditMenu::DynamicEditMenu(void)
  76. : BMenu (S_CW_EDIT_MENU)
  77. {
  78. }
  79. DynamicEditMenu::~DynamicEditMenu(void)
  80. {
  81. }
  82. void
  83. DynamicEditMenu::AllAttached(void)
  84. {
  85. BMenu::AllAttached();
  86. vision_app->pClientWin()->SetEditStates(false);
  87. }
  88. void
  89. DynamicEditMenu::DetachedFromWindow(void)
  90. {
  91. BMenu::DetachedFromWindow();
  92. for (int32 i = 0; i < CountItems(); i++)
  93. ItemAt(i)->SetEnabled(true);
  94. }
  95. ClientWindow::ClientWindow (BRect frame)
  96. : BWindow (
  97. frame,
  98. "Vision",
  99. B_DOCUMENT_WINDOW,
  100. B_ASYNCHRONOUS_CONTROLS)
  101. {
  102. Init();
  103. }
  104. ClientWindow::~ClientWindow (void)
  105. {
  106. delete fAgentrect;
  107. }
  108. bool
  109. ClientWindow::QuitRequested (void)
  110. {
  111. if (!fShutdown_in_progress)
  112. {
  113. fShutdown_in_progress = true;
  114. BMessage killMsg (M_CLIENT_QUIT);
  115. killMsg.AddBool ("vision:winlist", true);
  116. killMsg.AddBool ("vision:shutdown", fShutdown_in_progress);
  117. if (ServerBroadcast (&killMsg))
  118. fWait_for_quits = true;
  119. if (fWait_for_quits)
  120. return false;
  121. }
  122. be_app_messenger.SendMessage (B_QUIT_REQUESTED);
  123. return true;
  124. }
  125. void
  126. ClientWindow::FrameMoved (BPoint origin)
  127. {
  128. BWindow::FrameMoved (origin);
  129. vision_app->SetRect ("windowDockRect", fCwDock->Bounds());
  130. vision_app->SetRect ("clientWinRect", Frame());
  131. }
  132. void
  133. ClientWindow::FrameResized (float width, float height)
  134. {
  135. BWindow::FrameResized (width, height);
  136. vision_app->SetRect ("windowDockRect", fCwDock->Bounds());
  137. vision_app->SetRect ("clientWinRect", Frame());
  138. }
  139. void
  140. ClientWindow::ScreenChanged (BRect screenframe, color_space mode)
  141. {
  142. // user might have lowered resolution, may need to
  143. // move the window to a visible pos.
  144. if (Frame().top > screenframe.bottom)
  145. MoveTo (Frame().left, 110); // move up
  146. if (Frame().left > screenframe.right)
  147. MoveTo (110, Frame().top); // move left
  148. BWindow::ScreenChanged (screenframe, mode);
  149. }
  150. void
  151. ClientWindow::AddMenu (BMenu *menu)
  152. {
  153. if (menu != NULL)
  154. fMenuBar->AddItem (menu);
  155. }
  156. void
  157. ClientWindow::RemoveMenu (BMenu *menu)
  158. {
  159. if (menu != NULL)
  160. fMenuBar->RemoveItem (menu);
  161. }
  162. void
  163. ClientWindow::MessageReceived (BMessage *msg)
  164. {
  165. switch (msg->what)
  166. {
  167. // this is somewhat annoying but these are needed in addition to the ones in the input filter since the menu items
  168. // can't send the keyboard accelerators and only send the message ; annoying code duplication but oh well
  169. case M_UP_CLIENT:
  170. {
  171. pWindowList()->Select (pWindowList()->CurrentSelection() - 1);
  172. pWindowList()->ScrollToSelection();
  173. }
  174. break;
  175. case M_DOWN_CLIENT:
  176. {
  177. pWindowList()->Select (pWindowList()->CurrentSelection() + 1);
  178. pWindowList()->ScrollToSelection();
  179. }
  180. break;
  181. case M_SMART_UP_CLIENT:
  182. {
  183. pWindowList()->ContextSelectUp();
  184. }
  185. break;
  186. case M_SMART_DOWN_CLIENT:
  187. {
  188. pWindowList()->ContextSelectDown();
  189. }
  190. break;
  191. case M_NETWORK_CLIENT:
  192. {
  193. pWindowList()->SelectServer();
  194. }
  195. break;
  196. case M_PREVIOUS_CLIENT:
  197. {
  198. pWindowList()->SelectLast();
  199. }
  200. break;
  201. case M_NETWORK_UP:
  202. {
  203. pWindowList()->MoveCurrentUp();
  204. }
  205. break;
  206. case M_NETWORK_DOWN:
  207. {
  208. pWindowList()->MoveCurrentDown();
  209. }
  210. break;
  211. case M_COLLAPSE_NETWORK:
  212. {
  213. pWindowList()->CollapseCurrentServer();
  214. }
  215. break;
  216. case M_EXPAND_NETWORK:
  217. {
  218. pWindowList()->ExpandCurrentServer();
  219. }
  220. break;
  221. case M_CW_UPDATE_STATUS:
  222. {
  223. WindowListItem *item (NULL),
  224. *superItem (NULL);
  225. int32 newstatus;
  226. if ((msg->FindPointer ("item", reinterpret_cast<void **>(&item)) != B_OK)
  227. || (msg->FindInt32 ("status", ((int32 *)&newstatus)) != B_OK))
  228. {
  229. printf (":ERROR: no valid pointer and int found in M_CW_UPDATE_STATUS, bailing...\n");
  230. return;
  231. }
  232. superItem = (WindowListItem *)pWindowList()->Superitem(item);
  233. if (superItem && (!superItem->IsExpanded()))
  234. {
  235. int32 srvstatus ((superItem->SubStatus()));
  236. if (srvstatus < newstatus)
  237. superItem->SetSubStatus (newstatus);
  238. }
  239. if (!pWindowList()->FullListHasItem (item))
  240. return;
  241. if (msg->HasBool("hidden"))
  242. {
  243. item->SetStatus (newstatus);
  244. return;
  245. }
  246. if (item->Status() >= newstatus)
  247. return;
  248. else
  249. item->SetStatus (newstatus);
  250. }
  251. break;
  252. case M_STATUS_CLEAR:
  253. {
  254. fStatus->Clear();
  255. SetEditStates(true);
  256. }
  257. break;
  258. case M_OBITUARY:
  259. {
  260. WindowListItem *agentitem;
  261. BView *agentview;
  262. if ((msg->FindPointer ("agent", reinterpret_cast<void **>(&agentview)) != B_OK)
  263. || (msg->FindPointer ("item", reinterpret_cast<void **>(&agentitem)) != B_OK))
  264. {
  265. printf (":ERROR: no valid pointers found in M_OBITUARY, bailing...\n");
  266. return;
  267. }
  268. pWindowList()->RemoveAgent (agentview, agentitem);
  269. if (fShutdown_in_progress && pWindowList()->CountItems() == 0)
  270. PostMessage (B_QUIT_REQUESTED);
  271. }
  272. break;
  273. case M_CW_ALTW:
  274. {
  275. if (!fAltw_catch && vision_app->GetBool ("catchAltW"))
  276. {
  277. fAltw_catch = true;
  278. fAltwRunner = new BMessageRunner (
  279. this,
  280. new BMessage (M_CW_ALTW_RESET),
  281. 400000, // 0.4 seconds
  282. 1);
  283. }
  284. else
  285. PostMessage (B_QUIT_REQUESTED);
  286. }
  287. break;
  288. case M_CW_ALTW_RESET:
  289. {
  290. fAltw_catch = false;
  291. if (fAltwRunner)
  292. delete fAltwRunner;
  293. }
  294. break;
  295. case M_CW_ALTP:
  296. {
  297. pWindowList()->CloseActive();
  298. }
  299. break;
  300. case M_STATE_CHANGE:
  301. {
  302. ServerBroadcast (msg);
  303. }
  304. break;
  305. case M_MAKE_NEW_NETWORK:
  306. {
  307. BMessage network;
  308. msg->FindMessage ("network", &network);
  309. BString netName (network.FindString ("name"));
  310. pWindowList()->AddAgent (
  311. new ServerAgent (netName.String(),
  312. network,
  313. *AgentRect()),
  314. netName.String(),
  315. WIN_SERVER_TYPE,
  316. pWindowList()->CountItems() > 0 ? false : true); // grab focus if none present
  317. }
  318. break;
  319. case M_RESIZE_VIEW:
  320. {
  321. BView *view (NULL);
  322. msg->FindPointer ("view", reinterpret_cast<void **>(&view));
  323. WindowListItem *item (dynamic_cast<WindowListItem *>(pWindowList()->ItemAt (pWindowList()->CurrentSelection())));
  324. BView *agent (item->pAgent());
  325. if (dynamic_cast<ClientWindowDock *>(view))
  326. {
  327. BPoint point;
  328. msg->FindPoint ("loc", &point);
  329. fResize->MoveTo (point.x, fResize->Frame().top);
  330. fCwDock->ResizeTo (point.x - 1, fCwDock->Frame().Height());
  331. BRect *agRect (AgentRect());
  332. if (agent)
  333. {
  334. agent->ResizeTo (agRect->Width(), agRect->Height());
  335. agent->MoveTo (agRect->left, agRect->top);
  336. }
  337. }
  338. else
  339. DispatchMessage (msg, agent);
  340. }
  341. break;
  342. case M_OPEN_TERM:
  343. {
  344. status_t result = be_roster->Launch (skTermSig, 0, NULL);
  345. if (result != B_OK)
  346. {
  347. BMessage errMsg (M_DISPLAY);
  348. BString errString ("Launch failed! Error code: ");
  349. errString << result;
  350. errString += "\n";
  351. ClientAgent::PackDisplay(&errMsg, errString.String(), C_ERROR, C_BACKGROUND, F_TEXT);
  352. WindowListItem *item(dynamic_cast<WindowListItem *>(pWindowList()->ItemAt (pWindowList()->CurrentSelection())));
  353. if (item)
  354. {
  355. BMessenger (item->pAgent()).SendMessage (&errMsg);
  356. }
  357. }
  358. }
  359. break;
  360. case M_LIST_COMMAND:
  361. {
  362. WindowListItem *item ((WindowListItem *)pWindowList()->ItemAt (pWindowList()->CurrentSelection()));
  363. BView *view (NULL);
  364. if (item)
  365. view = item->pAgent();
  366. if ((view == NULL) || (dynamic_cast<ListAgent *>(view) != NULL))
  367. break;
  368. dynamic_cast<ClientAgent *>(view)->ParseCmd ("/LIST");
  369. }
  370. break;
  371. case M_JOIN_CHANNEL:
  372. {
  373. WindowListItem *item ((WindowListItem *)pWindowList()->ItemAt (pWindowList()->CurrentSelection()));
  374. BView *view (NULL);
  375. if (item)
  376. view = item->pAgent();
  377. if ((view == NULL) || (dynamic_cast<ListAgent *>(view) != NULL))
  378. break;
  379. BString cmd;
  380. if (msg->FindString ("channel", &cmd) < B_OK)
  381. break;
  382. cmd.Prepend("/JOIN ");
  383. dynamic_cast<ClientAgent *>(view)->ParseCmd (cmd.String());
  384. // XXX: should select the channel if already joined.
  385. }
  386. break;
  387. case M_NOTIFYLIST_UPDATE:
  388. {
  389. BObjectList<NotifyListItem> *nickList (NULL);
  390. BView *msgSource (NULL);
  391. int32 hasChanged (0);
  392. // whether we're the active one or not, no difference in state, ignore
  393. if (msg->HasInt32 ("change") && (hasChanged = msg->FindInt32("change")) == 0)
  394. break;
  395. msg->FindPointer("source", reinterpret_cast<void **>(&msgSource));
  396. msg->FindPointer("list", reinterpret_cast<void **>(&nickList));
  397. WindowListItem *item ((WindowListItem *)pWindowList()->ItemAt(pWindowList()->CurrentSelection()));
  398. if (item != NULL)
  399. {
  400. if (item->pAgent() == msgSource)
  401. pNotifyList()->UpdateList (nickList);
  402. else
  403. {
  404. item = (WindowListItem *)(pWindowList()->Superitem(item));
  405. if ((item != NULL) && (item->pAgent() == msgSource))
  406. pNotifyList()->UpdateList (nickList);
  407. }
  408. pWindowList()->BlinkNotifyChange(hasChanged, (ServerAgent *)msgSource);
  409. }
  410. }
  411. break;
  412. default:
  413. BWindow::MessageReceived (msg);
  414. }
  415. }
  416. ServerAgent *
  417. ClientWindow::GetTopServer (WindowListItem *request) const
  418. {
  419. ServerAgent *target (NULL);
  420. if (pWindowList()->FullListHasItem (request))
  421. {
  422. // if the item has no super, it is a server agent, return it.
  423. if (pWindowList()->Superitem(request) == NULL)
  424. target = dynamic_cast<ServerAgent *>(request->pAgent());
  425. else
  426. target = dynamic_cast<ServerAgent *>(((WindowListItem *)pWindowList()->Superitem(request))->pAgent());
  427. }
  428. return target;
  429. }
  430. void
  431. ClientWindow::SetEditStates (bool retargetonly)
  432. {
  433. WindowListItem *item (dynamic_cast<WindowListItem *>(pWindowList()->ItemAt(pWindowList()->CurrentSelection())));
  434. if (item != NULL)
  435. {
  436. ClientAgent *agent (dynamic_cast<ClientAgent *>(item->pAgent()));
  437. if (agent != NULL)
  438. agent->SetEditStates(fEdit, retargetonly);
  439. }
  440. }
  441. BRect *
  442. ClientWindow::AgentRect (void) const
  443. {
  444. fAgentrect->left = fResize->Frame().right - fCwDock->Frame().left + 1;
  445. fAgentrect->top = Bounds().top;
  446. fAgentrect->right = Bounds().Width() + 1;
  447. fAgentrect->bottom = fCwDock->Frame().Height();
  448. return fAgentrect;
  449. }
  450. WindowList *
  451. ClientWindow::pWindowList (void) const
  452. {
  453. return fCwDock->pWindowList();
  454. }
  455. NotifyList *
  456. ClientWindow::pNotifyList (void) const
  457. {
  458. return fCwDock->pNotifyList();
  459. }
  460. ClientWindowDock *
  461. ClientWindow::pCwDock (void) const
  462. {
  463. return fCwDock;
  464. }
  465. StatusView *
  466. ClientWindow::pStatusView (void) const
  467. {
  468. return fStatus;
  469. }
  470. /*
  471. -- #beos was here --
  472. <AnEvilYak> regurg, you don't like my monkey??
  473. <regurg> Oh, I don't like your monkey?
  474. <AnEvilYak> regurg: no :( *sob*
  475. <regurg> Why 'no'?
  476. <AnEvilYak> regurg: you tell me
  477. <regurg> What makes you think I tell you?
  478. */
  479. bool
  480. ClientWindow::ServerBroadcast (BMessage *outmsg_) const
  481. {
  482. bool reply (false);
  483. for (int32 i (0); i < pWindowList()->CountItems(); i++)
  484. {
  485. WindowListItem *aitem ((WindowListItem *)pWindowList()->ItemAt (i));
  486. if (aitem->Type() == WIN_SERVER_TYPE)
  487. {
  488. dynamic_cast<ServerAgent *>(aitem->pAgent())->fMsgr.SendMessage (outmsg_);
  489. reply = true;
  490. }
  491. }
  492. return reply;
  493. }
  494. void
  495. ClientWindow::Show(void)
  496. {
  497. // nothing yet
  498. BWindow::Show();
  499. }
  500. //////////////////////////////////////////////////////////////////////////////
  501. /// End BWindow functions
  502. //////////////////////////////////////////////////////////////////////////////
  503. //////////////////////////////////////////////////////////////////////////////
  504. /// Begin Private Functions
  505. //////////////////////////////////////////////////////////////////////////////
  506. void
  507. ClientWindow::Init (void)
  508. {
  509. SetSizeLimits (330,2000,150,2000);
  510. fShutdown_in_progress = false;
  511. fWait_for_quits = false;
  512. fAltw_catch = false;
  513. AddShortcut ('W', B_COMMAND_KEY, new BMessage(M_CW_ALTW));
  514. AddShortcut ('Q', B_COMMAND_KEY, new BMessage(M_CW_ALTW));
  515. BRect frame (Bounds());
  516. fMenuBar = new BMenuBar (frame, "menu_bar");
  517. BMenuItem *item;
  518. BMenu *menu;
  519. // Server menu
  520. menu = new BMenu("App");
  521. menu->AddItem (item = new BMenuItem (S_CW_APP_ABOUT B_UTF8_ELLIPSIS,
  522. new BMessage (B_ABOUT_REQUESTED)));
  523. item->SetTarget (vision_app);
  524. menu->AddItem (item = new BMenuItem (S_CW_APP_PREFS B_UTF8_ELLIPSIS, new BMessage (M_PREFS_SHOW)));
  525. item->SetTarget (vision_app);
  526. menu->AddSeparatorItem();
  527. menu->AddItem (item = new BMenuItem (S_CW_APP_QUIT,
  528. new BMessage (B_QUIT_REQUESTED)));
  529. item->SetTarget (vision_app);
  530. fApp = new TIconMenu (menu);
  531. fMenuBar->AddItem (fApp);
  532. fServer = new BMenu (S_CW_SERVER_MENU);
  533. fServer->AddItem (menu = new NetworkMenu (S_CW_SERVER_CONNECT B_UTF8_ELLIPSIS, M_CONNECT_NETWORK, BMessenger (vision_app)));
  534. fServer->AddItem (item = new BMenuItem (S_CW_SERVER_SETUP B_UTF8_ELLIPSIS,
  535. new BMessage (M_SETUP_SHOW), '/', B_SHIFT_KEY));
  536. item->SetTarget (vision_app);
  537. fServer->AddSeparatorItem();
  538. fServer->AddItem (item = new BMenuItem (S_CW_APP_CHANLIST B_UTF8_ELLIPSIS,
  539. new BMessage (M_LIST_COMMAND), 'L'));
  540. fMenuBar->AddItem (fServer);
  541. // Edit menu
  542. fEdit = new DynamicEditMenu ();
  543. fEdit->AddItem (item = new BMenuItem (S_CW_EDIT_CUT, new BMessage (B_CUT), 'X'));
  544. fEdit->AddItem (item = new BMenuItem (S_CW_EDIT_COPY, new BMessage (B_COPY), 'C'));
  545. fEdit->AddItem (item = new BMenuItem (S_CW_EDIT_PASTE, new BMessage (B_PASTE), 'V'));
  546. fEdit->AddItem (item = new BMenuItem (S_CW_EDIT_SELECT_ALL, new BMessage (B_SELECT_ALL), 'A', B_OPTION_KEY));
  547. fMenuBar->AddItem (fEdit);
  548. // Window menu
  549. fWindow = new BMenu (S_CW_WINDOW_MENU);
  550. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_UP, new BMessage (M_UP_CLIENT), B_UP_ARROW));
  551. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_DOWN, new BMessage (M_DOWN_CLIENT), B_DOWN_ARROW));
  552. // bowser muscle memory
  553. AddShortcut(',', B_COMMAND_KEY, new BMessage (M_UP_CLIENT));
  554. AddShortcut('.', B_COMMAND_KEY, new BMessage (M_DOWN_CLIENT));
  555. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_SM_UP, new BMessage (M_SMART_UP_CLIENT), B_UP_ARROW, B_SHIFT_KEY));
  556. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_SM_DOWN, new BMessage (M_SMART_DOWN_CLIENT), B_DOWN_ARROW, B_SHIFT_KEY));
  557. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_NETWORK, new BMessage (M_NETWORK_CLIENT), '/'));
  558. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_PREVIOUS, new BMessage (M_PREVIOUS_CLIENT), '0', B_SHIFT_KEY));
  559. AddShortcut(B_INSERT, B_SHIFT_KEY, new BMessage (M_PREVIOUS_CLIENT));
  560. fWindow->AddSeparatorItem();
  561. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_NET_UP, new BMessage (M_NETWORK_UP), 'U', B_SHIFT_KEY));
  562. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_NET_DOWN, new BMessage (M_NETWORK_DOWN), 'D', B_SHIFT_KEY));
  563. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_COLLAPSE, new BMessage (M_COLLAPSE_NETWORK), B_LEFT_ARROW));
  564. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_EXPAND, new BMessage (M_EXPAND_NETWORK), B_RIGHT_ARROW));
  565. fWindow->AddSeparatorItem();
  566. fWindow->AddItem (item = new BMenuItem (S_CW_WINDOW_PART, new BMessage (M_CW_ALTP), 'P'));
  567. item->SetTarget (this);
  568. fMenuBar->AddItem (fWindow);
  569. AddChild (fMenuBar);
  570. // add objects
  571. frame.top = fMenuBar->Frame().bottom + 1;
  572. bgView = new BView (frame,
  573. "Background",
  574. B_FOLLOW_ALL_SIDES,
  575. 0);
  576. bgView->SetViewColor (ui_color (B_PANEL_BACKGROUND_COLOR));
  577. AddChild (bgView);
  578. frame = bgView->Bounds();
  579. fStatus = new StatusView (frame);
  580. bgView->AddChild (fStatus);
  581. fStatus->AddItem (new StatusItem (
  582. "irc.elric.net", 0),
  583. true);
  584. BRect cwDockRect (vision_app->GetRect ("windowDockRect"));
  585. fCwDock = new ClientWindowDock (BRect (0, frame.top,
  586. (cwDockRect.Width() == 0.0) ? 130 : cwDockRect.Width(),
  587. fStatus->Frame().top - 1));
  588. bgView->AddChild (fCwDock);
  589. fResize = new ResizeView (fCwDock, BRect (fCwDock->Frame().right + 1,
  590. Bounds().top, fCwDock->Frame().right + 3, fStatus->Frame().top - 1));
  591. bgView->AddChild (fResize);
  592. fAgentrect = new BRect (
  593. (fResize->Frame().right - fCwDock->Frame().left) + 1,
  594. Bounds().top + 1,
  595. Bounds().Width() - 1,
  596. fCwDock->Frame().Height());
  597. }
  598. //////////////////////////////////////////////////////////////////////////////
  599. /// End Private Functions
  600. //////////////////////////////////////////////////////////////////////////////