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 }