]> code.citadel.org Git - citadel.git/blob - daphne/main.cpp
further format string cleanups (for i686-linux type sizes)
[citadel.git] / daphne / main.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        main.cpp
3 // Purpose:     Main screen type thing
4 // Version:     $Id$
5 /////////////////////////////////////////////////////////////////////////////
6
7 // ============================================================================
8 // declarations
9 // ============================================================================
10
11 #include "includes.hpp"
12
13 #ifdef __WXMOTIF__
14 #include "/usr/local/share/bitmaps/globe.xpm"
15 #include "/usr/local/share/bitmaps/mail.xpm"
16 #include "/usr/local/share/bitmaps/who.xpm"
17 #include "/usr/local/share/bitmaps/chat.xpm"
18 #include "/usr/local/share/bitmaps/xglobe.xpm"
19 #include "/usr/local/share/bitmaps/goto.xpm"
20 #endif
21
22
23 // Globals
24 wxMDIParentFrame *BigMDI;
25 RoomTree *RoomList;
26 wxConfig *ini;
27
28 // ----------------------------------------------------------------------------
29 // private classes
30 // ----------------------------------------------------------------------------
31
32 // Define a new application type, each program should derive a class from wxApp
33 class Daphne : public wxApp
34 {
35 public:
36     // override base class virtuals
37     // ----------------------------
38
39     // this one is called on application startup and is a good place for the app
40     // initialization (doing it here and not in the ctor allows to have an error
41     // return: if OnInit() returns false, the application terminates)
42     virtual bool OnInit();
43 };
44
45 // Define a new frame type: this is going to be our main frame
46 class MyFrame : public wxMDIParentFrame
47 {
48 public:
49     // constructor(s)
50     MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
51
52         // event handlers (these functions should _not_ be virtual)
53         void OnQuit(wxCommandEvent& event);
54         void OnAbout(wxCommandEvent& event);
55         void OnDoCmd(wxCommandEvent& event);
56         void GotoNewRoom(wxTreeEvent& event);
57         void DoTerm(wxCommandEvent& event);
58 private:
59         void OnConnect(wxCommandEvent& event);
60         void OnGotoMail(wxCommandEvent& event);
61         void OnTestWin(wxCommandEvent& event);
62         void OnEditMenu(wxCommandEvent& cmd);
63         void OnUsersMenu(wxCommandEvent& cmd);
64         void OnRoomsMenu(wxCommandEvent& cmd);
65 /*      void OnDoChat(wxCommandEvent& event); */
66         void MyFrame::OnSize(wxSizeEvent& event);
67         wxButton *do_cmd;
68         void InitToolBar(wxToolBar* toolBar);
69
70         who *TheWholist;
71
72         // any class wishing to process wxWindows events must use this macro
73         DECLARE_EVENT_TABLE()
74 };
75
76 // ----------------------------------------------------------------------------
77 // constants
78 // ----------------------------------------------------------------------------
79
80 // IDs for the controls and the menu commands
81 enum
82 {
83         DO_NOTHING,
84         IG_Quit,
85         IG_Term,
86         IG_About,
87         IG_Text,
88         MENU_CONNECT,
89         MENU_TESTWIN,
90         EMENU_PREFS,
91         EMENU_HOSTS,
92         UMENU_WHO,
93         UMENU_SEND_EXPRESS,
94         RMENU_GOTO,
95         BUTTON_DO_CMD,
96         ROOMTREE_DOUBLECLICK,
97         GOTO_MAIL
98 };
99
100 // ----------------------------------------------------------------------------
101 // event tables and other macros for wxWindows
102 // ----------------------------------------------------------------------------
103
104 // the event tables connect the wxWindows events with the functions (event
105 // handlers) which process them. It can be also done at run-time, but for the
106 // simple menu events like this the static method is much simpler.
107 BEGIN_EVENT_TABLE(      MyFrame, wxMDIParentFrame)
108 /*      EVT_MENU(       IG_Chat,                MyFrame::OnDoChat)*/
109         EVT_MENU(       IG_Quit,                MyFrame::OnQuit)
110         EVT_MENU(       IG_Term,                MyFrame::DoTerm)
111         EVT_MENU(       IG_About,               MyFrame::OnAbout)
112         EVT_MENU(       MENU_CONNECT,           MyFrame::OnConnect)
113         EVT_MENU(       EMENU_PREFS,            MyFrame::OnEditMenu)
114         EVT_MENU(       EMENU_HOSTS,            MyFrame::OnEditMenu)
115         EVT_MENU(       GOTO_MAIL,              MyFrame::OnGotoMail)
116         EVT_MENU(       MENU_TESTWIN,           MyFrame::OnTestWin)
117         EVT_MENU(       UMENU_WHO,              MyFrame::OnUsersMenu)
118         EVT_MENU(       UMENU_SEND_EXPRESS,     MyFrame::OnUsersMenu)
119         EVT_MENU(       RMENU_GOTO,             MyFrame::OnRoomsMenu)
120         EVT_BUTTON(     BUTTON_DO_CMD,          MyFrame::OnDoCmd)
121         EVT_SIZE(                               MyFrame::OnSize)
122 END_EVENT_TABLE()
123
124 // Create a new application object: this macro will allow wxWindows to create
125 // the application object during program execution (it's better than using a
126 // static object for many reasons) and also declares the accessor function
127 // wxGetApp() which will return the reference of the right type (i.e. Daphne
128 // and not wxApp)
129 IMPLEMENT_APP(Daphne)
130
131 // ============================================================================
132 // implementation
133 // ============================================================================
134
135 wxRadioBox *DevSelect;
136 wxSlider *ndims;
137 CitClient *citadel;
138
139 // ----------------------------------------------------------------------------
140 // the application class
141 // ----------------------------------------------------------------------------
142
143 // `Main program' equivalent: the program execution "starts" here
144 bool Daphne::OnInit()
145 {
146         int w, h;
147         wxString sizestr;
148
149         // Read the configuration file
150         ini = new wxConfig("daphne");
151         ini->SetRecordDefaults(TRUE);
152         ini->Read("/Window Sizes/Main", &sizestr, "789 451");
153         sscanf((const char *)sizestr, "%d %d", &w, &h);
154
155
156         // Connect to the server
157         citadel = new CitClient();
158
159         // Create the main application window
160         MyFrame *frame = new MyFrame("Daphne",
161                                  wxPoint(10, 10), wxSize(w, h));
162         BigMDI = frame;
163
164         // Show it and tell the application that it's our main window
165         // @@@ what does it do exactly, in fact? is it necessary here?
166         SetTopWindow(frame);
167
168         // success: wxApp::OnRun() will be called which will enter the main
169         // message loop and the application will run. If we returned FALSE
170         // here, the application would exit immediately.
171         return TRUE;
172 }
173
174 // ----------------------------------------------------------------------------
175 // main frame
176 // ----------------------------------------------------------------------------
177
178 // frame constructor
179 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
180        : wxMDIParentFrame(
181                 (wxMDIParentFrame *)NULL,
182                 -1,
183                 title, pos, size, wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL
184                 ) {
185         wxString buf;
186
187         TheWholist = NULL;
188
189
190         // Set up the left-side thingie
191
192         RoomList = new RoomTree(this, citadel);
193
194         // Set up the toolbar
195
196         CreateToolBar(wxNO_BORDER|wxTB_FLAT|wxTB_HORIZONTAL);
197         InitToolBar(GetToolBar());
198
199
200         // Set up the pulldown menus
201
202         wxMenu *menuFile = new wxMenu;
203         menuFile->Append(MENU_CONNECT, "&Connect");
204         menuFile->Append(MENU_TESTWIN, "Add &Test window");
205         menuFile->AppendSeparator(); 
206         menuFile->Append(IG_Term, "&Disconnect");
207         menuFile->Append(IG_Quit, "E&xit");
208
209
210         wxMenu *menuEdit = new wxMenu;
211         menuEdit->Append(EMENU_PREFS, "&Preferences...");
212         menuEdit->Append(EMENU_HOSTS, "&BBSes to log into");
213         wxMenu *menuUsers = new wxMenu;
214         menuUsers->Append(UMENU_WHO, "&Who is online?");
215         menuUsers->Append(UMENU_SEND_EXPRESS, "&Page another user");
216
217         wxMenu *menuRooms = new wxMenu;
218         menuRooms->Append(RMENU_GOTO, "&Goto next room with unread messages");
219
220         wxMenu *menuHelp = new wxMenu;
221         menuHelp->Append(IG_About, "&About...");
222
223         // now append the freshly created menu to the menu bar...
224         wxMenuBar *menuBar = new wxMenuBar;
225         menuBar->Append(menuFile, "&File");
226         menuBar->Append(menuEdit, "&Edit");
227         menuBar->Append(menuUsers, "&Users");
228         menuBar->Append(menuRooms, "&Rooms");
229         menuBar->Append(menuHelp, "&Help");
230
231         // ... and attach this menu bar to the frame
232         SetMenuBar(menuBar);
233
234         // Create the status bar
235         CreateStatusBar(3);
236         SetStatusText("Not connected", 0);
237
238         Show(TRUE);
239
240         wxYield();
241         ini->Read("/Citadel Server/ConnectOnStartup", &buf, "no");
242         if (!buf.CmpNoCase("yes")) {
243                 wxCommandEvent cjunk;
244                 OnConnect(cjunk);
245         }
246 }
247
248
249
250 // The toolbar for this application.
251 void MyFrame::InitToolBar(wxToolBar* toolBar) {
252         int i;
253         wxBitmap* bitmaps[6];
254
255 // wxGTK seems to do the right thing by itself, while wxMSW wants to be
256 // told how big the toolbar icons are going to be, otherwise it defaults to
257 // 16x16.  Strangely, wxToolBar::SetToolBitmapSize() doesn't seem to be
258 // available at all in wxGTK, hence the ifdef...
259 #ifndef __WXGTK__
260         toolBar->SetToolBitmapSize(wxSize(32, 32));
261 #endif
262
263         // Set up the toolbar icons (BMP is available on both GTK and MSW) 
264 #ifdef __WXMSW__
265         bitmaps[0] = new wxBitmap("globe", wxBITMAP_TYPE_BMP_RESOURCE);
266         bitmaps[1] = new wxBitmap("mail", wxBITMAP_TYPE_BMP_RESOURCE);
267         bitmaps[2] = new wxBitmap("who", wxBITMAP_TYPE_BMP_RESOURCE);
268         bitmaps[3] = new wxBitmap("chat", wxBITMAP_TYPE_BMP_RESOURCE);
269         bitmaps[4] = new wxBitmap("xglobe", wxBITMAP_TYPE_BMP_RESOURCE);
270         bitmaps[5] = new wxBitmap("goto", wxBITMAP_TYPE_BMP_RESOURCE);
271 #elif !defined(__WXMOTIF__)
272         bitmaps[0] = new wxBitmap("/usr/local/share/bitmaps/globe.bmp", wxBITMAP_TYPE_BMP);
273         bitmaps[1] = new wxBitmap("/usr/local/share/bitmaps/mail.bmp", wxBITMAP_TYPE_BMP);
274         bitmaps[2] = new wxBitmap("/usr/local/share/bitmaps/who.bmp", wxBITMAP_TYPE_BMP);
275         bitmaps[3] = new wxBitmap("/usr/local/share/bitmaps/chat.bmp", wxBITMAP_TYPE_BMP);
276         bitmaps[4] = new wxBitmap("/usr/local/share/bitmaps/xglobe.bmp", wxBITMAP_TYPE_BMP);
277         bitmaps[5] = new wxBitmap("/usr/local/share/bitmaps/goto.bmp", wxBITMAP_TYPE_BMP);
278 #else
279         bitmaps[0] = new wxBitmap(globe_xpm);
280         bitmaps[1] = new wxBitmap(mail_xpm);
281         bitmaps[2] = new wxBitmap(who_xpm);
282         bitmaps[3] = new wxBitmap(chat_xpm);
283         bitmaps[4] = new wxBitmap(xglobe_xpm);
284         bitmaps[5] = new wxBitmap(goto_xpm);
285 #endif
286
287         toolBar->AddTool(MENU_CONNECT,
288                         *bitmaps[0],
289                         wxNullBitmap,
290                         FALSE,
291                         -1, -1,
292                         (wxObject *)NULL,
293                         "The WORLD!!");
294                         
295         toolBar->AddSeparator();
296
297         toolBar->AddTool(GOTO_MAIL,
298                         *bitmaps[1],
299                         wxNullBitmap,
300                         FALSE,
301                         -1, -1,
302                         (wxObject *)NULL,
303                         "Open your e-mail inbox");
304                         
305         toolBar->AddTool(RMENU_GOTO,
306                         *bitmaps[5],
307                         wxNullBitmap,
308                         FALSE,
309                         -1, -1,
310                         (wxObject *)NULL,
311                         "Goto next room");
312
313         toolBar->AddSeparator();
314
315         toolBar->AddTool(UMENU_WHO,
316                         *bitmaps[2],
317                         wxNullBitmap,
318                         FALSE,
319                         -1, -1,
320                         (wxObject *)NULL,
321                         "Who is online?");
322                         
323         toolBar->AddTool(DO_NOTHING,
324                         *bitmaps[3],
325                         wxNullBitmap,
326                         FALSE,
327                         -1, -1,
328                         (wxObject *)NULL,
329                         "Real-time chat"); 
330                         
331         toolBar->AddTool(IG_Term,
332                         *bitmaps[4],
333                         wxNullBitmap,
334                         FALSE,
335                         -1, -1,
336                         (wxObject *)NULL,
337                         "Disconnect");
338
339         toolBar->Realize();
340
341         for (i = 0; i < 5; i++)
342                 delete bitmaps[i];
343 }
344
345
346
347
348
349 // Event handlers.
350 // We really could handle all menu items in one function, but that would
351 // get kind of confusing, so we break it down by top-level menus.
352
353 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
354 {
355         // Kill the client connection
356         citadel->detach();
357
358         // TRUE is to force the frame to close
359         Close(TRUE);
360
361         cleanup(0);
362 }
363
364 /* // IG_Chat
365
366 void MyFrame::OnDoChat(wxCommandEvent& unused) {
367         new ChatWindow(citadel, this);
368         sendcmd="CHAT";
369 }*/
370
371 // doterm(terminate session)
372
373 void MyFrame::DoTerm(wxCommandEvent& WXUNUSED(event))
374 {
375
376         // Kill the client connection and don't destroy Daphne
377         citadel->detach();
378         BigMDI->SetStatusText("Not connected", 0);      
379         RoomList->DeleteAllItems();
380         BigMDI->SetStatusText("", 1);
381         BigMDI->SetStatusText("", 2);
382  }
383  
384
385
386 // Edit menu handler
387 void MyFrame::OnEditMenu(wxCommandEvent& cmd) {
388         int id;
389         id = cmd.GetId();
390         if (id == EMENU_PREFS) {
391                 new Preferences(citadel, this);
392         }
393         else if (id == EMENU_HOSTS) {
394                 new Hosts(citadel, this);
395         }
396 }
397
398
399
400 // User menu handler
401 void MyFrame::OnUsersMenu(wxCommandEvent& cmd) {
402         int id;
403         
404         id = cmd.GetId();
405         if (id == UMENU_WHO) {
406                 if (citadel->IsConnected()==FALSE) {
407                 wxMessageBox("You are not connected to a BBS.");
408         } else 
409
410                 //if (TheWholist == NULL)
411                         TheWholist = new who(citadel, this);
412                 //else
413                         //TheWholist->Activate();
414         }
415         else if (id == UMENU_SEND_EXPRESS)
416                         if (citadel->IsConnected()==FALSE) {
417                 wxMessageBox("You are not connected to a BBS.");
418         } else 
419
420                 new SendExpress(citadel, this, "");
421 }
422
423
424 // Rooms menu handler
425 void MyFrame::OnRoomsMenu(wxCommandEvent& cmd) {
426         int id;
427         
428         id = cmd.GetId();
429         if (id == RMENU_GOTO) {
430                         if (citadel->IsConnected()==FALSE) {
431                 wxMessageBox("You are not connected to a BBS.");
432         } else
433                 new RoomView(citadel, this, RoomList->GetNextRoom());
434         }
435 }
436
437
438 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
439 {
440         wxString msg;
441         msg.Printf(
442           "This is the development version of a project code-named 'Daphne',\n"
443           "a GUI client for the Citadel/UX groupware system.  It is being\n"
444           "developed using the wxWindows toolkit, and therefore should be\n"
445           "easy to port to Linux, Windows, and eventually Macintosh."
446           );
447         wxMessageBox(msg, "Daphne", wxOK | wxICON_INFORMATION, this);
448 }
449
450 void MyFrame::OnDoCmd(wxCommandEvent& whichbutton) {
451 }
452
453
454 void MyFrame::OnConnect(wxCommandEvent& unused) {
455         int retval;
456         wxString DefaultHost, DefaultPort;
457
458         ini->Read("/Citadel Server/Host", &DefaultHost, DEFAULT_HOST);
459         ini->Read("/Citadel Server/Port", &DefaultPort, DEFAULT_PORT);
460
461         if (citadel->IsConnected()) {
462                 wxMessageBox("You are currently connected to "
463                         + citadel->HumanNode
464                         + ".  If you wish to connect to a different Citadel "
465                         + "server, you must log out first.",
466                         "Already connected");
467         } else {
468                 retval = citadel->attach(DefaultHost, DefaultPort);
469                 if (retval == 0) {
470                         SetStatusText("Connected to " + citadel->HumanNode, 0);
471                         new UserLogin(citadel, this);
472                 } else {
473                         wxMessageBox("Could not connect to server.", "Error");
474                 }
475         }
476 }
477
478 void MyFrame::OnGotoMail(wxCommandEvent& unused) {
479         if (citadel->IsConnected()==FALSE) {
480         wxMessageBox("You are not connected to a BBS.");
481
482         } else
483         new RoomView(citadel, this, "_MAIL_");
484         }
485
486 void MyFrame::OnTestWin(wxCommandEvent& unused) {
487         new TestWindow(citadel, this);
488 /*      sendcmd="CHAT"; */
489 }
490
491 void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event) )
492 {
493         int w, h;
494         wxString sw, sh;
495
496         // Handle the MDI and roomlist crap
497         GetClientSize(&w, &h);
498         RoomList->SetSize(0, 0, 200, h);
499         GetClientWindow()->SetSize(200, 0, w - 200, h);
500
501         // Remember the size of the window from session to session
502         GetSize(&w, &h);
503         sw.Printf("%d %d", w, h);
504         ini->Write("/Window Sizes/Main", sw);
505 }