#include #include #include #include #include #include "structures.h" #include "functions.h" #include "vars.h" /*---------------------------------------------------------------- * GtkMainQuit * * * * Exit SLMC properly * * Used by menu and MainWindow decoration * * First close the databases, then, quit the gtk main loop * * * * --------------------------------------------------------------*/ int GtkMainQuit(GtkWidget *Widget, gpointer NotUsed) { sqlite3_close(Widgets.db); sqlite3_close(Widgets.db2); gtk_main_quit(); return 0; } /*---------------------------------------------------------------- * CheckMails * * * * call CheckM function and refresh the list of mails * * used by MainWindow's menu. * * * * -------------------------------------------------------------*/ int CheckMails(GtkWidget *Widget, gpointer NotUsed) { CheckM(); g_signal_emit_by_name(GTK_TREE_VIEW(Widgets.TreeView), "cursor-changed"); return 0; } /*---------------------------------------------------------------- * DeleteMail * * * * Delete a mail from database * * Used by MainWindow's menu and toolbar * * * * --------------------------------------------------------------*/ int DeleteMail(GtkWidget *Widget, gpointer NotUsed) { int rc; char *zErrMsg = 0; GtkTextBuffer *MailBuffer; Widgets.Requete = g_strdup_printf("DELETE FROM mails WHERE ROWID='%s'", Widgets.MailId); rc = sqlite3_exec(Widgets.db, Widgets.Requete, NULL, 0, &zErrMsg); if(rc!=SQLITE_OK) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } Widgets.Requete = g_strdup_printf("SELECT ROWID,* FROM mails WHERE account='%s'", Widgets.CurrentAccount); gtk_list_store_clear(GTK_LIST_STORE(Widgets.ListStore)); rc = sqlite3_exec(Widgets.db2, Widgets.Requete, ShowMailsList, 0, &zErrMsg); if(rc!=SQLITE_OK) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } gtk_label_set_text(GTK_LABEL(Widgets.RightLabel), "Subject: \nFrom: \nDate: \nTo: \nCC:"); MailBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(Widgets.Rig)); gtk_text_buffer_set_text(GTK_TEXT_BUFFER(MailBuffer), "", -1); return 0; } /*---------------------------------------------------------------- * SendMail * * * * Send mail by SMTP * * used by function NewMailWindow. * * gpointer Widg: expected to be a MailWidget structure * * * * -------------------------------------------------------------*/ void SendMail(GtkWidget *button, gpointer *Widg) { GtkTextBuffer *TextBuffer; GtkTextIter BufferStart; GtkTextIter BufferEnd; NewMail MailInfos; MailWidgets *FromWidgets; FromWidgets = (MailWidgets*) Widg; MailInfos.ToEmail = (gchar*) gtk_entry_get_text(GTK_ENTRY(FromWidgets->To)); MailInfos.CCEmail = (gchar*) gtk_entry_get_text(GTK_ENTRY(FromWidgets->CC)); MailInfos.Subject = (gchar*) gtk_entry_get_text(GTK_ENTRY(FromWidgets->Subject)); TextBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(FromWidgets->Text)); gtk_text_buffer_get_start_iter(TextBuffer, &BufferStart); gtk_text_buffer_get_end_iter(TextBuffer, &BufferEnd); MailInfos.Text = gtk_text_buffer_get_text(TextBuffer, &BufferStart, &BufferEnd, TRUE); // connection to SMTP server : port 25, need HELO message Connection((gchar*)Widgets.AccInfos.SMTPServer, 25, 1); // SMTP Protocol talks between our client and the server SendToSocket(g_strdup_printf("MAIL FROM: %s", Widgets.AccInfos.Email)); ReadFromSocket(); SendToSocket(g_strdup_printf("RCPT TO: %s", MailInfos.ToEmail)); if(MailInfos.CCEmail) SendToSocket(g_strdup_printf("RCPT TO: %s", MailInfos.CCEmail)); ReadFromSocket(); SendToSocket("DATA"); ReadFromSocket(); // sending header informations, and message SendToSocket(g_strdup_printf("To: %s", MailInfos.ToEmail)); if(MailInfos.CCEmail) SendToSocket(g_strdup_printf("CC: %s", MailInfos.CCEmail)); SendToSocket(g_strdup_printf("From: %s", Widgets.AccInfos.Email)); SendToSocket(g_strdup_printf("Subject: %s\r\n", MailInfos.Subject)); SendToSocket(g_locale_to_utf8(MailInfos.Text, -1, NULL, NULL, NULL)); // stop to send informations SendToSocket("."); ReadFromSocket(); Deconnection(); } /*---------------------------------------------------------------- * NewMailWindow * * * * Open a new window with input buttons, to type the email. * * used by MainWindow's menu and toolbar * * gpointer Mail: exepted to be a structure: NewMail * * * * -------------------------------------------------------------*/ int NewMailWindow(GtkMenuItem *menuitem, gpointer Mail) { GtkWidget *NewMailWindow; GtkWidget *Container; GtkWidget *ContainerHTo; GtkWidget *ContainerHCC; GtkWidget *ContainerHSubj; GtkWidget *LabelTo; GtkWidget *LabelCC; GtkWidget *LabelSubj; GtkWidget *Send, *Scroll; GtkWidget *To; GtkWidget *CC; GtkWidget *Subj; GtkWidget *TextMail; NewMail *MailInfos; static MailWidgets Widgs; MailInfos = (NewMail*) Mail; NewMailWindow = CreateGtkWindow("New Mail", 700, 300, 0, 0, 0); Container = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(NewMailWindow), Container); // creating the inputs To = CreateEntry(MailInfos->ToEmail, 0); LabelTo = CreateLabel("To:", 7); CC = CreateEntry(MailInfos->CCEmail, 0); LabelCC = CreateLabel("CC:", 7); Subj = CreateEntry(MailInfos->Subject, 0); LabelSubj = CreateLabel("Subject:", 7); TextMail = CreateTextView(MailInfos->Text, 1); Scroll = PackIntoScroll(TextMail); Send = gtk_button_new_with_label("Send"); // storing the widgets into a structure in order to send it to a data treatment function Widgs.To = GTK_WIDGET(To); Widgs.CC = GTK_WIDGET(CC); Widgs.Subject = GTK_WIDGET(Subj); Widgs.Text = TextMail; g_signal_connect(GTK_OBJECT(Send), "clicked", G_CALLBACK(SendMail), &Widgs); g_signal_connect_swapped(GTK_OBJECT(Send), "clicked", G_CALLBACK(gtk_widget_destroy), NewMailWindow); // packing ContainerHTo = PackLabelEntry(LabelTo, To); ContainerHCC = PackLabelEntry(LabelCC, CC); ContainerHSubj = PackLabelEntry(LabelSubj, Subj); gtk_box_pack_start(GTK_BOX(Container), GTK_WIDGET(ContainerHTo), 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), GTK_WIDGET(ContainerHCC), 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), GTK_WIDGET(ContainerHSubj), 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), GTK_WIDGET(Scroll), 1, 1, 4); gtk_box_pack_start(GTK_BOX(Container), GTK_WIDGET(Send), 0, 0, 10); gtk_widget_show_all(NewMailWindow); return EXIT_SUCCESS; } /*---------------------------------------------------------------- * AboutWindow * * * * Open a new window with informations about the programme and * * its creator (me :D) * * used by main function * * gpointer data: excepted to be NULL * * * * -------------------------------------------------------------*/ void AboutWindow() { GtkWidget *AboutWindow; GtkWidget *Container; GtkWidget *AboutText; GtkWidget *AboutTitle; GtkWidget *AboutText2; GtkWidget *AboutTitle2; GtkWidget *AboutText3; GtkWidget *AboutTitle3; GtkWidget *Ok; AboutWindow = CreateGtkWindow("About SLMC", 600, 800, 0, 0, 0); Container = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(AboutWindow), Container); gtk_container_set_border_width(GTK_CONTAINER(Container), 15); AboutTitle=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(AboutTitle), "About://SLMC\n"); AboutText=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(AboutText), "Simple Lightweight Mail Client\n\nis a simple POP3 and SMTP mail client written in C and GTK,\nreleased as free software under the GNU GPL license.\n\n"); AboutTitle2=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(AboutTitle2), "About://Th3_4ut0r\n"); AboutText2=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(AboutText2), "Sébastien BOCAHU\nalso known as Zecrazytux\n\nPS1 SUPINFO student\nSUPINFO ID: 51237\nzecrazytux@supinfo.com\nwww.zecrazytux.net\n"); AboutTitle3=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(AboutTitle3), "Thanks\n"); AboutText3=gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(AboutText3), "Lots of thanks to:\nGerald from GTK-FR's forum.\nProgs, C/C++ coder of the game \"Men are ants\"\nOpen Source softwares, in which i learned how to use many functions.\nBernard Chardonneau for sharing its Libremail source code.\nQuake3, a 3D first person shooter game which runs under Linux.\nGET27\ncofee and chocolate\nLofofora, Nightwish, Joe Satriani, and so on...\n\nwithout them my project wouldn't have been realized !\n"); gtk_misc_set_alignment(GTK_MISC(AboutTitle), 0.5, 0); gtk_misc_set_alignment(GTK_MISC(AboutText), 0, 0); gtk_misc_set_alignment(GTK_MISC(AboutTitle2), 0.5, 0); gtk_misc_set_alignment(GTK_MISC(AboutText2), 0, 0); gtk_misc_set_alignment(GTK_MISC(AboutTitle3), 0.5, 0); gtk_misc_set_alignment(GTK_MISC(AboutText3), 0, 0); Ok = gtk_button_new_with_label("Ok"); g_signal_connect_swapped(GTK_WIDGET(Ok), "clicked", G_CALLBACK(gtk_widget_destroy), AboutWindow); gtk_box_pack_start(GTK_BOX(Container), AboutTitle, 1, 1, 0); gtk_box_pack_start(GTK_BOX(Container), AboutText, 1, 1, 0); gtk_box_pack_start(GTK_BOX(Container), AboutTitle2, 0, 1, 0); gtk_box_pack_start(GTK_BOX(Container), AboutText2, 1, 1, 0); gtk_box_pack_start(GTK_BOX(Container), AboutTitle3, 0, 1, 0); gtk_box_pack_start(GTK_BOX(Container), AboutText3, 1, 1, 0); gtk_box_pack_start(GTK_BOX(Container), Ok, 0, 0, 2); gtk_widget_show_all(AboutWindow); } /*** joe satriani rox, crowd chant motivated a lot to write this code :p | rock powaaa ***/ int DeleteAccount(GtkWidget *Widget, gpointer NotUsed) { int rc; char *zErrMsg = 0; GtkTextBuffer *MailBuffer; Widgets.Requete = g_strdup_printf("DELETE FROM accounts WHERE ROWID='%s'", Widgets.NewAccount.Id); rc = sqlite3_exec(Widgets.db, Widgets.Requete, NULL, 0, &zErrMsg); if( rc!=SQLITE_OK ) { fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } Widgets.Requete = g_strdup_printf("DELETE FROM mails WHERE account='%s'", Widgets.NewAccount.Id); rc = sqlite3_exec(Widgets.db, Widgets.Requete, NULL, 0, &zErrMsg); if(rc!=SQLITE_OK) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } gtk_list_store_clear(GTK_LIST_STORE(Widgets.ListAccounts)); rc = sqlite3_exec(Widgets.db,"SELECT ROWID,* FROM accounts", ListAccounts, 0, &zErrMsg); if( rc!=SQLITE_OK ) { fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } gtk_tree_store_clear(GTK_TREE_STORE(Widgets.TreeStore)); rc = sqlite3_exec(Widgets.db,"SELECT DISTINCT (smtpserver) FROM accounts", Mailboxes, 0, &zErrMsg); if( rc!=SQLITE_OK ) { fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } gtk_list_store_clear(GTK_LIST_STORE(Widgets.ListStore)); gtk_label_set_text(GTK_LABEL(Widgets.RightLabel), "Subject: \nFrom: \nDate: \nTo: \nCC:"); MailBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(Widgets.Rig)); gtk_text_buffer_set_text(GTK_TEXT_BUFFER(MailBuffer), "", -1); return 0; } int AddAccount(GtkWidget *Widget, gpointer account) { Account AccInfos; AccountWidgets *NewAcc; int rc; char *zErrMsg = 0; NewAcc = (AccountWidgets*) account; AccInfos.Name = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->Name)); AccInfos.Email = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->Email)); AccInfos.POPServer = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->POPServer)); AccInfos.SMTPServer = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->SMTPServer)); AccInfos.User = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->User)); AccInfos.Passwd = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->Passwd)); Widgets.Requete = g_strdup_printf("INSERT INTO accounts VALUES ('%s', '%s', '%s', '%s', '%s', '%s')", AccInfos.Name, AccInfos.Email, AccInfos.POPServer, AccInfos.SMTPServer, AccInfos.User, AccInfos.Passwd); rc = sqlite3_exec(Widgets.db, Widgets.Requete, NULL, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } gtk_list_store_clear(GTK_LIST_STORE(Widgets.ListAccounts)); rc = sqlite3_exec(Widgets.db,"SELECT ROWID,* FROM accounts", ListAccounts, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } gtk_tree_store_clear(GTK_TREE_STORE(Widgets.TreeStore)); rc = sqlite3_exec(Widgets.db,"SELECT DISTINCT (smtpserver) FROM accounts", Mailboxes, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } return 0; } int ModAccount(GtkWidget *Widget, gpointer account) { Account AccInfos; AccountWidgets *NewAcc; int rc; char *zErrMsg = 0; NewAcc = (AccountWidgets*) account; AccInfos.Name = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->Name)); AccInfos.Email = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->Email)); AccInfos.POPServer = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->POPServer)); AccInfos.SMTPServer = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->SMTPServer)); AccInfos.User = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->User)); AccInfos.Passwd = (gchar*) gtk_entry_get_text(GTK_ENTRY(NewAcc->Passwd)); Widgets.Requete = g_strdup_printf("UPDATE accounts SET name='%s', email='%s', popserver='%s', smtpserver='%s', user='%s', password='%s' WHERE ROWID='%s'", AccInfos.Name, AccInfos.Email, AccInfos.POPServer, AccInfos.SMTPServer, AccInfos.User, AccInfos.Passwd, Widgets.NewAccount.Id); rc = sqlite3_exec(Widgets.db, Widgets.Requete, NULL, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } gtk_list_store_clear(GTK_LIST_STORE(Widgets.ListAccounts)); rc = sqlite3_exec(Widgets.db,"SELECT ROWID,* FROM accounts", ListAccounts, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } gtk_tree_store_clear(GTK_TREE_STORE(Widgets.TreeStore)); rc = sqlite3_exec(Widgets.db,"SELECT DISTINCT (smtpserver) FROM accounts", Mailboxes, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } return 0; } /*---------------------------------------------------------------- * NewAccountWindow * * * * Open a new window for the user to write his needed * * informations... * * used by AccountManager function * * gpointer Infos: structure Account: empty or old * * informations in case of modification * * -------------------------------------------------------------*/ int NewAccountWindow(GtkMenuItem *menuitem, gpointer new) { GtkWidget *NewAccWindow; GtkWidget *Container; GtkWidget *Info_Name, *Info_Name_Entry, *ContainerHName; GtkWidget *Info_Email, *Info_Email_Entry, *ContainerHEmail; GtkWidget *Info_POPServer, *Info_POPServer_Entry, *ContainerHPOPServer; GtkWidget *Info_SMTPServer, *Info_SMTPServer_Entry, *ContainerHSMTPServer; GtkWidget *Info_User, *Info_User_Entry, *ContainerHUser; GtkWidget *Info_Passwd, *Info_Passwd_Entry, *ContainerHPasswd; GtkWidget *Ok, *Cancel, *ContainerHButton; static AccountWidgets Widgs; if((int)new) { Widgets.NewAccount.Id = ""; Widgets.NewAccount.Name = ""; Widgets.NewAccount.Email = ""; Widgets.NewAccount.POPServer = ""; Widgets.NewAccount.SMTPServer = ""; Widgets.NewAccount.User = ""; Widgets.NewAccount.Passwd = ""; } NewAccWindow = CreateGtkWindow("SLMC - New/modify account", 370, 450, 0, 0, 0); Info_Name_Entry = CreateEntry(Widgets.NewAccount.Name, 0); Info_Name = CreateLabel("Name:", 12); ContainerHName = PackLabelEntry(Info_Name, Info_Name_Entry); Info_Email_Entry = CreateEntry(Widgets.NewAccount.Email, 0); Info_Email = CreateLabel("Email:", 12); ContainerHEmail = PackLabelEntry(Info_Email, Info_Email_Entry); Info_POPServer_Entry = CreateEntry(Widgets.NewAccount.POPServer, 0); Info_POPServer = CreateLabel("POP Server:", 12); ContainerHPOPServer = PackLabelEntry(Info_POPServer, Info_POPServer_Entry); Info_SMTPServer_Entry = CreateEntry(Widgets.NewAccount.SMTPServer, 0); Info_SMTPServer = CreateLabel("SMTP Server:", 12); ContainerHSMTPServer = PackLabelEntry(Info_SMTPServer, Info_SMTPServer_Entry); Info_User_Entry = CreateEntry(Widgets.NewAccount.User, 0); Info_User = CreateLabel("Username:", 12); ContainerHUser = PackLabelEntry(Info_User, Info_User_Entry); Info_Passwd_Entry = CreateEntry(Widgets.NewAccount.Passwd, 1); Info_Passwd = CreateLabel("Password:", 12); ContainerHPasswd = PackLabelEntry(Info_Passwd, Info_Passwd_Entry); Ok = gtk_button_new_with_label("Ok"); Cancel = gtk_button_new_with_label("Cancel"); gtk_widget_set_size_request(GTK_WIDGET(Ok), 80, 30); gtk_widget_set_size_request(GTK_WIDGET(Cancel), 80, 30); ContainerHButton = gtk_hbox_new(TRUE, 10); gtk_box_pack_start(GTK_BOX(ContainerHButton), Ok, 0, 0, 2); gtk_box_pack_start(GTK_BOX(ContainerHButton), Cancel, 0, 0, 2); Widgs.Name = GTK_WIDGET(Info_Name_Entry); Widgs.Email = GTK_WIDGET(Info_Email_Entry); Widgs.POPServer = GTK_WIDGET(Info_POPServer_Entry); Widgs.SMTPServer = GTK_WIDGET(Info_SMTPServer_Entry); Widgs.User = GTK_WIDGET(Info_User_Entry); Widgs.Passwd = GTK_WIDGET(Info_Passwd_Entry); if((int)new) g_signal_connect(GTK_WIDGET(Ok), "clicked", G_CALLBACK(AddAccount), &Widgs); else g_signal_connect(GTK_WIDGET(Ok), "clicked", G_CALLBACK(ModAccount), &Widgs); g_signal_connect_swapped(Ok, "clicked", G_CALLBACK (gtk_widget_destroy), NewAccWindow); g_signal_connect_swapped(Cancel, "clicked", G_CALLBACK (gtk_widget_destroy), NewAccWindow); Container = gtk_vbox_new(TRUE, 0); gtk_container_add(GTK_CONTAINER(NewAccWindow), Container); gtk_box_pack_start(GTK_BOX(Container), ContainerHName, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerHEmail, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerHPOPServer, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerHSMTPServer, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerHUser, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerHPasswd, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerHButton, 0, 0, 2); gtk_widget_show_all(NewAccWindow); return EXIT_SUCCESS; } /*---------------------------------------------------------------- * AccountManager * * * * Accounts management window: delete, add, modify accounts * * Used by: main function (menu) * * * * -------------------------------------------------------------*/ int AccountManager(int argc,char **argv) { GtkWidget *AccWindow; GtkWidget *Container; GtkWidget *ContainerL; GtkWidget *ContainerR; GtkWidget *DeleteAcc; GtkWidget *NewAcc; GtkWidget *ModifyAcc; GtkWidget *Ok; GtkWidget *ScrollL; GtkWidget *List; GtkCellRenderer *cell; GtkTreeViewColumn *column; static Account NewAccount; int rc; char *zErrMsg = 0; NewAccount.Id = ""; NewAccount.Name = NewAccount.Email = NewAccount.POPServer = NewAccount.SMTPServer = NewAccount.User = NewAccount.Passwd = ""; AccWindow = CreateGtkWindow("SLMC - Accounts manager", 400, 300, 0, 0, 0); Container = gtk_hbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(AccWindow), Container); ContainerL = gtk_vbox_new(FALSE, 0); ContainerR = gtk_vbox_new(FALSE, 0); Widgets.ListAccounts = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); List = gtk_tree_view_new_with_model(GTK_TREE_MODEL(Widgets.ListAccounts)); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("NAME",cell, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(List), GTK_TREE_VIEW_COLUMN(column)); cell = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("ID",cell, "text", 1, NULL); ScrollL = PackIntoScroll(GTK_WIDGET(List)); DeleteAcc = gtk_button_new_with_label("Delete account"); ModifyAcc = gtk_button_new_with_label("Modify account"); NewAcc = gtk_button_new_with_label("New account"); Ok = gtk_button_new_with_label("Ok"); g_signal_connect(GTK_WIDGET(DeleteAcc), "clicked", G_CALLBACK(DeleteAccount), (gpointer*)0); g_signal_connect(GTK_WIDGET(ModifyAcc), "clicked", G_CALLBACK(NewAccountWindow), (gpointer*)0); g_signal_connect(G_OBJECT(NewAcc), "clicked", G_CALLBACK(NewAccountWindow), (gpointer*)1); g_signal_connect_swapped(GTK_WIDGET(Ok), "clicked", G_CALLBACK(gtk_widget_destroy), AccWindow); gtk_box_pack_start(GTK_BOX(ContainerL), ScrollL, 1, 1, 2); gtk_box_pack_start(GTK_BOX(ContainerR), DeleteAcc, 0, 0, 2); gtk_box_pack_start(GTK_BOX(ContainerR), ModifyAcc, 0, 0, 2); gtk_box_pack_start(GTK_BOX(ContainerR), NewAcc, 0, 0, 2); gtk_box_pack_start(GTK_BOX(ContainerR), Ok, 0, 0, 2); gtk_box_pack_start(GTK_BOX(Container), ContainerL, 1, 1, 0); gtk_box_pack_start(GTK_BOX(Container), ContainerR, 0, 0, 0); rc = sqlite3_exec(Widgets.db,"SELECT ROWID,* FROM accounts", ListAccounts, 0, &zErrMsg); if( rc!=SQLITE_OK ) { GtkError(g_strdup_printf("SQL error: %s\n", zErrMsg), 0); sqlite3_free(zErrMsg); } Widgets.AccountsSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(List)); g_signal_connect(GTK_TREE_VIEW(List), "cursor-changed", G_CALLBACK(AccountInListSelected), NULL); gtk_widget_show_all(AccWindow); return EXIT_SUCCESS; }