DCCHandler.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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 <AppFileInfo.h>
  26. #include <Alert.h>
  27. #include <Button.h>
  28. #include <Directory.h>
  29. #include <FilePanel.h>
  30. #include <Invoker.h>
  31. #include <Path.h>
  32. #include <MessageFilter.h>
  33. #include <stdlib.h>
  34. #include "ClientWindow.h"
  35. #include "ServerAgent.h"
  36. #include "Utilities.h"
  37. #include "Vision.h"
  38. #include "VTextControl.h"
  39. class DCCFileFilter : public BMessageFilter
  40. {
  41. BFilePanel *panel;
  42. BMessage send_msg;
  43. public:
  44. DCCFileFilter (BFilePanel *, const BMessage &);
  45. virtual ~DCCFileFilter (void);
  46. virtual filter_result Filter (BMessage *, BHandler **);
  47. filter_result HandleButton (BMessage *);
  48. filter_result HandleAlert (BMessage *);
  49. };
  50. void
  51. ServerAgent::DCCChatDialog(BString theNick, BString theIP, BString thePort)
  52. {
  53. BString theText(theNick);
  54. theText << S_SERVER_DCC_CHAT_PROMPT;
  55. BAlert *myAlert = new BAlert("DCC request", theText.String(), "Accept",
  56. "Refuse");
  57. myAlert->SetFeel (B_FLOATING_APP_WINDOW_FEEL);
  58. BMessage *myMessage = new BMessage(M_CHAT_ACCEPT);
  59. myMessage->AddString("nick", theNick.String());
  60. myMessage->AddString("ip", theIP.String());
  61. myMessage->AddString("port", thePort.String());
  62. BInvoker *myInvoker = new BInvoker(myMessage, this);
  63. myAlert->Go(myInvoker);
  64. }
  65. const uint32 M_FILE_PANEL_BUTTON = 'Tact';
  66. const uint32 M_FILE_PANEL_ALERT = 'alrt';
  67. void
  68. ServerAgent::DCCGetDialog (
  69. BString nick,
  70. BString file,
  71. BString size,
  72. BString ip,
  73. BString port)
  74. {
  75. BMessage msg (M_DCC_ACCEPT), reply;
  76. msg.AddString ("vision:nick", nick.String());
  77. msg.AddString ("vision:file", file.String());
  78. msg.AddString ("vision:size", size.String());
  79. msg.AddString ("vision:ip", ip.String());
  80. msg.AddString ("vision:port", port.String());
  81. BFilePanel *panel;
  82. BString text;
  83. text << nick
  84. << ": "
  85. << file
  86. << " ("
  87. << size
  88. << " bytes)";
  89. panel = new BFilePanel (
  90. B_SAVE_PANEL,
  91. &fSMsgr,
  92. 0,
  93. 0,
  94. false,
  95. &msg);
  96. panel->SetButtonLabel (B_DEFAULT_BUTTON, "Accept");
  97. panel->SetButtonLabel (B_CANCEL_BUTTON, "Refuse");
  98. panel->SetSaveText (file.String());
  99. BWindow *panelWindow (panel->Window());
  100. if (panelWindow->Lock())
  101. {
  102. panelWindow->SetTitle (text.String());
  103. panelWindow->SetFlags (panelWindow->Flags() | B_AVOID_FOCUS);
  104. panelWindow->AddFilter (new DCCFileFilter (panel, msg));
  105. if (vision_app->GetBool ("dccAutoAccept"))
  106. {
  107. BDirectory path (vision_app->GetString ("dccDefPath"));
  108. if (path.InitCheck() == B_OK)
  109. panel->SetPanelDirectory(&path);
  110. }
  111. if (vision_app->GetBool ("dccAutoAccept"))
  112. {
  113. panelWindow->Hide();
  114. BButton *button (dynamic_cast<BButton *>(panel->Window()->FindView ("default button")));
  115. if (button)
  116. button->Invoke();
  117. }
  118. panelWindow->Unlock();
  119. panel->Show();
  120. // hack trick to ensure that the file panel doesn't take over the keyboard focus
  121. // when it pops up
  122. panelWindow->Lock();
  123. panelWindow->SetFlags (panelWindow->Flags() & ~B_AVOID_FOCUS);
  124. panelWindow->Unlock();
  125. }
  126. }
  127. DCCFileFilter::DCCFileFilter (BFilePanel *p, const BMessage &msg)
  128. : BMessageFilter (B_ANY_DELIVERY, B_ANY_SOURCE),
  129. panel (p),
  130. send_msg (msg)
  131. {
  132. }
  133. DCCFileFilter::~DCCFileFilter (void)
  134. {
  135. }
  136. filter_result
  137. DCCFileFilter::Filter (BMessage *msg, BHandler **)
  138. {
  139. filter_result result (B_DISPATCH_MESSAGE);
  140. switch (msg->what)
  141. {
  142. case M_FILE_PANEL_BUTTON:
  143. {
  144. result = HandleButton (msg);
  145. break;
  146. }
  147. case M_FILE_PANEL_ALERT:
  148. {
  149. result = HandleAlert (msg);
  150. break;
  151. }
  152. case B_QUIT_REQUESTED:
  153. {
  154. //printf ("Panel Quit Requested\n");
  155. break;
  156. }
  157. }
  158. return result;
  159. }
  160. filter_result
  161. DCCFileFilter::HandleButton (BMessage *)
  162. {
  163. filter_result result (B_DISPATCH_MESSAGE);
  164. BTextControl *paneltext (dynamic_cast<BTextControl *>(
  165. panel->Window()->FindView ("text view")));
  166. if (paneltext)
  167. {
  168. BDirectory dir;
  169. struct stat s;
  170. entry_ref ref;
  171. BEntry entry;
  172. panel->GetPanelDirectory (&ref);
  173. dir.SetTo (&ref);
  174. if (entry.SetTo (&dir, paneltext->Text()) == B_NO_ERROR
  175. && entry.GetStat (&s) == B_NO_ERROR
  176. && S_ISREG (s.st_mode))
  177. {
  178. if (vision_app->GetBool ("dccAutoAccept"))
  179. {
  180. BMessage msg (M_FILE_PANEL_ALERT);
  181. msg.AddInt32 ("which", 2);
  182. panel->Window()->PostMessage (&msg);
  183. result = B_SKIP_MESSAGE;
  184. }
  185. else
  186. {
  187. BString buffer;
  188. BAlert *alert;
  189. buffer << "The file \""
  190. << paneltext->Text()
  191. << "\" already exists in the specified folder. "
  192. "Do you want to continue the transfer?";
  193. alert = new BAlert (
  194. "DCC Request",
  195. buffer.String(),
  196. "Cancel",
  197. "Replace",
  198. "Resume",
  199. B_WIDTH_AS_USUAL,
  200. B_OFFSET_SPACING,
  201. B_WARNING_ALERT);
  202. alert->Go (new BInvoker (
  203. new BMessage (M_FILE_PANEL_ALERT),
  204. panel->Window()));
  205. result = B_SKIP_MESSAGE;
  206. }
  207. }
  208. }
  209. return result;
  210. }
  211. filter_result
  212. DCCFileFilter::HandleAlert (BMessage *msg)
  213. {
  214. BTextControl *text (dynamic_cast<BTextControl *>(
  215. panel->Window()->FindView ("text view")));
  216. int32 which;
  217. msg->FindInt32 ("which", &which);
  218. if (which == 0 || text == 0)
  219. {
  220. return B_SKIP_MESSAGE;
  221. }
  222. entry_ref ref;
  223. panel->GetPanelDirectory (&ref);
  224. if (which == 2)
  225. {
  226. BDirectory dir (&ref);
  227. BFile file (&dir, text->Text(), B_READ_ONLY);
  228. BEntry entry (&dir, text->Text());
  229. BPath path;
  230. off_t position;
  231. file.GetSize (&position);
  232. entry.GetPath (&path);
  233. send_msg.AddString ("path", path.Path());
  234. send_msg.AddInt64 ("pos", position);
  235. send_msg.what = M_ADD_RESUME_DATA;
  236. }
  237. else
  238. {
  239. send_msg.AddRef ("directory", &ref);
  240. send_msg.AddString ("name", text->Text());
  241. }
  242. panel->Messenger().SendMessage (&send_msg);
  243. BMessage cmsg (B_CANCEL);
  244. cmsg.AddPointer ("source", panel);
  245. panel->Messenger().SendMessage (&cmsg);
  246. return B_SKIP_MESSAGE;
  247. }