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