Integer type name change.
[silc.git] / apps / silcer / src / SilcerMainDlg.cc
1 /*
2
3   SilcerMainDlg.cc 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silcerapp.hh"
21 #include "silcerchatview.hh"
22 #include "SilcerMainDlg.hh"
23 #include "gtkspell.h"
24
25 #include <libgnomeui/gnome-window-icon.h>   
26 #include <libgnome/gnome-help.h>
27 #include <gtk--/style.h>
28 #include <gnome--/href.h>
29 #include <gtk--/text.h>
30 #include <gtk--/toolbar.h>
31 #include <gtk--/notebook.h>
32
33 static char *parse_command(const char *buffer)
34 {
35   char *ret;
36   char *cp = (char *)buffer;
37   int len;
38
39   len = strcspn((const char *)cp, " ");
40   ret = silc_to_upper(cp + 1);
41   ret[len - 1] = 0;
42   return ret;
43 }
44
45 SilcerMainDlg::SilcerMainDlg(void) : SilcerBaseDialog("SilcerMainDlg")
46 {
47   _thisWindow->realize();
48
49   // Get intput box and set it for input
50   _InputBox = getWidget<Gtk::Text>("SilcerMainDlgInputBox");
51   _InputBox->key_press_event.connect(slot(this,
52                                           &SilcerMainDlg::InputBoxKeyPress));
53   _Completer = g_completion_new(NULL);
54
55   // Get output box and create new chat view box
56   _OutputBox = getWidget<Gtk::HBox>("SilcerMainDlgOutputBox");
57   _ChatView = new SilcerChatView(_thisWindow, _OutputBox, false);
58
59   // Show only icons on toolbar
60   getWidget<Gtk::Toolbar>("SilcerMainDlgToolbar")->
61     set_style(GTK_TOOLBAR_ICONS);
62
63   // Hide tabs, since they are not used currently!
64   getWidget<Gtk::Notebook>("SilcerMainDlgTab")->set_show_tabs(false);
65
66   _thisWindow->show();
67 }
68
69 SilcerMainDlg::~SilcerMainDlg(void)
70 {
71
72 }
73
74 void SilcerMainDlg::print(const string message)
75 {
76   _ChatView->render(message, "", "", BLUE);
77 }
78
79 void SilcerMainDlg::print(const string message, const string nickname)
80 {
81   _ChatView->render(message, nickname, "", BLUE2);
82 }
83
84 gint SilcerMainDlg::InputBoxKeyPress(GdkEventKey *key)
85 {
86   string msg;
87
88   switch (key->keyval) {
89   case GDK_space:
90     if (gtkspell_running())
91       gtkspell_check_all(_InputBox->gtkobj());
92     break;
93
94   case GDK_Return:
95   case GDK_KP_Enter:
96     if (key->state & GDK_SHIFT_MASK) {
97       key->state ^= GDK_SHIFT_MASK;
98       return 0;
99     }
100
101     // Parse message to see whether it is command
102     msg = _InputBox->get_chars(0, -1);
103     if (msg.empty()) {
104       _InputBox->delete_text(0, -1);
105       gtk_signal_emit_stop_by_name(GTK_OBJECT(_InputBox->gtkobj()), 
106                                    "key_press_event");
107       break;
108     }
109
110     if (msg.at(0) == '/') {
111       // Command
112       SilcClientCommand cmd;
113       SilcClientCommandContext ctx;
114       char *tmpcmd;
115       SilcUInt32 argc = 0;
116       unsigned char **argv;
117       SilcUInt32 *argv_lens, *argv_types;
118
119       // Parse arguments
120       tmpcmd = parse_command(msg.c_str());
121       cmd = silc_client_command_find(silc_client, (const char *)tmpcmd);
122       silc_free(tmpcmd);
123       if (cmd == NULL)
124         break;
125
126       silc_parse_command_line((unsigned char *)msg.c_str(), &argv, &argv_lens,
127                               &argv_types, &argc, cmd->max_args);
128
129       ctx = silc_client_command_alloc();
130       ctx->client = silc_client;
131       ctx->conn = silc_client_conn;
132       ctx->command = cmd;
133       ctx->argc = argc;
134       ctx->argv = argv;
135       ctx->argv_lens = argv_lens;
136       ctx->argv_types = argv_types;
137       
138       // Execute the command
139       silc_client_command_call(cmd, ctx);
140     } else {
141       // Channel message
142       if (silc_client_conn->current_channel) {
143         print(msg);
144         silc_client_send_channel_message(silc_client, 
145                                          silc_client_conn,
146                                          silc_client_conn->current_channel, 
147                                          NULL,
148                                          0, (unsigned char *)msg.c_str(), 
149                                          msg.length(), TRUE);
150       }
151     }
152
153     _InputBox->delete_text(0, -1);
154     gtk_signal_emit_stop_by_name(GTK_OBJECT(_InputBox->gtkobj()), 
155                                  "key_press_event");
156     break;
157
158   case GDK_Tab:
159     {
160       // Word completion
161       msg = _InputBox->get_chars(0, -1);
162
163       if (!msg.empty()) {
164         string lastword;
165
166         // Search for the last whitespace
167         string::size_type n = msg.find_last_of(" ");
168         if (n != string::npos)
169           lastword = msg.substr(n+1);
170         else
171           lastword = msg;
172         
173         // Try and autocomplete
174         gchar *prefix;
175         g_completion_complete(_Completer, (char*)lastword.c_str(), &prefix);
176         if (prefix != NULL){
177           // Replace the last word in the message and update
178           if (n != string::npos)
179             msg.replace(msg.find_last_of(" ")+1, msg.length(), prefix);
180           else
181             msg = string(prefix);
182           g_free(prefix);
183           
184           // Update text
185           _InputBox->delete_text(0, -1);
186           _InputBox->insert(msg);
187         }
188
189         gtk_signal_emit_stop_by_name(GTK_OBJECT(_InputBox->gtkobj()), 
190                                      "key_press_event");
191         return 1;
192       }
193     }
194     break;
195
196   default:
197     break;
198   }
199
200   return 0;
201 }