1 /**
2 * Channel
3 *
4 * Represents a channel which is a collection
5 * of the channel name the users list widget,
6 * the title widget and the chat list box widget
7 * along with the input box state
8 */
9 
10 module areas.Channel;
11 
12 import gtk.Box;
13 import gtk.ListBox;
14 import gtk.Label;
15 import gtk.TextView;
16 import libdnet.client;
17 import gtk.Label;
18 import std.string;
19 import gtk.Button;
20 import gtk.Tooltip;
21 import gtk.Widget;
22 import gtk.ScrolledWindow;
23 import gtk.Button;
24 import gtk.Entry;
25 import UserNode;
26 
27 import pango.PgAttributeList;
28 import pango.PgAttribute;
29 import Connection;
30 
31 import gogga;
32 import areas.MessageArea;
33 
34 public final class Channel : MessageArea
35 {
36     private DClient client;
37     private Connection connection;
38 
39     /**
40     * Channel details
41     */
42     private string channelName;
43 
44     /**
45     * UI components
46     *
47     * Users's box
48     *    - Label users
49     *    - ListBox users
50     */
51     private ListBox users;
52     private ListBox textArea;
53     private Entry textInput;
54 
55     /* TODO: No mutexes should be needed (same precaution) as the GTK lock provides safety */
56     private string[] usersString;
57 
58     this(Connection connection, string channelName)
59     {
60         this.client = connection.getClient();
61         this.connection = connection;
62         this.channelName = channelName;
63         
64         initializeBox();
65     }
66 
67     private void initializeBox()
68     {
69         box = new Box(GtkOrientation.HORIZONTAL, 1);
70 
71         /* The user's box */
72         Box userBox = new Box(GtkOrientation.VERTICAL, 1);
73 
74         /* The user's list */
75         users = new ListBox();
76 
77         userBox.add(new Label("Users"));
78 
79         // import gtk.Expander;
80         // Expander g = new Expander("Bruh");
81         // g.setExpanded(true)
82         // g.add(users);
83         userBox.add(users);
84         
85         /* The text box */
86         Box textBox = new Box(GtkOrientation.VERTICAL, 1);
87 
88         /* Channel title */
89         Label channelTitleLabel = new Label(channelName);
90         channelTitleLabel.setMarkup("<span size=\"large\"><b>"~channelName~"</b></span>");
91         textBox.add(channelTitleLabel);
92 
93         /* The messages box */
94         textArea = new ListBox();
95         ScrolledWindow scrollTextChats = new ScrolledWindow(textArea);
96         textBox.add(scrollTextChats);
97         
98 
99         /* The Box for the whole |attach button| text field| send button| */
100         Box textInputBox = new Box(GtkOrientation.HORIZONTAL, 1);
101 
102         import gtk.Image;
103 
104         /* The attachment button */
105         Button attachFileButton = new Button("Upload");
106         Image attachFileButtonIcon = new Image("user-available", GtkIconSize.BUTTON); /* TODO: Fix icon now showing */
107         attachFileButton.setImage(attachFileButtonIcon);
108         attachFileButton.addOnClicked(&uploadFileDialog);
109         textInputBox.add(attachFileButton);
110 
111         /* The text input */
112         textInput = new Entry();
113         textInput.addOnActivate(&sendMessageEnter);
114         textInput.addOnChanged(&textChangd);
115         
116         textInputBox.packStart(textInput,1,1,0);
117         
118 
119         /* The send button */
120         Button sendButton = new Button("Send");
121         sendButton.addOnClicked(&sendMessageBtn);
122         textInputBox.add(sendButton);
123         textBox.add(textInputBox);
124         
125         box.add(textBox);
126         box.packEnd(userBox,0,0,0);
127 
128         textBox.setChildPacking(scrollTextChats, true, true, 0, GtkPackType.START);
129         box.setChildPacking(textBox, true, true, 0, GtkPackType.START);
130 
131     }
132 
133     private void uploadFileDialog(Button e)
134     {
135         import gtk.FileChooserDialog; /* TODO: Set parent */
136         FileChooserDialog fileChooser = new FileChooserDialog("Send file to "~channelName, null, FileChooserAction.OPEN);
137         fileChooser.run();
138         gprintln("Selected file: "~fileChooser.getFilename());
139     }
140 
141     import gtk.EditableIF;
142     private void textChangd(EditableIF)
143     {
144         /* If the text box just became empty stop ssending typing notifications */
145         /* Send typing stats */
146         // client.sendIsTyping(channelName, true);
147         /* TODO: Client implement wiht different tag? */
148     }
149 
150     private void sendMessageEnter(Entry)
151     {
152         /* Retrieve the message */
153         string message = textInput.getBuffer().getText();
154 
155         /* TODO: Add the message to our log (as it won't be delivered to us) */
156         sendMessage(message);
157 
158         /* Send the message */
159         client.sendMessage(0, channelName, message);
160 
161         /* Clear the text box */
162         textInput.getBuffer().setText("",0);
163 
164         box.showAll();
165     }
166 
167     private void sendMessageBtn(Button)
168     {
169         /* Retrieve the message */
170         string message = textInput.getBuffer().getText();
171 
172         /* TODO: Add the message to our log (as it won't be delivered to us) */
173         sendMessage(message);
174 
175         /* Send the message */
176         client.sendMessage(0, channelName, message);
177 
178         /* Clear the text box */
179         textInput.getBuffer().setText("",0);
180 
181         box.showAll();
182     }
183 
184     public string getName()
185     {
186         return channelName;
187     }
188 
189     
190 
191 
192     private Box getUserListItem(string username)
193     {
194         /* This is an item for a username in this Channel's user list */
195         Box box = new Box(GtkOrientation.HORIZONTAL, 1);
196 
197 
198         import gtk.IconView;
199         IconView icon = new IconView();
200         import gtk.StatusIcon;
201         StatusIcon d = new StatusIcon("user-available");
202 
203         return box;
204     }
205 
206 
207     // private bool userLabelPopup(Widget)
208     // {
209     //     import std.stdio;
210     //     writeln("NOWNOWNOWNOWNOW");
211 
212     //     return true;
213     // }
214 
215     
216 
217 
218     public void populateUsersList()
219     {
220         string[] memberList = client.getMembers(channelName);
221 
222         foreach(string member; memberList)
223         {
224             /* Create the user entry in the list */
225             UserNode userNode = new UserNode(connection, member);
226             users.add(userNode.getBox());
227 
228             /* Add the user to the tracking list */
229             usersString~=member;
230         }
231     }
232 
233    
234 
235 
236    
237     public void channelJoin(string username)
238     {
239         /* The label to add */
240         Label joinLabel = new Label("--> "~username~" joined the channel");
241         joinLabel.setHalign(GtkAlign.START);
242         PgAttributeList joinLabelAttrs = new PgAttributeList();
243         PgAttribute joinLabelAttr = PgAttribute.styleNew(PangoStyle.ITALIC);
244         joinLabelAttrs.insert(joinLabelAttr);
245         joinLabel.setAttributes(joinLabelAttrs);
246 
247         /* Add join message to message log */
248         textArea.add(joinLabel);
249 
250         /* Create the user entry in the list */
251         UserNode userNode = new UserNode(connection, username);
252         users.add(userNode.getBox());
253 
254         /* Add the user to the tracking list */
255         usersString~=username;
256     }
257 
258     public void channelLeave(string username)
259     {
260         /* The label to add */
261         Label leaveLabel = new Label("<-- "~username~" left the channel");
262         leaveLabel.setHalign(GtkAlign.START);
263         PgAttributeList leaveLabelAttrs = new PgAttributeList();
264         PgAttribute leaveLabelAttr = PgAttribute.styleNew(PangoStyle.ITALIC);
265         leaveLabelAttrs.insert(leaveLabelAttr);
266         leaveLabel.setAttributes(leaveLabelAttrs);
267 
268         /* Add leave message to message log */
269         textArea.add(leaveLabel);
270 
271         /* TODO: Better way with just removing one dude */
272         
273         /* Remove the user form users list */
274         string[] newUsers;
275 
276         foreach(string currentUser; usersString)
277         {
278             if(cmp(currentUser, username))
279             {
280                 newUsers ~= currentUser;
281             }
282         }
283 
284         usersString = newUsers;
285 
286         /* Clear list */
287         users.removeAll();
288 
289         foreach(string currentUser; usersString)
290         {
291             /* Create the user entry in the list */
292             UserNode userNode = new UserNode(connection, currentUser);
293             users.add(userNode.getBox());
294         }
295     }
296 
297     public void sendMessage(string message)
298     {
299         /* TOOD: Pass in connection perhaps */
300         string username = "Yourself";
301 
302         /* Create the MessageBox */
303         Box messageBox = new Box(GtkOrientation.VERTICAL, 1);
304 
305         /* Create and add the username */
306         Label usernameLabel = new Label("");
307         usernameLabel.setMarkup("<b>"~username~"</b>");
308         usernameLabel.setHalign(GtkAlign.END);
309         messageBox.add(usernameLabel);
310 
311         /* Create and add the message */
312         Label messageLabel = new Label(message);
313         messageLabel.setHalign(GtkAlign.END);
314         messageLabel.setSelectable(true);
315         messageBox.add(messageLabel);
316 
317         /* Add the message to the log */
318         textArea.add(messageBox);
319     }
320 
321     public void receiveMessage(string username, string message)
322     {
323         /* Create the MessageBox */
324         Box messageBox = new Box(GtkOrientation.VERTICAL, 1);
325 
326         /* Create and add the username */
327         Label usernameLabel = new Label("");
328         usernameLabel.setMarkup("<b>"~username~"</b>");
329         usernameLabel.setHalign(GtkAlign.START);
330         messageBox.add(usernameLabel);
331 
332         /* Create and add the message */
333         Label messageLabel = new Label(message);
334         messageLabel.setHalign(GtkAlign.START);
335         messageLabel.setSelectable(true);
336         messageBox.add(messageLabel);
337 
338         // import gtk.Image;
339         // Image d = new Image("/home/deavmi/Downloads/5207740.jpg");
340         // messageBox.add(d);
341 
342         /* Add the message to the log */
343         textArea.add(messageBox);
344     }
345 }