Hello everyone, I am building a text editor in Gtk+, but I am getting a small error.
What I want to do is to implement Save. For this I used following approach.
1. Declare an array, filepathsarray, where all paths of file will be saved of each tab.
2. Set the current filepath in filepathsarray, whenever open or save as is activated.
3. if filepathsarray[current_index] is empty then create a new file i.e. call saveas_activated function.
4. if filepathsarray[current_index] is not empty then sets the content of that file.
Here is my code
Code:
#include<gtk/gtk.h>
#include<glib.h>
#include<gtksourceview/gtksourceview.h>
#include<gtksourceview/gtksourcelanguage.h>
#include<gtksourceview/gtksourcelanguagemanager.h>
#include<string.h>
#include<stdio.h>
GtkSourceBuffer *buffer;
GtkWidget *notebook;
GtkWidget *scrollwin[10];
GtkWidget *txtinput[10];
GtkWidget *window;
int offset = 0;
GtkWidget *txtfind;
GtkWidget *txtreplace;
char *filepathsarray[10];
static void destroy(GtkWidget *);
static gboolean delete_event(GtkWidget *,GdkEvent *);
void open_activated(GtkWidget *, GtkWindow *);
void filenew_activated(GtkWidget *);
void save_activated(GtkWidget *, GtkWindow *);
void saveas_activated(GtkWidget *, GtkWindow *);
void cut_activated(GtkWidget *);
void paste_activated(GtkWidget *);
void copy_activated(GtkWidget *);
void undo_activated(GtkWidget *);
void redo_activated(GtkWidget *);
void newtab_activated(GtkWidget *);
void removetab_activated(GtkWidget *);
void findandreplace_activated(GtkWidget *);
void cmdfind_clicked(GtkWidget *);
void cmdreplace_clicked(GtkWidget *);
int main(int argc, char *argv[])
{
GtkWidget *menubar, *file, *edit, *filemenu, *editmenu, *label1;
GtkWidget *filenew, *open, *save,*saveas, *cut, *copy, *paste,*vbox,*undo,*redo,*newtab,*removetab, *findandreplace;
GtkAccelGroup *group;
GtkAdjustment *horizontal, *vertical;
int i;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"TextEditor");
gtk_widget_set_size_request(window,600,400);
group = gtk_accel_group_new();
menubar = gtk_menu_bar_new();
for (i=0;i<10;i++)
{
buffer = GTK_SOURCE_BUFFER(gtk_source_buffer_new(NULL));
txtinput[i] = gtk_source_view_new_with_buffer(buffer);
scrollwin[i] = gtk_scrolled_window_new(NULL,NULL);
filepathsarray[i] = "";
}
notebook = gtk_notebook_new();
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin[0]),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrollwin[0]),txtinput[0]);
label1 = gtk_label_new("New File");
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrollwin[0],label1);
vbox = gtk_vbox_new(FALSE,2);
gtk_box_pack_start(GTK_BOX(vbox),menubar,FALSE,FALSE,0); /* Expand set to FALSE,Hence Fill also to FALSE*/
gtk_box_pack_start(GTK_BOX(vbox),notebook,TRUE,TRUE,0); /* Expand and Fill set to FALSE*/
file = gtk_menu_item_new_with_label("File");
edit = gtk_menu_item_new_with_label("Edit");
filemenu = gtk_menu_new();
editmenu = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(file),filemenu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit),editmenu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar),file);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar),edit);
/*Create the File menu*/
filenew = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW,group);
open = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN,group);
save = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE,group);
saveas = gtk_menu_item_new_with_label("Save As");
newtab = gtk_menu_item_new_with_label("New Tab");
removetab = gtk_menu_item_new_with_label("Remove Current Tab");
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),filenew);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),newtab);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),open);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),save);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),saveas);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),removetab);
/*Create the Edit menu*/
cut = gtk_image_menu_item_new_from_stock(GTK_STOCK_CUT,group);
copy = gtk_image_menu_item_new_from_stock(GTK_STOCK_COPY,group);
paste = gtk_image_menu_item_new_from_stock(GTK_STOCK_PASTE,group);
undo = gtk_image_menu_item_new_from_stock(GTK_STOCK_UNDO,group);
redo = gtk_image_menu_item_new_from_stock(GTK_STOCK_REDO,group);
findandreplace = gtk_image_menu_item_new_from_stock(GTK_STOCK_FIND_AND_REPLACE,group);
g_signal_connect(G_OBJECT(undo),"activate",G_CALLBACK(undo_activated),NULL);
g_signal_connect(G_OBJECT(redo),"activate",G_CALLBACK(redo_activated),NULL);
g_signal_connect(G_OBJECT(cut),"activate",G_CALLBACK(cut_activated),NULL);
g_signal_connect(G_OBJECT(paste),"activate",G_CALLBACK(paste_activated),NULL);
g_signal_connect(G_OBJECT(copy),"activate",G_CALLBACK(copy_activated),NULL);
g_signal_connect(G_OBJECT(findandreplace),"activate",G_CALLBACK(findandreplace_activated),NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu),undo);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu),redo);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu),cut);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu),copy);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu),paste);
gtk_menu_shell_append(GTK_MENU_SHELL(editmenu),findandreplace);
g_signal_connect(G_OBJECT(open),"activate",G_CALLBACK(open_activated),(gpointer)GTK_WINDOW(window));
g_signal_connect(G_OBJECT(filenew),"activate",G_CALLBACK(filenew_activated),NULL);
g_signal_connect(G_OBJECT(saveas),"activate",G_CALLBACK(saveas_activated),(gpointer)GTK_WINDOW(window));
g_signal_connect(G_OBJECT(save),"activate",G_CALLBACK(save_activated),(gpointer)GTK_WINDOW(window));
g_signal_connect(G_OBJECT(newtab),"activate",G_CALLBACK(newtab_activated),NULL);
g_signal_connect(G_OBJECT(removetab),"activate",G_CALLBACK(removetab_activated),NULL);
gtk_container_add(GTK_CONTAINER(window),vbox);
gtk_window_add_accel_group(GTK_WINDOW(window),group);
g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(destroy),NULL);
g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
void cmdfind_clicked(GtkWidget *widget)
{
const gchar *textfind;
textfind = gtk_entry_get_text(GTK_ENTRY(txtfind));
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
GtkTextIter match_start_iter,match_end_iter;
GtkTextIter start_iter;
gtk_text_buffer_get_iter_at_offset(buffer,&start_iter,offset);
if(gtk_text_iter_forward_search(&start_iter,textfind,GTK_TEXT_SEARCH_TEXT_ONLY,&match_start_iter,&match_end_iter,NULL) == TRUE)
{
gtk_text_buffer_select_range(buffer,&match_start_iter,&match_end_iter);
offset = gtk_text_iter_get_offset(&match_end_iter);
gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]),&match_end_iter,0.1,FALSE,0.5,0.5);
}
}
void cmdreplace_clicked(GtkWidget *widget)
{
const gchar *textfind,*textreplace;
textfind = gtk_entry_get_text(GTK_ENTRY(txtfind));
textreplace = gtk_entry_get_text(GTK_ENTRY(txtreplace));
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
GtkTextIter match_start_iter,match_end_iter;
GtkTextIter start_iter;
gtk_text_buffer_get_iter_at_offset(buffer,&start_iter,offset);
if(gtk_text_iter_forward_search(&start_iter,textfind,GTK_TEXT_SEARCH_TEXT_ONLY,&match_start_iter,&match_end_iter,NULL) == TRUE)
{
gtk_text_buffer_select_range(buffer,&match_start_iter,&match_end_iter);
offset = gtk_text_iter_get_offset(&match_end_iter);
gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]),&match_end_iter,0.1,FALSE,0.5,0.5);
gtk_text_buffer_delete_selection(buffer,FALSE,FALSE);
gtk_text_buffer_insert_at_cursor(buffer,textreplace,-1);
}
}
void findandreplace_activated(GtkWidget *widget)
{
GtkWidget *findandreplacewindow;
GtkWidget *cmdfind;
GtkWidget *cmdreplace;
GtkWidget *frame;
findandreplacewindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
frame = gtk_fixed_new();
txtfind = gtk_entry_new();
gtk_widget_set_size_request(txtfind,241,31);
gtk_fixed_put(GTK_FIXED(frame),txtfind,10,20);
cmdfind = gtk_button_new_with_mnemonic("_Find");
gtk_widget_set_size_request(cmdfind,95,31);
gtk_fixed_put(GTK_FIXED(frame),cmdfind,260,20);
txtreplace = gtk_entry_new();
gtk_widget_set_size_request(txtreplace,241,31);
gtk_fixed_put(GTK_FIXED(frame),txtreplace,10,70);
cmdreplace = gtk_button_new_with_mnemonic("_Replace");
gtk_widget_set_size_request(cmdreplace,95,31);
gtk_fixed_put(GTK_FIXED(frame),cmdreplace,260,70);
g_signal_connect(G_OBJECT(cmdfind),"clicked",G_CALLBACK(cmdfind_clicked),NULL);
g_signal_connect(G_OBJECT(cmdreplace),"clicked",G_CALLBACK(cmdreplace_clicked),NULL);
gtk_container_add(GTK_CONTAINER(findandreplacewindow),frame);
gtk_window_set_transient_for(GTK_WINDOW(findandreplacewindow),GTK_WINDOW(window));
gtk_window_set_destroy_with_parent(GTK_WINDOW(findandreplacewindow),TRUE);
gtk_widget_set_size_request(GTK_WIDGET(findandreplacewindow),362,110);
gtk_window_set_title(GTK_WINDOW(findandreplacewindow),"Find and Replace");
gtk_widget_show_all(findandreplacewindow);
}
static void destroy(GtkWidget *window)
{
gtk_main_quit();
}
static gboolean delete_event(GtkWidget *window,GdkEvent *event)
{
return FALSE;
}
void removetab_activated(GtkWidget *widget)
{
int i;
for (i = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); i<10;i++)
{
txtinput[i] = txtinput[i+1];
}
GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER(gtk_source_buffer_new(NULL));
txtinput[10] = gtk_source_view_new_with_buffer(buffer);
gtk_notebook_remove_page(GTK_NOTEBOOK(notebook),gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)));
}
void newtab_activated(GtkWidget *widget)
{
int pages = 0;
GtkWidget *label1;
label1 = gtk_label_new("New File");
pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
gtk_container_add(GTK_CONTAINER(scrollwin[pages]),txtinput[pages]);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin[pages]),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrollwin[pages],label1);
gtk_widget_show_all(window);
}
void undo_activated(GtkWidget *widget)
{
GtkSourceBuffer *buffer;
buffer = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))])));
gtk_source_buffer_undo(buffer);
}
void redo_activated(GtkWidget *widget)
{
GtkSourceBuffer *buffer;
buffer = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))])));
gtk_source_buffer_redo(buffer);
}
void copy_activated(GtkWidget *widget)
{
GtkClipboard *clipboard;
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
clipboard = gtk_clipboard_get(GDK_NONE);
gtk_text_buffer_copy_clipboard(buffer,clipboard);
}
void cut_activated(GtkWidget *widget)
{
GtkClipboard *clipboard;
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
clipboard = gtk_clipboard_get(GDK_NONE);
gtk_text_buffer_cut_clipboard(buffer,clipboard,TRUE);
}
void paste_activated(GtkWidget *widget)
{
GtkClipboard *clipboard;
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
clipboard = gtk_clipboard_get(GDK_NONE);
gtk_text_buffer_paste_clipboard(buffer,clipboard,NULL,TRUE);
}
void saveas_activated(GtkWidget *widget, GtkWindow *parent)
{
GtkWidget *dialog;
GtkTextIter start_iter, end_iter;
GtkTextBuffer *buffer;
GtkSourceLanguageManager *languagemanager = gtk_source_language_manager_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
dialog = gtk_file_chooser_dialog_new("Save File", parent, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,GTK_STOCK_SAVE,GTK_RESPONSE_ACCEPT,NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog))== GTK_RESPONSE_ACCEPT)
{
char *filepath,*text;
char *filename;
gssize length = -1;
filepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
filepathsarray[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))] = filepath;
gtk_text_buffer_get_end_iter(buffer,&end_iter);
gtk_text_buffer_get_start_iter(buffer,&start_iter);
text = gtk_text_buffer_get_text(buffer,&start_iter,&end_iter,FALSE);
g_file_set_contents(filepath,text,length,NULL);
GtkSourceLanguage *language = gtk_source_language_manager_guess_language(languagemanager,filepath,NULL);
filename = strrchr(filepath,'/');
*filename++;
gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(notebook),scrollwin[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))],filename);
gtk_source_buffer_set_language(GTK_SOURCE_BUFFER(buffer),language);
g_free(filepath);
g_free(text);
}
gtk_widget_destroy(dialog);
}
void save_activated(GtkWidget *widget, GtkWindow *parent)
{
if (filepathsarray[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))] == "")
{
saveas_activated(widget,parent);
}
else
{
gssize length = -1;
GtkTextBuffer *buffer;
GtkTextIter start_iter, end_iter;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
gtk_text_buffer_get_start_iter(buffer, &start_iter);
gtk_text_buffer_get_end_iter(buffer, &end_iter);
char *text;
text = gtk_text_buffer_get_text(buffer,&start_iter,&end_iter,FALSE);
g_file_set_contents(filepathsarray[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))],text,length,NULL);
}
}
void open_activated(GtkWidget *widget, GtkWindow *parent)
{
GtkWidget *dialog;
GtkSourceLanguageManager *languagemanager = gtk_source_language_manager_new();
dialog = gtk_file_chooser_dialog_new("Open File", parent, GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,NULL);
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
if(gtk_dialog_run(GTK_DIALOG(dialog))== GTK_RESPONSE_ACCEPT)
{
char *filepath,*string,*filename;
gsize length = -1;
filepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
filepathsarray[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))] = filepath;
g_file_get_contents(filepath,&string,&length,NULL);
GtkSourceLanguage *language = gtk_source_language_manager_guess_language(languagemanager,filepath,NULL);
filename = strrchr(filepath,'/');
*filename++;
gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(notebook),scrollwin[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))],filename);
gtk_source_buffer_set_language(GTK_SOURCE_BUFFER(buffer),language);
gtk_text_buffer_set_text(buffer,string,-1);
g_free(filepath);
g_free(string);
}
gtk_widget_destroy(dialog);
}
void filenew_activated(GtkWidget *widget)
{
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))]));
gtk_text_buffer_set_text(buffer,"",-1);
filepathsarray[gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))] = "";
}
but I am not getting the desired result for no. 4. I think there is some problem in storing filepaths in filepathsarray. Please help!! Thnx in advance!!