daphne: main.o citclient.o userlogin.o testwindow.o who.o \
utils.o express_message.o send_express.o prefs.o \
- roomtree.o roomview.o tcp_sockets.o message.o enter.o
+ roomtree.o roomview.o tcp_sockets.o message.o enter.o \
+ selectuser.o servprops.o
c++ main.o citclient.o userlogin.o testwindow.o who.o \
utils.o express_message.o send_express.o prefs.o \
roomtree.o roomview.o tcp_sockets.o message.o enter.o \
+ selectuser.o servprops.o \
$(LFLAGS) -o daphne
clean:
enum {
BUTTON_SAVE,
- BUTTON_CANCEL
+ BUTTON_CANCEL,
+ BUTTON_FIND
};
BEGIN_EVENT_TABLE(EnterMessage, wxMDIChildFrame)
EVT_BUTTON(BUTTON_CANCEL, EnterMessage::OnCancel)
EVT_BUTTON(BUTTON_SAVE, EnterMessage::OnSave)
+ EVT_BUTTON(BUTTON_FIND, EnterMessage::OnFind)
END_EVENT_TABLE()
citsock = sock;
citMyMDI = MyMDI;
ThisRoom = roomname;
+ finduser_panel = (SelectUser *) NULL;
wxButton *cancel_button = new wxButton(
this,
c9->height.AsIs();
toname->SetConstraints(c9);
- wxButton *findrecp = new wxButton(this, -1, " Find ");
+ wxButton *findrecp = new wxButton(
+ this,
+ BUTTON_FIND,
+ " Find "
+ );
wxLayoutConstraints *d1 = new wxLayoutConstraints;
d1->centreY.SameAs(toname, wxCentreY);
}
+// The user clicked "Find" ... so we have to go looking for a recipient.
+// Shove a FindUser panel right in front of everything else.
+//
+void EnterMessage::OnFind(wxCommandEvent& whichbutton) {
+ finduser_panel = new SelectUser(citsock, this,
+ "Please select a recipient",
+ "Recipients",
+ 0,
+ toname);
+
+ wxLayoutConstraints *f1 = new wxLayoutConstraints;
+ f1->centreX.SameAs(this, wxCentreX);
+ f1->centreY.SameAs(this, wxCentreY);
+ f1->width.SameAs(this, wxWidth);
+ f1->height.SameAs(this, wxHeight);
+ finduser_panel->SetConstraints(f1);
+ Layout();
+}
+
+
void EnterMessage::OnSave(wxCommandEvent& whichbutton) {
wxString sendcmd, recvcmd, xferbuf;
+// Global server properties
+
+class ServProps : public wxMDIChildFrame {
+public:
+ ServProps( CitClient *sock,
+ wxMDIParentFrame *MyMDI,
+ wxString WhichPanel);
+ void ChangePanel(wxString WhichPanel);
+private:
+ void OnButtonPressed(wxCommandEvent& whichbutton);
+ CitClient *citsock;
+ wxMDIParentFrame *citMyMDI;
+ wxPanel *identity_panel, *network_panel, *security_panel;
+ wxString ServerConfigStrings[20];
+ void LoadServerConfigStrings(void);
+ void SaveServerConfigStrings(void);
+ DECLARE_EVENT_TABLE()
+};
+
+
+
// The ever-present tree of floors and rooms
class RoomTree : public wxTreeCtrl {
wxTreeItemId floorboards[MAXFLOORS];
wxImageList *TreeIcons;
wxTreeItemId march_next;
+ ServProps *CurrServProps;
DECLARE_EVENT_TABLE()
};
};
+class SelectUser : public wxPanel {
+public:
+ SelectUser(CitClient *, wxWindow *, wxString,
+ wxString, unsigned int, wxTextCtrl *);
+private:
+ void OnButtonPressed(wxCommandEvent& whichbutton);
+ void AddLocalUsers(wxTreeCtrl *, CitClient *);
+ wxButton select_button;
+ wxButton cancel_button;
+ CitClient *citsock;
+ wxTextCtrl *target_textctrl;
+ wxTreeCtrl *TheTree;
+ DECLARE_EVENT_TABLE()
+};
+
+
+
class EnterMessage : public wxMDIChildFrame {
public:
EnterMessage(CitClient *sock, wxMDIParentFrame *MyMDI,
private:
void OnCancel(wxCommandEvent& whichbutton);
void OnSave(wxCommandEvent& whichbutton);
+ void OnFind(wxCommandEvent& whichbutton);
CitClient *citsock;
wxMDIParentFrame *citMyMDI;
wxString ThisRoom;
wxChoice *fromname;
wxTextCtrl *toname;
wxTextCtrl *TheMessage;
+ SelectUser *finduser_panel;
DECLARE_EVENT_TABLE()
};
-
-
// Stuff from utils.cpp
void extract(wxString& outputbuf, wxString inputbuf, int parmnum);
{
BUTTON_SAVE,
BUTTON_CANCEL,
- TAB_SERVER,
- TAB_MESSAGES
};
// ----------------------------------------------------------------------------
wxTreeItemId null_item;
+enum {
+ RI_NOTHING,
+ RI_ROOM,
+ RI_SERVPROPS
+};
+
class RoomItem : public wxTreeItemData {
public:
- RoomItem(wxString name, bool newmsgs);
+ RoomItem(wxString name, bool newmsgs, int typ);
wxString RoomName;
bool HasNewMessages;
wxTreeItemId nextroom;
+ int NodeType;
};
-RoomItem::RoomItem(wxString name, bool newmsgs)
+RoomItem::RoomItem(wxString name, bool newmsgs, int typ)
: wxTreeItemData() {
RoomName = name;
HasNewMessages = newmsgs;
nextroom = null_item;
+ NodeType = typ;
}
citsock = sock;
citMyMDI = parent;
+ CurrServProps = NULL;
InitTreeIcons();
}
roomname,
2,
-1,
- new RoomItem(roomname, TRUE)
+ new RoomItem(roomname, TRUE, RI_ROOM)
);
SetItemBold(item, TRUE);
SetItemBold(floorboards[floornum], TRUE);
roomname,
3,
-1,
- new RoomItem(roomname, FALSE)
+ new RoomItem(roomname, FALSE, RI_ROOM)
);
}
+ wxTreeItemId sp = AppendItem(
+ GetRootItem(),
+ "Global settings",
+ -1,
+ -1,
+ new RoomItem("Global settings", FALSE, RI_NOTHING)
+ );
+
+ AppendItem(sp, "Identity",
+ -1,
+ -1,
+ new RoomItem("Identity", FALSE, RI_SERVPROPS)
+ );
+
+ AppendItem(sp, "Network",
+ -1,
+ -1,
+ new RoomItem("Network", FALSE, RI_SERVPROPS)
+ );
+
+ AppendItem(sp, "Security",
+ -1,
+ -1,
+ new RoomItem("Security", FALSE, RI_SERVPROPS)
+ );
+
// Demo of traversal -- do not use
// while (march_next != null_item) {
// wxTreeItemId foo = GetNextRoomId();
itemId = GetSelection();
- // Don't do this unless it's a *room* the user clicked on.
+ // Don't do this unless it's a leaf node the user clicked on.
if (itemId == GetRootItem()) return;
for (i=0; i<MAXFLOORS; ++i)
if (itemId == floorboards[i]) return;
- // Ok, it's a room, so go there.
+ // Ok, it's a leaf node...
r = (RoomItem *)GetItemData(itemId);
- new RoomView(citsock, citMyMDI, r->RoomName);
+ switch (r->NodeType) {
+
+ case RI_ROOM:
+ new RoomView(citsock, citMyMDI, r->RoomName);
+ break;
+
+ case RI_SERVPROPS:
+ if (CurrServProps == NULL) {
+ CurrServProps = new ServProps(
+ citsock, citMyMDI, r->RoomName);
+ } else {
+ CurrServProps->ChangePanel(r->RoomName);
+ }
+ break;
+
+ }
}
wxString RoomTree::GetNextRoom(void) {
roomname
) {
- wxString sendcmd, recvcmd;
+ wxString sendcmd, recvcmd, xferbuf, buf;
citsock = sock;
citMyMDI = MyMDI;
banner = new wxPanel(this, -1);
banner->SetBackgroundColour(wxColour(0x00, 0x00, 0x77));
banner->SetForegroundColour(wxColour(0xFF, 0xFF, 0x00));
+
wxLayoutConstraints *b1 = new wxLayoutConstraints;
b1->top.SameAs(this, wxTop, 2);
b1->left.SameAs(this, wxLeft, 2);
wxStaticText *rname = new wxStaticText(banner, -1, ThisRoom);
rname->SetFont(wxFont(18, wxDEFAULT, wxNORMAL, wxNORMAL));
rname->SetForegroundColour(wxColour(0xFF, 0xFF, 0x00));
+
wxLayoutConstraints *b2 = new wxLayoutConstraints;
b2->top.SameAs(banner, wxTop, 1);
b2->left.SameAs(banner, wxLeft, 1);
b2->height.PercentOf(banner, wxHeight, 50);
rname->SetConstraints(b2);
+ wxHtmlWindow *roominfo = new wxHtmlWindow(banner);
+
+ wxLayoutConstraints *b3 = new wxLayoutConstraints;
+ b3->top.SameAs(banner, wxTop);
+ b3->bottom.SameAs(banner, wxBottom);
+ b3->right.SameAs(banner, wxRight);
+ b3->left.PercentOf(banner, wxWidth, 67);
+ roominfo->SetConstraints(b3);
+
close_button = new wxButton(
this,
BUTTON_CLOSE,
Layout();
wxYield();
+
+ sendcmd = "RINF";
+ if (citsock->serv_trans(sendcmd, recvcmd, xferbuf, ThisRoom) == 1) {
+ variformat_to_html(buf, xferbuf, FALSE);
+ } else {
+ buf = " ";
+ }
+
+ wxString hbuf;
+ hbuf = "<HTML><BODY TEXT=#FFFF00 BGCOLOR=#000077>";
+ hbuf += "<FONT SIZE=-1>";
+ hbuf += buf;
+ hbuf += "</FONT></BODY></HTML>";
+ roominfo->SetPage(hbuf);
+
do_readloop("MSGS NEW"); // FIX make this configurable
}
--- /dev/null
+// ============================================================================
+// declarations
+// ============================================================================
+
+#include "includes.hpp"
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+
+
+class ReturnedUser : public wxTreeItemData {
+public:
+ ReturnedUser(wxString);
+ wxString emailaddr;
+};
+
+ReturnedUser::ReturnedUser(wxString e) {
+ emailaddr = e;
+}
+
+
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// IDs for the controls and the menu commands
+enum
+{
+ BUTTON_SENDCMD,
+ BUTTON_CLOSE,
+ THE_TREE
+};
+
+
+// ----------------------------------------------------------------------------
+// event tables and other macros for wxWindows
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE( SelectUser, wxPanel)
+ EVT_BUTTON( BUTTON_SENDCMD, SelectUser::OnButtonPressed)
+ EVT_BUTTON( BUTTON_CLOSE, SelectUser::OnButtonPressed)
+END_EVENT_TABLE()
+
+//BEGIN_EVENT_TABLE(thisclassname, wxTreeCtrl)
+// EVT_TREE_ITEM_ACTIVATED(THE_TREE, SelectUser::OnTreeClick)
+//END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+
+// ----------------------------------------------------------------------------
+// the application class
+// ----------------------------------------------------------------------------
+
+// frame constructor
+SelectUser::SelectUser(CitClient *sock, wxWindow *the_parent,
+ wxString caption,
+ wxString rootlabel,
+ unsigned int flags,
+ wxTextCtrl *PlaceToPutTheSelection)
+ : wxPanel(the_parent, -1) {
+
+ citsock = sock;
+ target_textctrl = PlaceToPutTheSelection;
+
+ TheTree = new wxTreeCtrl(
+ this,
+ THE_TREE,
+ wxDefaultPosition, wxDefaultSize,
+ wxTR_HAS_BUTTONS | wxSUNKEN_BORDER
+ );
+
+ wxStaticText *caption_ctrl = new wxStaticText(this, -1, caption);
+ wxLayoutConstraints *c0 = new wxLayoutConstraints;
+ c0->left.SameAs(this, wxLeft, 5);
+ c0->top.SameAs(this, wxTop, 5);
+ c0->width.AsIs();
+ c0->height.AsIs();
+ caption_ctrl->SetConstraints(c0);
+
+ wxButton *select_button = new wxButton(
+ this,
+ BUTTON_SENDCMD,
+ " Select "
+ );
+
+ wxButton *cancel_button = new wxButton(
+ this,
+ BUTTON_CLOSE,
+ " Cancel "
+ );
+
+ wxLayoutConstraints *c5 = new wxLayoutConstraints;
+ c5->left.SameAs(this, wxLeft, 5);
+ c5->bottom.SameAs(this, wxBottom, 5);
+ c5->width.AsIs();
+ c5->height.AsIs();
+ select_button->SetConstraints(c5);
+
+ wxLayoutConstraints *c6 = new wxLayoutConstraints;
+ c6->right.SameAs(this, wxRight, 5);
+ c6->bottom.SameAs(this, wxBottom, 5);
+ c6->width.AsIs();
+ c6->height.AsIs();
+ cancel_button->SetConstraints(c6);
+
+ wxLayoutConstraints *c1 = new wxLayoutConstraints;
+ c1->top.Below(caption_ctrl, 5);
+ c1->bottom.Above(select_button, -5);
+ c1->left.SameAs(this, wxLeft, 5);
+ c1->right.SameAs(this, wxRight, 5);
+ TheTree->SetConstraints(c1);
+
+ SetAutoLayout(TRUE);
+ Show(TRUE);
+ Layout();
+ wxYield();
+
+ // Load up the tree with some STUFF
+ TheTree->AddRoot(
+ rootlabel,
+ -1, // FIX put an image here
+ -1, // FIX same image
+ NULL // No data here, it's only a heading
+ );
+
+ // Add local users to the tree (this is probably always going to be
+ // desired, so there's no need for a flag)
+ AddLocalUsers(TheTree, citsock);
+}
+
+
+
+void SelectUser::OnButtonPressed(wxCommandEvent& whichbutton) {
+
+ if (whichbutton.GetId()==BUTTON_CLOSE) {
+ delete this;
+ }
+ else if (whichbutton.GetId()==BUTTON_SENDCMD) {
+ ReturnedUser *u = (ReturnedUser *)
+ TheTree->GetItemData(TheTree->GetSelection());
+ if ( (u != NULL) && (target_textctrl != NULL) ) {
+ target_textctrl->SetValue(u->emailaddr);
+ delete this;
+ }
+ }
+}
+
+
+void SelectUser::AddLocalUsers(wxTreeCtrl *tree, CitClient *cit) {
+ wxString sendcmd;
+ wxString recvcmd;
+ wxString xferbuf;
+ wxStringTokenizer *ul;
+ wxString buf, username;
+
+ sendcmd = "LIST";
+ if (citsock->serv_trans(sendcmd, recvcmd, xferbuf) != 1) return;
+
+ wxTreeItemId localusers = tree->AppendItem(
+ tree->GetRootItem(),
+ cit->HumanNode,
+ -1, // FIX put an image here
+ -1, // FIX and here
+ NULL // No data here either. It's a heading.
+ );
+
+ ul = new wxStringTokenizer(xferbuf, "\n", FALSE);
+ while (ul->HasMoreToken()) {
+ buf = ul->NextToken();
+ extract(username, buf, 0);
+ tree->AppendItem(
+ localusers,
+ username,
+ -1, // FIX img
+ -1, // FIX img
+ new ReturnedUser(username)
+ );
+ }
+}
+
+
--- /dev/null
+// =========================================================================
+// declarations
+// =========================================================================
+
+#include "includes.hpp"
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// IDs for the controls and the menu commands
+enum {
+ BUTTON_SAVE,
+ BUTTON_CANCEL,
+};
+
+// ----------------------------------------------------------------------------
+// event tables and other macros for wxWindows
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(ServProps, wxMDIChildFrame)
+ EVT_BUTTON(BUTTON_SAVE, ServProps::OnButtonPressed)
+ EVT_BUTTON(BUTTON_CANCEL, ServProps::OnButtonPressed)
+END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// frame constructor
+ServProps::ServProps(CitClient * sock,
+ wxMDIParentFrame * MyMDI,
+ wxString WhichPanel)
+ :wxMDIChildFrame(MyMDI, //parent
+ -1, //window id
+ " Server properties ",
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL,
+ "ServProps"
+)
+{
+
+ wxString buf;
+
+ citsock = sock;
+ citMyMDI = MyMDI;
+
+ // set the frame icon
+ /* SetIcon(wxICON(mondrian)); */
+
+ wxButton *save_button = new wxButton(
+ this,
+ BUTTON_SAVE,
+ "Save",
+ wxPoint(200, 200),
+ wxSize(100, 30),
+ 0L,
+ wxDefaultValidator,
+ "save_button"
+ );
+
+ wxButton *cancel_button = new wxButton(
+ this,
+ BUTTON_CANCEL,
+ "Cancel",
+ wxPoint(300, 300),
+ wxSize(100, 30),
+ 0L,
+ wxDefaultValidator,
+ "cancel_button"
+ );
+
+ wxLayoutConstraints *c1 = new wxLayoutConstraints;
+ c1->bottom.SameAs(this, wxBottom, 5);
+ c1->left.SameAs(this, wxLeft, 10);
+ c1->height.AsIs();
+ c1->width.AsIs();
+ save_button->SetConstraints(c1);
+
+ wxLayoutConstraints *c3 = new wxLayoutConstraints;
+ c3->bottom.SameAs(save_button, wxBottom);
+ c3->right.SameAs(this, wxRight, 10);
+ c3->height.AsIs();
+ c3->width.AsIs();
+ cancel_button->SetConstraints(c3);
+
+ identity_panel = new wxPanel(this, -1);
+ network_panel = new wxPanel(this, -1);
+ security_panel = new wxPanel(this, -1);
+
+ wxLayoutConstraints *c4 = new wxLayoutConstraints;
+ c4->top.SameAs(this, wxTop);
+ c4->left.SameAs(this, wxLeft);
+ c4->right.SameAs(this, wxRight);
+ c4->bottom.Above(cancel_button, -5);
+
+ wxLayoutConstraints *c41 = new wxLayoutConstraints;
+ memcpy(c41, c4, sizeof(wxLayoutConstraints));
+
+ wxLayoutConstraints *c42 = new wxLayoutConstraints;
+ memcpy(c42, c4, sizeof(wxLayoutConstraints));
+
+ identity_panel->SetConstraints(c4);
+ network_panel->SetConstraints(c41);
+ security_panel->SetConstraints(c42);
+
+ wxStaticText *ip_label = new wxStaticText(
+ identity_panel, -1, "Server identity");
+ wxStaticText *np_label = new wxStaticText(
+ network_panel, -1, "Network presence");
+ wxStaticText *sp_label = new wxStaticText(
+ security_panel, -1, "Global security settings");
+
+ wxLayoutConstraints *c5 = new wxLayoutConstraints;
+ c5->top.SameAs(network_panel, wxTop, 3);
+ c5->left.SameAs(network_panel, wxLeft, 3);
+ c5->right.SameAs(network_panel, wxRight, 3);
+ c5->height.AsIs();
+
+ ip_label->SetConstraints(c5);
+ //np_label->SetConstraints(c5);
+ //sp_label->SetConstraints(c5);
+
+ SetAutoLayout(TRUE);
+ Show(TRUE);
+ LoadServerConfigStrings();
+ Layout();
+ wxYield();
+ ChangePanel(WhichPanel);
+}
+
+
+void ServProps::ChangePanel(wxString WhichPanel)
+{
+ identity_panel->Show(!WhichPanel.CmpNoCase("Identity") ? TRUE : FALSE);
+ network_panel->Show(!WhichPanel.CmpNoCase("Network") ? TRUE : FALSE);
+ security_panel->Show(!WhichPanel.CmpNoCase("Security") ? TRUE : FALSE);
+ Layout();
+ wxYield();
+}
+
+
+void ServProps::OnButtonPressed(wxCommandEvent & whichbutton)
+{
+ switch (whichbutton.GetId()) {
+ case BUTTON_CANCEL:
+ delete this;
+ break;
+ case BUTTON_SAVE:
+ SaveServerConfigStrings();
+ delete this;
+ break;
+ }
+}
+
+
+void ServProps::LoadServerConfigStrings()
+{
+ int i;
+ wxString sendcmd, recvcmd, xferbuf;
+
+ for (i=0; i<20; ++i)
+ ServerConfigStrings[i].Empty();
+
+ // Make the window go away if this command fails.
+ // Most likely we mistakenly got here without first checking for
+ // the proper access level.
+ sendcmd = "CONF get";
+ if (citsock->serv_trans(sendcmd, recvcmd, xferbuf) != 1)
+ delete this;
+
+ wxStringTokenizer *cl = new wxStringTokenizer(xferbuf, "\n", FALSE);
+ i = 0;
+ while ((i<20) && (cl->HasMoreToken())) {
+ ServerConfigStrings[i++] = cl->NextToken();
+ }
+}
+
+
+void ServProps::SaveServerConfigStrings()
+{
+ int i;
+ wxString sendcmd, recvcmd, xferbuf;
+
+ xferbuf = "";
+ for (i=0; i<20; ++i) {
+ xferbuf += ServerConfigStrings[i];
+ xferbuf += "\n";
+ }
+
+ sendcmd = "CONF set";
+ if (citsock->serv_trans(sendcmd, recvcmd, xferbuf) != 4) {
+ wxMessageDialog errmsg(this,
+ recvcmd.Mid(4),
+ "Error",
+ wxOK | wxCENTRE | wxICON_INFORMATION,
+ wxDefaultPosition);
+ errmsg.ShowModal();
+ }
+}
+
c8->bottom.Above(cmd_button, -5);
xfercmd->SetConstraints(c8);
+ cmd_button->SetDefault();
SetAutoLayout(TRUE);
Show(TRUE);
Layout();
void who::LoadWholist(void) {
wxString sendcmd, recvcmd, buf;
wxString rwho;
- int i, pos;
+ int i = 0;
wxString sess, user, room, host;
wxStringTokenizer *wl;
wholist->SetItem(i, 1, user);
wholist->SetItem(i, 2, room);
wholist->SetItem(i, 3, host);
+ ++i;
}
}