Commit d0386d39 by karudu

Merge branch 'Karl' into 'master'

Esialgne kood masterisse

See merge request !1
parents ba71144c c1f0f5fe
#include <gtk/gtk.h>
/* TODO
Failide avamine
Failide salvestamine
*/
#ifdef SOURCEVIEW
#include <gtksourceview/gtksource.h>
#endif
#ifdef SOURCEVIEW
#define PEALKIRI "CEditor SourceView"
#else
#define PEALKIRI "CEditor TextView"
#endif
// Uuenda näidatud rida ja veergu kursori asukoha järgi
void UuendaRidaVeerg(GtkTextBuffer *Puhver, GtkStatusbar *StatusBar)
{
GtkTextIter Iter;
// Leia kursori asukoht
gtk_text_buffer_get_iter_at_mark(Puhver, &Iter, gtk_text_buffer_get_insert(Puhver));
// Võta selle rida ja veerg
gint Rida = gtk_text_iter_get_line(&Iter);
gint Veerg = gtk_text_iter_get_line_offset(&Iter);
gtk_statusbar_pop(StatusBar, 0); // Võta eelmine tekst ära
gchar *Tekst = g_strdup_printf("%d:%d", Rida + 1, Veerg + 1); // Loo string rea ja veeruga
gtk_statusbar_push(StatusBar, 0, Tekst); // Näita teksti
g_free(Tekst);
}
// Kutsutakse copy/paste lohistamise korral, praegu lihtsalt uuendab rida/veergu
void TekstMarkSet(GtkTextBuffer *Puhver, const GtkTextIter *new_location, GtkTextMark *Mark, gpointer Data)
{
UuendaRidaVeerg(Puhver, GTK_STATUSBAR(Data));
}
#include "ceditor.h"
#include "ui.h"
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
// Aken
GtkWidget *Aken = gtk_window_new(GTK_WINDOW_TOPLEVEL); // Loo aken
gtk_window_set_position(GTK_WINDOW(Aken), GTK_WIN_POS_CENTER); // Aken ekraani keskel
gtk_window_set_default_size(GTK_WINDOW(Aken), 800, 600); // Akna suurus
gtk_window_set_title(GTK_WINDOW(Aken), PEALKIRI); // Pealkiri
// Close nupu callback
g_signal_connect_swapped(G_OBJECT(Aken), "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Box
GtkWidget *Box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Vertikaalne box, 0px vahe
gtk_container_add(GTK_CONTAINER(Aken), Box); // Pane box aknasse
// Menu bar
GtkWidget *MenuBar = gtk_menu_bar_new(); // Loo menu bar
GtkWidget *FailMenuNupp = gtk_menu_item_new_with_label("Fail"); // Fail
GtkWidget *AboutMenuNupp = gtk_menu_item_new_with_label("About"); // About
GtkWidget *FailMenu = gtk_menu_new(); // Fail menüü
GtkWidget *FailMenuUus = gtk_menu_item_new_with_label("Uus"); // Fail->Uus
GtkWidget *FailMenuAva = gtk_menu_item_new_with_label("Ava"); // Fail->Ava
GtkWidget *FailMenuSalvesta = gtk_menu_item_new_with_label("Salvesta"); // Fail->Salvesta
GtkWidget *FailMenuSalvestaN = gtk_menu_item_new_with_label("Salvesta nimega"); // Fail->Salvesta nimega
GtkWidget *FailMenuValju = gtk_menu_item_new_with_label("Välju"); // Fail->Välju
// Menüü nupud menu bar'i
gtk_menu_shell_append(GTK_MENU_SHELL(MenuBar), FailMenuNupp);
gtk_menu_shell_append(GTK_MENU_SHELL(MenuBar), AboutMenuNupp);
// Menüüd nuppudesse
gtk_menu_item_set_submenu(GTK_MENU_ITEM(FailMenuNupp), FailMenu);
// Fail menüü
gtk_menu_shell_append(GTK_MENU_SHELL(FailMenu), FailMenuUus); // Fail->Uus
gtk_menu_shell_append(GTK_MENU_SHELL(FailMenu), FailMenuAva); // Fail->Ava
gtk_menu_shell_append(GTK_MENU_SHELL(FailMenu), FailMenuSalvesta); // Fail->Salvesta
gtk_menu_shell_append(GTK_MENU_SHELL(FailMenu), FailMenuSalvestaN); // Fail->Salvesta nimega
gtk_menu_shell_append(GTK_MENU_SHELL(FailMenu), gtk_separator_menu_item_new());
gtk_menu_shell_append(GTK_MENU_SHELL(FailMenu), FailMenuValju); // Fail->Välju
g_signal_connect(G_OBJECT(FailMenuValju), "activate", G_CALLBACK(gtk_main_quit), NULL);
// Pane menubar box'i
gtk_box_pack_start(GTK_BOX(Box), MenuBar, FALSE, FALSE, 0);
gtk_init(&argc, &argv);
// Tekstiaken
#ifdef SOURCEVIEW
GtkWidget *View = gtk_source_view_new(); // Loo tekstiaken
#else
GtkWidget *View = gtk_text_view_new(); // Loo tekstiaken
#endif
gtk_box_pack_start(GTK_BOX(Box), View, TRUE, TRUE, 0); // Pane tekstiaken box'i
ui *UI = LooUI();
gtk_widget_show_all(UI->Aken); // Näita akent
// Teksti puhver
GtkTextBuffer *Puhver = gtk_text_view_get_buffer(GTK_TEXT_VIEW(View)); // Tekstiakna teksti puhver
gtk_main();
// Status bar
GtkWidget *StatusBar = gtk_statusbar_new(); // Loo status bar
gtk_box_pack_start(GTK_BOX(Box), StatusBar, FALSE, FALSE, 0); // Pane statusbar box'i
// Teksti muutuse callback, uuendab rida/veergu
g_signal_connect(Puhver, "changed", G_CALLBACK(UuendaRidaVeerg), StatusBar);
// Copy/paste lohistamise callback, uuendab samuti
g_signal_connect_object(Puhver, "mark_set", G_CALLBACK(TekstMarkSet), StatusBar, 0);
gtk_widget_show_all(Aken); // Näita akent
UuendaRidaVeerg(Puhver, GTK_STATUSBAR(StatusBar)); // Esimene uuendus
gtk_main();
return 0;
}
\ No newline at end of file
return 0;
}
#ifndef CEDITOR_H
#define CEDITOR_H
#include <gtk/gtk.h>
#include <gtksourceview/gtksource.h>
typedef struct
{
GtkWidget *Aken; // Programmi aken
char *FailiNimi; // Viit faili nimele, 0 kui nime veel pole
GtkWidget *Pealkiri; // Vahekaardi pealkiri
char *PealkiriTekst; // Originaalne pealkirja tekst
GtkWidget *Box; // Vahekaardi box
GtkWidget *TextView; // Vahekaardi tekstiaken
GtkSourceBuffer *Puhver; // Vahekaardi tekstipuhver
GtkWidget *ScrollWindow; // Tekstiakna scroll
GtkWidget *StatusBar; // Status bar
GtkWidget *search_entry; // Otsingu tekst entry
GtkWidget *replace_entry; // Asendamise tekst entry
GtkSourceLanguageManager *LangManager; // Süntaksi värvimise asjad
GtkSourceLanguage *Language;
gint MuudetudID; // Muudetud teksti signaali ID
} tab;
typedef struct
{
GtkWidget *Aken; // Programmi aken
GtkWidget *Box; // Akna box
GtkWidget *MenuBar; // Ülaosa menüü
GtkWidget *Notebook; // Notebook vahekaartidega
GtkWidget *ToolBar; //Tool bar
GtkWidget *AccelGroup; // Accel group nuppude hotkey'de jaoks
// Viited nuppudele nende sisse/välja lülitamiseks
GtkWidget *FailMenuAva;
GtkWidget *FailMenuSalvesta;
GtkWidget *FailMenuSalvestaN;
GtkWidget *FailMenuSulgeV;
tab *Tabid; // Vahekaartide massiiv
int PraeguneTab; // Praegune valitud vahekaart
int TabidN; // Mitu vahekaarti on avatud
//toolbari nupud
GtkToolItem *Undo; //undo nupp
GtkToolItem *Redo; //redo nupp
// SourceView stiil
GtkSourceStyleSchemeManager *SchemeManager;
GtkSourceStyleSchemeChooser *SchemeChooser;
GKeyFile *Seaded; // Seadete fail
char *SeadedNimi; // Seadete faili nimi
} ui;
#endif // CEDITOR_H
#include "compiler.h"
// Salvesta kompilaatori seaded ja sulge aken
void SalvestaSeaded(GtkWidget *Nupp, gpointer Data)
{
puhvrid *Puhvrid = (puhvrid *)Data;
g_key_file_set_string(Puhvrid->Seaded, "Kompilaator", "komp_asukoht", gtk_entry_buffer_get_text(Puhvrid->PuhverKAsukoht));
g_key_file_set_string(Puhvrid->Seaded, "Kompilaator", "komp_seaded", gtk_entry_buffer_get_text(Puhvrid->PuhverKSeaded));
g_key_file_set_string(Puhvrid->Seaded, "Kompilaator", "prog_asukoht", gtk_entry_buffer_get_text(Puhvrid->PuhverPAsukoht));
g_key_file_set_string(Puhvrid->Seaded, "Kompilaator", "prog_seaded", gtk_entry_buffer_get_text(Puhvrid->PuhverPSeaded));
g_key_file_save_to_file(Puhvrid->Seaded, Puhvrid->SeadedNimi, 0);
gtk_widget_destroy(GTK_WIDGET(Puhvrid->Aken));
g_free(Puhvrid);
}
// Sulge aken
void SulgeSeaded(GtkWidget *Nupp, gpointer Data)
{
puhvrid *Puhvrid = (puhvrid *)Data;
gtk_widget_destroy(GTK_WIDGET(Puhvrid->Aken));
g_free(Puhvrid);
}
// Kompilaatori seadete aken
void KompilaatoriSeaded(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
GtkWindow *Aken = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(Aken, 400, 180); // Akna suurus
gtk_window_set_title(Aken, "Kompilaatori seaded"); // Pealkiri
gtk_window_set_type_hint(Aken, GDK_WINDOW_TYPE_HINT_DIALOG);
GtkBox *Box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(Aken), Box); // Pane box aknasse
GtkBox *HBox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkBox *HBox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkBox *HBox3 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkBox *HBox4 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkBox *HBoxNupud = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkLabel *LabelKAsukoht = gtk_label_new("Kompilaatori asukoht");
GtkLabel *LabelKSeaded = gtk_label_new("Kompilaatori seaded");
GtkLabel *LabelPAsukoht = gtk_label_new("Programmi asukoht");
GtkLabel *LabelPSeaded = gtk_label_new("Programmi seaded");
GtkEntry *EntryKAsukoht = gtk_entry_new();
gtk_entry_set_width_chars(EntryKAsukoht, 40);
GtkEntry *EntryKSeaded = gtk_entry_new();
gtk_entry_set_width_chars(EntryKSeaded, 40);
GtkEntry *EntryPAsukoht = gtk_entry_new();
gtk_entry_set_width_chars(EntryPAsukoht, 40);
GtkEntry *EntryPSeaded = gtk_entry_new();
gtk_entry_set_width_chars(EntryPSeaded, 40);
GtkEntryBuffer *PuhverKAsukoht = gtk_entry_get_buffer(EntryKAsukoht);
GtkEntryBuffer *PuhverKSeaded = gtk_entry_get_buffer(EntryKSeaded);
GtkEntryBuffer *PuhverPAsukoht = gtk_entry_get_buffer(EntryPAsukoht);
GtkEntryBuffer *PuhverPSeaded = gtk_entry_get_buffer(EntryPSeaded);
gtk_box_pack_start(HBox1, GTK_WIDGET(LabelKAsukoht), FALSE, FALSE, 8);
gtk_box_pack_start(HBox1, GTK_WIDGET(EntryKAsukoht), FALSE, FALSE, 0);
gtk_box_pack_start(HBox2, GTK_WIDGET(LabelKSeaded), FALSE, FALSE, 8);
gtk_box_pack_start(HBox2, GTK_WIDGET(EntryKSeaded), FALSE, FALSE, 6);
gtk_box_pack_start(HBox3, GTK_WIDGET(LabelPAsukoht), FALSE, FALSE, 8);
gtk_box_pack_start(HBox3, GTK_WIDGET(EntryPAsukoht), FALSE, FALSE, 12);
gtk_box_pack_start(HBox4, GTK_WIDGET(LabelPSeaded), FALSE, FALSE, 8);
gtk_box_pack_start(HBox4, GTK_WIDGET(EntryPSeaded), FALSE, FALSE, 18);
char *KAsukoht = g_key_file_get_string(UI->Seaded, "Kompilaator", "komp_asukoht", NULL);
if(KAsukoht) gtk_entry_buffer_set_text(PuhverKAsukoht, KAsukoht, -1);
char *KSeaded = g_key_file_get_string(UI->Seaded, "Kompilaator", "komp_seaded", NULL);
if(KSeaded) gtk_entry_buffer_set_text(PuhverKSeaded, KSeaded, -1);
char *PAsukoht = g_key_file_get_string(UI->Seaded, "Kompilaator", "prog_asukoht", NULL);
if(PAsukoht) gtk_entry_buffer_set_text(PuhverPAsukoht, PAsukoht, -1);
char *PSeaded = g_key_file_get_string(UI->Seaded, "Kompilaator", "prog_seaded", NULL);
if(PSeaded) gtk_entry_buffer_set_text(PuhverPSeaded, PSeaded, -1);
puhvrid *Puhvrid = malloc(sizeof(puhvrid));
Puhvrid->Aken = Aken;
Puhvrid->Seaded = UI->Seaded;
Puhvrid->SeadedNimi = UI->SeadedNimi;
Puhvrid->PuhverKAsukoht = PuhverKAsukoht;
Puhvrid->PuhverKSeaded = PuhverKSeaded;
Puhvrid->PuhverPAsukoht = PuhverPAsukoht;
Puhvrid->PuhverPSeaded = PuhverPSeaded;
GtkButton *NuppSalvesta = gtk_button_new_with_label("Salvesta");
GtkButton *NuppValju = gtk_button_new_with_label("Välju");
g_signal_connect(NuppSalvesta, "clicked", G_CALLBACK(SalvestaSeaded), Puhvrid);
g_signal_connect(NuppValju, "clicked", G_CALLBACK(SulgeSeaded), Puhvrid);
gtk_box_pack_start(HBoxNupud, GTK_WIDGET(NuppSalvesta), FALSE, FALSE, 140);
gtk_box_pack_start(HBoxNupud, GTK_WIDGET(NuppValju), FALSE, FALSE, 8);
gtk_box_pack_start(Box, GTK_WIDGET(HBox1), FALSE, FALSE, 4);
gtk_box_pack_start(Box, GTK_WIDGET(HBox2), FALSE, FALSE, 4);
gtk_box_pack_start(Box, GTK_WIDGET(HBox3), FALSE, FALSE, 4);
gtk_box_pack_start(Box, GTK_WIDGET(HBox4), FALSE, FALSE, 4);
gtk_box_pack_start(Box, GTK_WIDGET(HBoxNupud), FALSE, FALSE, 8);
gtk_widget_show_all(Aken);
}
// Loo programmi käsureast argv massiiv
char **LooArgv(char *Tekst)
{
int Argument = 0;
int P = 0;
int ArgP = 0;
char **Argv = malloc(sizeof(char *) * 16);
Argv[0] = malloc(512);
int Quotes = 0;
for(;;)
{
char C = Tekst[P++];
if(!Quotes)
{
switch(C)
{
case ' ':
{
Argv[Argument][ArgP] = 0;
Argument++;
Argv[Argument] = malloc(512);
ArgP = 0;
} break;
case 0:
{
Argv[Argument][ArgP] = 0;
Argv[Argument + 1] = malloc(1);
Argv[Argument + 1] = NULL;
return Argv;
} break;
case '"': Quotes = 1; break;
default: Argv[Argument][ArgP++] = C; break;
}
}
else
{
switch(C)
{
case '"': Quotes = 0; break;
default: Argv[Argument][ArgP++] = C; break;
}
}
}
}
// Käivita kompilaator vastavalt seadistustele
void Kompileeri(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
char *Asukoht = g_key_file_get_string(UI->Seaded, "Kompilaator", "komp_asukoht", NULL);
char *Seaded = g_key_file_get_string(UI->Seaded, "Kompilaator", "komp_seaded", NULL);
char *PAsukoht = g_key_file_get_string(UI->Seaded, "Kompilaator", "prog_asukoht", NULL);
if(Asukoht && Seaded && PAsukoht) // Kontrolli, et seaded on olemas
{
gchar *PKaust = g_path_get_dirname(PAsukoht); // Eemalda programmi nimi faili asukohast, jäta kaust järele
// Tee asukohast ja seadetest käsurea string, asukoht läheb jutumärkide vahele, et tühikud töötaks
char *Kask;
if(Seaded) Kask = g_strdup_printf("\"%s\" %s", Asukoht, Seaded);
else Kask = g_strdup_printf("\"%s\"", Asukoht);
char **Argv = LooArgv(Kask); // Teisalda käsurida argumentide massiiviks
GError *Viga = NULL;
gint WaitStatus;
// Käivita kompilaator
int Status = g_spawn_sync(PKaust, Argv, NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_CHILD_INHERITS_STDIN,
NULL, NULL, NULL, NULL, &WaitStatus, &Viga);
// Vaata, kuidas läks
if(Status == TRUE) // Kutsuti edukalt välja
{
// Kui kompileerimine õnnestus (tagastas 0), siis teata sellest status bar'il
if(g_spawn_check_wait_status(WaitStatus, &Viga))
{
StatusBarMsg(UI, "Kompileerimine OK");
}
else g_error_free(Viga);
}
else // Ei suutnud kompilaatorit käivitada, veateade
{
GtkWidget *Dialog = gtk_message_dialog_new(UI->Aken, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Viga kompilaatori väljakutsumisel:\n%s", Viga->message);
gtk_dialog_run(GTK_DIALOG(Dialog));
gtk_widget_destroy(Dialog);
g_error_free(Viga);
}
g_free(Asukoht);
g_free(Seaded);
g_free(PAsukoht);
g_free(PKaust);
g_free(Kask);
g_free(Argv);
}
else // Pole veel seadistatud
{
GtkWidget *Dialog = gtk_message_dialog_new(UI->Aken, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Kompilaatori asukoht või seaded pole seadistatud,\nseadista need ja proovi uuesti");
gtk_dialog_run(GTK_DIALOG(Dialog));
gtk_widget_destroy(Dialog);
}
}
// Käivita seadetes antud programm
void KaivitaProgramm(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
char *Asukoht = g_key_file_get_string(UI->Seaded, "Kompilaator", "prog_asukoht", NULL);
char *Seaded = g_key_file_get_string(UI->Seaded, "Kompilaator", "prog_seaded", NULL);
if(Asukoht && Seaded) // Kontrolli, et seaded on olemas
{
gchar *Kaust = g_path_get_dirname(Asukoht); // Eemalda programmi nimi faili asukohast, jäta kaust järele
// Tee asukohast ja seadetest käsurea string, asukoht läheb jutumärkide vahele, et tühikud töötaks
char *Kask;
if(Seaded) Kask = g_strdup_printf("\"%s\" %s", Asukoht, Seaded);
else Kask = g_strdup_printf("\"%s\"", Asukoht);
char **Argv = LooArgv(Kask); // Teisalda käsurida argumentide massiiviks
GError *Viga = NULL;
gint WaitStatus;
// Käivita programm
int Status = g_spawn_sync(Kaust, Argv, NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_CHILD_INHERITS_STDIN,
NULL, NULL, NULL, NULL, &WaitStatus, &Viga);
// Vaata, kuidas läks
if(Status == TRUE) // Kutsuti edukalt välja
{
// Loe ja näita programmi tagastatud koodi
gint Kood = 0;
if(g_spawn_check_wait_status(WaitStatus, &Viga) == FALSE)
{
Kood = Viga->code;
g_error_free(Viga);
}
char *Msg = g_strdup_printf("Programm tagastas 0x%x", Kood);
StatusBarMsg(UI, Msg);
gtk_window_present(UI->Aken); // Näita redaktori akent
g_free(Msg);
}
else // Ei suutnud programmi käivitada, veateade
{
GtkWidget *Dialog = gtk_message_dialog_new(UI->Aken, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Viga programmi väljakutsumisel:\n%s", Viga->message);
gtk_dialog_run(GTK_DIALOG(Dialog));
gtk_widget_destroy(Dialog);
g_error_free(Viga);
}
g_free(Asukoht);
g_free(Seaded);
g_free(Kaust);
g_free(Kask);
g_free(Argv);
}
else // Pole veel seadistatud
{
GtkWidget *Dialog = gtk_message_dialog_new(UI->Aken, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Programmi asukoht või seaded pole seadistatud,\nseadista need ja proovi uuesti");
gtk_dialog_run(GTK_DIALOG(Dialog));
gtk_widget_destroy(Dialog);
}
}
#ifndef COMPILER_H
#define COMPILER_H
#include "ceditor.h"
typedef struct
{
GtkWindow *Aken;
GKeyFile *Seaded;
char *SeadedNimi;
GtkEntryBuffer *PuhverKAsukoht;
GtkEntryBuffer *PuhverKSeaded;
GtkEntryBuffer *PuhverPAsukoht;
GtkEntryBuffer *PuhverPSeaded;
} puhvrid;
void KompilaatoriSeaded(GtkWidget *Nupp, gpointer Data);
void Kompileeri(GtkWidget *Nupp, gpointer Data);
void KaivitaProgramm(GtkWidget *Nupp, gpointer Data);
#endif // COMPILER_H
#include "menubar.h"
// Loob uue vahekaardi
void Uus(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
// Loo uus vahekaart
LisaTab(UI);
tab *Tab = &UI->Tabid[UI->TabidN - 1];
Tab->FailiNimi = 0;
gtk_notebook_set_current_page(UI->Notebook, UI->TabidN - 1); // Näita uut vahekaarti
// Muuda need uuesti vajutatavaks, kui ennem polnud
gtk_widget_set_sensitive(UI->FailMenuAva, TRUE);
gtk_widget_set_sensitive(UI->FailMenuSalvesta, TRUE);
gtk_widget_set_sensitive(UI->FailMenuSalvestaN, TRUE);
gtk_widget_set_sensitive(UI->FailMenuSulgeV, TRUE);
}
// Avab faili ja loeb selle teksti vahekaarti
void Ava(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
tab *Tab = &UI->Tabid[UI->PraeguneTab];
GtkWidget *Dialog = gtk_file_chooser_dialog_new("Ava fail", NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
"Tühista", GTK_RESPONSE_CANCEL,
"Ava", GTK_RESPONSE_ACCEPT, NULL);
gint Vastus = gtk_dialog_run(GTK_DIALOG(Dialog));
if(Vastus == GTK_RESPONSE_ACCEPT) // Ava, kui vajutati accept
{
char *Nimi = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(Dialog));
gchar *Sisu;
GError *Viga = NULL;
// TODO paremad veateated
if(g_file_get_contents(Nimi, &Sisu, NULL, &Viga)) // Proovi faili sisu lugeda
{
if(g_utf8_validate(Sisu, -1, NULL))
{
gtk_text_buffer_set_text(Tab->Puhver, Sisu, -1); // Kopeeri fail puhvrisse
gtk_text_buffer_set_modified(Tab->Puhver, FALSE); // Tekst on muutmata
Tab->FailiNimi = Nimi;
UuendaTabiPealkirja(Tab, Nimi);
UuendaTabMuudetud(0, Tab);
}
else
{
printf("g_utf8_validate viga\n");
g_free(Nimi);
}
g_free(Sisu);
}
else
{
// Faili ei saanud lugeda
printf("Viga faili avamisel: %s\n", Viga->message);
g_error_free(Viga);
g_free(Nimi);
}
}
gtk_widget_destroy(Dialog);
}
// Salvesta fail, tagastab 1 kui edukas
int SalvestaFail(ui *UI, tab *Tab)
{
GtkTextBuffer *Puhver = Tab->Puhver;
char *Nimi;
GtkWidget *Dialog = 0;
if(Tab->FailiNimi) // Fail on juba olemas
{
if(gtk_text_buffer_get_modified(Puhver) == 0) return; // Ära salvesta, kui midagi pole muudetud
Nimi = Tab->FailiNimi;
}
else // Salvestame uue faili
{
Dialog = gtk_file_chooser_dialog_new("Salvesta fail", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
"Tühista", GTK_RESPONSE_CANCEL,
"Salvesta", GTK_RESPONSE_ACCEPT, NULL);
gint Vastus = gtk_dialog_run(GTK_DIALOG(Dialog));
if(Vastus == GTK_RESPONSE_ACCEPT)
{
Nimi = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(Dialog));
}
else
{
gtk_widget_destroy(Dialog);
return 0;
}
}
GtkTextIter TekstA, TekstL;
gtk_text_buffer_get_start_iter(Puhver, &TekstA);
gtk_text_buffer_get_end_iter(Puhver, &TekstL);
gchar *Sisu = gtk_text_buffer_get_text(Puhver, &TekstA, &TekstL, TRUE);
GError *Viga = NULL;
if(g_file_set_contents(Nimi, Sisu, -1, &Viga) == TRUE)
{
gtk_text_buffer_set_modified(Tab->Puhver, FALSE); // Tekst on muutmata
// Kui enne salvestamist failinime polńud, siis kasuta praegust
if(!Tab->FailiNimi)
{
Tab->FailiNimi = Nimi;
UuendaTabiPealkirja(Tab, Nimi);
}
UuendaTabMuudetud(0, Tab);
g_free(Sisu);
if(Dialog) gtk_widget_destroy(Dialog);
return 1;
}
else
{
printf("Viga faili salvestamisel: %s\n", Viga->message);
g_error_free(Viga);
g_free(Nimi);
g_free(Sisu);
if(Dialog) gtk_widget_destroy(Dialog);
return 0;
}
}
// Salvestab vahekaardi teksti praegusesse faili
void Salvesta(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
tab *Tab = &UI->Tabid[UI->PraeguneTab];
SalvestaFail(UI, Tab);
}
// Salvestab vahekaardi teksti vabalt valitud faili
void SalvestaNimega(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
tab *Tab = &UI->Tabid[UI->PraeguneTab];
GtkTextBuffer *Puhver = Tab->Puhver;
GtkWidget *Dialog = gtk_file_chooser_dialog_new("Salvesta fail", NULL, GTK_FILE_CHOOSER_ACTION_SAVE,
"Tühista", GTK_RESPONSE_CANCEL,
"Salvesta", GTK_RESPONSE_ACCEPT, NULL);
gint Vastus = gtk_dialog_run(GTK_DIALOG(Dialog));
if(Vastus == GTK_RESPONSE_ACCEPT)
{
char *Nimi = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(Dialog));
GtkTextIter TekstA, TekstL;
gtk_text_buffer_get_start_iter(Puhver, &TekstA);
gtk_text_buffer_get_end_iter(Puhver, &TekstL);
gchar *Sisu = gtk_text_buffer_get_text(Puhver, &TekstA, &TekstL, TRUE);
gtk_text_buffer_set_modified(Puhver, FALSE);
GError *Viga = NULL;
if(g_file_set_contents(Nimi, Sisu, -1, &Viga) == TRUE)
{
if(g_strcmp0(Nimi, Tab->FailiNimi) == 0)
{
printf("Sama fail\n");
}
// Kui enne salvestamist failinime polńud, siis kasuta praegust
if(!Tab->FailiNimi)
{
Tab->FailiNimi = Nimi;
UuendaTabiPealkirja(Tab, Nimi);
}
UuendaTabMuudetud(0, Tab);
}
else
{
printf("Viga faili salvestamisel: %s\n", Viga->message);
g_error_free(Viga);
g_free(Nimi);
}
g_free(Sisu);
}
gtk_widget_destroy(Dialog);
}
// Sulgeb praeguse vahekaardi
void SulgeVahekaart(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
SulgeTab(UI, UI->PraeguneTab);
if(UI->TabidN == 0)
{
gtk_widget_set_sensitive(UI->FailMenuAva, FALSE);
gtk_widget_set_sensitive(UI->FailMenuSalvesta, FALSE);
gtk_widget_set_sensitive(UI->FailMenuSalvestaN, FALSE);
gtk_widget_set_sensitive(UI->FailMenuSulgeV, FALSE);
}
}
#ifndef MENUBAR_H
#define MENUBAR_H
#include "ceditor.h"
void Uus(GtkWidget *Nupp, gpointer Data);
void Ava(GtkWidget *Nupp, gpointer Data);
void Salvesta(GtkWidget *Nupp, gpointer Data);
void SalvestaNimega(GtkWidget *Nupp, gpointer Data);
void SulgeVahekaart(GtkWidget *Nupp, gpointer Data);
#endif // MENUBAR_H
#include "search.h"
GtkTextIter mstart, mend;
int Asendatud = 0;
//Funktsioon tekstiaknast sna leidmiseks
void find (GtkTextView *text_view, const gchar *text, GtkTextIter *iter)
{
GtkTextBuffer *buffer;
GtkTextMark *last_pos;
gboolean found;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); // Vtab teksti tekstiaknast puhvrina
found = gtk_text_iter_forward_search (iter, text, 0, &mstart, &mend, NULL); // Otsib text-i ja omistab mstart text-i algusesse ja mend text-i lppu
if (found)
{
gtk_text_buffer_select_range (buffer, &mstart, &mend); // Leiab mstart iter-i ja mend iter-i asukohad puhvris
last_pos = gtk_text_buffer_create_mark (buffer, "last_pos", &mend, FALSE); // Koostab puhvris marki mend asukohal
gtk_text_view_scroll_mark_onscreen(text_view, last_pos); // Highlight-ib tekstiaknas sna
Asendatud = 0;
}
}
//Funktsioon tekstiaknas sna asendamiseks
void asenda (GtkTextView *text_view, const gchar *replace, GtkTextIter *iter)
{
if(Asendatud == 0)
{
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); // Vtab teksti tekstiaknast puhvrina
gtk_text_buffer_select_range (buffer, &mstart, &mend); // Leiab mstart iter-i ja mend iter-i asukohad puhvris
gtk_text_buffer_delete (buffer, &mstart, &mend); // Kustutab puhvrist mstart ja mend iter-ite vahel oleva teksti
gtk_text_buffer_insert (buffer, &mstart, replace, -1); // Lisab mstart ja mend iter-ite vahele asendamise kastist oleva teksti
Asendatud = 1;
}
}
// funktsioon selleks kui search nuppu vajutatakse
void Otsi_nupp_vajutatud (GtkWidget *search_button, tab *Tab)
{
const gchar *text;
GtkTextBuffer *buffer;
GtkTextIter iter;
text = gtk_entry_get_text (GTK_ENTRY (Tab->search_entry)); // Vtab otsingu kastist oleva teksti ja omistab selle text-ile
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (Tab->TextView)); // Vtab teksti kirjutamis aknast puhvrina
gtk_text_buffer_get_start_iter (buffer, &iter); // Koostab iter-i puhvri alguses
find (GTK_TEXT_VIEW (Tab->TextView), text, &iter); // Funktsioon leiab tekstiaknast text-i sna
}
// funktsioon selleks kui jargmine_nupp vajutatakse
void Jargmine_nupp_vajutatud (GtkWidget *next_button, tab *Tab)
{
const gchar *text;
GtkTextBuffer *buffer;
GtkTextMark *last_pos;
GtkTextIter iter;
text = gtk_entry_get_text (GTK_ENTRY (Tab->search_entry)); // Vtab otsingu kastist oleva teksti ja omistab selle text-ile
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (Tab->TextView)); // Vtab teksti tekstiaknast puhvrina
last_pos = gtk_text_buffer_get_mark (buffer, "last_pos"); // Koostab puhvris marki
if (last_pos == NULL) return;
gtk_text_buffer_get_iter_at_mark (buffer, &iter, last_pos); // Koostab iter-i mark-i asukohal
find (GTK_TEXT_VIEW (Tab->TextView), text, &iter); // Funktsioon leiab tekstiaknast text-i sna
}
//funktsioon selleks kui asenda nuppu vajutatakse
void Asenda_nupp_vajutatud (GtkWidget *asenda_nupp, tab *Tab)
{
const gchar *text, *replace;
GtkTextBuffer *buffer;
GtkTextMark *last_pos;
GtkTextIter iter;
text = gtk_entry_get_text (GTK_ENTRY (Tab->search_entry)); // Otsingusse siestatud tekst
replace = gtk_entry_get_text (GTK_ENTRY (Tab->replace_entry)); // Tekst, mis asub asendamise teksti kastis
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (Tab->TextView)); // Vtab teksti tekstiaknast puhvrina
last_pos = gtk_text_buffer_get_mark (buffer, "last_pos"); // Koostab puhvris marki
if (last_pos == NULL)
return;
gtk_text_buffer_get_iter_at_mark (buffer, &iter, last_pos); // Koostab iteri mark-i asukohal
asenda (GTK_TEXT_VIEW (Tab->TextView), replace, &iter); // funktsioon asendab text-i replace-ga
}
#ifndef SEARCH_H
#define SEARCH_H
#include "ceditor.h"
void find (GtkTextView *text_view, const gchar *text, GtkTextIter *iter);
void asenda (GtkTextView *text_view, const gchar *replace, GtkTextIter *iter);
void Otsi_nupp_vajutatud (GtkWidget *search_button, tab *Tab);
void Jargmine_nupp_vajutatud (GtkWidget *next_button, tab *Tab);
void Asenda_nupp_vajutatud (GtkWidget *asenda_nupp, tab *Tab);
#endif // SEARCH_H
#include "settings.h"
void FontSeaded(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
GtkFontChooserDialog *FontChooser = gtk_font_chooser_dialog_new("Font", NULL);
char *SFondiNimi = g_key_file_get_string(UI->Seaded, "Seaded", "font", NULL); // Seadistatud fondi nimi
if(SFondiNimi)
{
gtk_font_chooser_set_font(FontChooser, SFondiNimi);
g_free(SFondiNimi);
}
int Vastus = gtk_dialog_run(GTK_DIALOG(FontChooser));
if(Vastus == GTK_RESPONSE_OK)
{
char *FondiNimi = gtk_font_chooser_get_font(FontChooser);
g_key_file_set_string(UI->Seaded, "Seaded", "font", FondiNimi);
g_key_file_save_to_file(UI->Seaded, UI->SeadedNimi, 0);
SeaFont(UI, FondiNimi); // Pane vahekaartidele uus font
g_free(FondiNimi);
}
gtk_widget_destroy(FontChooser);
}
void CheckboxVajutatud(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
gboolean Olek = gtk_toggle_button_get_active(Nupp);
if(Olek) // Sees
{
SeaVarvimine(UI, 1);
g_key_file_set_boolean(UI->Seaded, "Seaded", "varvi_suntaksi", 1);
}
else // Väljas
{
SeaVarvimine(UI, 0);
g_key_file_set_boolean(UI->Seaded, "Seaded", "varvi_suntaksi", 0);
}
g_key_file_save_to_file(UI->Seaded, UI->SeadedNimi, 0);
}
void SeaUusStiil(GtkWidget *nupp, gpointer Data)
{
ui *UI = (ui *)Data;
GtkSourceStyleScheme *Stiil = gtk_source_style_scheme_chooser_get_style_scheme(UI->SchemeChooser);
SeaStiil(UI, Stiil);
// Salvesta stiili ID ära
gchar *StiilID = gtk_source_style_scheme_get_id(Stiil);
g_key_file_set_string(UI->Seaded, "Seaded", "sourceview_stiil", StiilID);
g_key_file_save_to_file(UI->Seaded, UI->SeadedNimi, 0);
}
void SVarvSeaded(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
GtkWindow *Aken = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(Aken, 300, 100);
gtk_window_set_title(Aken, "Süntaksi värvimine");
gtk_window_set_type_hint(Aken, GDK_WINDOW_TYPE_HINT_DIALOG);
GtkBox *HBox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
GtkLabel *LabelValiStiil = gtk_label_new("Vali stiil:");
GtkWidget *ChooserButton = gtk_source_style_scheme_chooser_button_new();
gtk_box_pack_start(HBox1, GTK_WIDGET(LabelValiStiil), FALSE, FALSE, 8);
gtk_box_pack_start(HBox1, GTK_WIDGET(ChooserButton), FALSE, FALSE, 0);
GtkWidget *Checkbox = gtk_check_button_new_with_label("Värvi süntaksi");
gtk_toggle_button_set_active(Checkbox, 1);
// Kui süntaksi värvimise valik on salvestatud, siis kasuta seda
GError *VViga = NULL;
gboolean Varvimine = g_key_file_get_boolean(UI->Seaded, "Seaded", "varvi_suntaksi", &VViga);
if(!VViga) gtk_toggle_button_set_active(Checkbox, Varvimine);
else g_error_free(VViga);
g_signal_connect(Checkbox, "toggled", G_CALLBACK(CheckboxVajutatud), UI);
GtkWidget *ApplyButton = gtk_button_new_with_label("Salvesta stiil");
GtkBox *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(Aken), box);
gtk_box_pack_start(box, GTK_WIDGET(HBox1), FALSE, FALSE, 4);
gtk_box_pack_start(box, GTK_WIDGET(Checkbox), FALSE, FALSE, 4);
gtk_box_pack_start(box, GTK_WIDGET(ApplyButton), FALSE, FALSE, 8);
UI->SchemeChooser = ChooserButton;
g_signal_connect(ApplyButton, "clicked", G_CALLBACK(SeaUusStiil), UI);
gtk_widget_show_all(Aken);
}
#ifndef SETTINGS_H
#define SETTINGS_H
#include "ceditor.h"
void FontSeaded(GtkWidget *Nupp, gpointer Data);
void SVarvSeaded(GtkWidget *Nupp, gpointer Data);
#endif // SETTINGS_H
#include "statusbar.h"
// Uuenda näidatud rida ja veergu kursori asukoha järgi
void UuendaRidaVeerg(GtkTextBuffer *Puhver, GtkStatusbar *StatusBar)
{
GtkTextIter Iter;
// Leia kursori asukoht
gtk_text_buffer_get_iter_at_mark(Puhver, &Iter, gtk_text_buffer_get_insert(Puhver));
// Võta selle rida ja veerg
gint Rida = gtk_text_iter_get_line(&Iter);
gint Veerg = gtk_text_iter_get_line_offset(&Iter);
gtk_statusbar_pop(StatusBar, STATUSBAR_RIDAVEERG); // Võta eelmine tekst ära
gchar *Tekst = g_strdup_printf("%d:%d", Rida + 1, Veerg + 1); // Loo string rea ja veeruga
gtk_statusbar_push(StatusBar, STATUSBAR_RIDAVEERG, Tekst); // Näita teksti
g_free(Tekst);
}
// Näita status bar'il teksti
void StatusBarMsg(ui *UI, char *Tekst)
{
GtkStatusbar *StatusBar = UI->Tabid[UI->PraeguneTab].StatusBar;
gtk_statusbar_pop(StatusBar, STATUSBAR_TEKST); // Võta eelmine tekst ära
gtk_statusbar_push(StatusBar, STATUSBAR_TEKST, Tekst); // Näita teksti
}
#ifndef STATUSBAR_H
#define STATUSBAR_H
#include "ceditor.h"
// Status bar'i sõnumite id'd
#define STATUSBAR_RIDAVEERG 0
#define STATUSBAR_TEKST 1
void UuendaRidaVeerg(GtkTextBuffer *Puhver, GtkStatusbar *StatusBar);
void StatusBarMsg(ui *UI, char *Tekst);
#endif // STATUSBAR_H
#include "tab.h"
// Kustuta vahekaarti indeksil
void KustutaTab(ui *UI, int Indeks)
{
// Kustuta vahekaart
gtk_notebook_remove_page(GTK_NOTEBOOK(UI->Notebook), Indeks);
int TabidN = UI->TabidN;
// Kui massiivis on pärast kustutatud vahekaarti neid veel,
// siis nihuta need õigele kohale
for(int i = Indeks; i < TabidN - 1; i++)
{
UI->Tabid[i] = UI->Tabid[i + 1];
}
if(TabidN == 1)
{
g_free(UI->Tabid); // Vabasta massiiv, kui see on nüüd tühi
}
else
{
UI->Tabid = g_realloc(UI->Tabid, sizeof(tab) * (TabidN - 1)); // Eemalda vahekaart massiivist
}
UI->TabidN--;
}
// Uuenda vahekaardi pealkirja (faili nime)
void UuendaTabiPealkirja(tab *Tab, char *Nimi)
{
Tab->PealkiriTekst = g_path_get_basename(Nimi); // Eralda faili nimi
gtk_label_set_label(GTK_LABEL(Tab->Pealkiri), Tab->PealkiriTekst);
// Terve faili nimi tooltip'is
gtk_widget_set_tooltip_text(Tab->Pealkiri, Nimi);
}
void UuendaTabMuudetud(GtkWidget *Puhver, gpointer Data)
{
tab *Tab = (tab *)Data;
if(gtk_text_buffer_get_modified(Tab->Puhver))
{
char *Tekst = g_strdup_printf("%s *", gtk_label_get_text(Tab->Pealkiri));
gtk_label_set_label(GTK_LABEL(Tab->Pealkiri), Tekst);
g_free(Tekst);
}
else
{
gtk_label_set_label(GTK_LABEL(Tab->Pealkiri), Tab->PealkiriTekst);
}
}
// Kutsutakse igal vahekaardi muutmisel
void TabMuudetud(GtkWidget *Notebook, GtkWidget *Tab, guint Indeks, gpointer Data)
{
ui *UI = (ui *)Data;
UI->PraeguneTab = Indeks;
}
// Sulge praegune vahekaart, väljastab 1, kui vahekaart suleti, 0 kui mitte
int SulgeTab(ui *UI, int Indeks)
{
tab *Tab = &UI->Tabid[Indeks];
// Kui tekst on muudetud, siis küsi üle, kas salvestada
if(gtk_text_buffer_get_modified(Tab->Puhver))
{
GtkWidget *MsgDialog = gtk_message_dialog_new(UI->Aken, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
"Salvesta fail enne sulgemist?");
gtk_dialog_add_buttons(MsgDialog, "Jah", 0, "Ei", 1, "Loobu", 2, NULL);
gint Vastus = gtk_dialog_run(GTK_DIALOG(MsgDialog));
gtk_widget_destroy(MsgDialog);
if(Vastus == 0) // Jah
{
// Kui fail salvestati, siis jätka, muidu ära tee midagi
if(SalvestaFail(UI, Tab)) {}
else return 0;
}
else if(Vastus == 1) {} // Ei
else return 0;
}
KustutaTab(UI, Indeks);
return 1;
}
// Sea kõikdele vahekaartidele uus font
void SeaFont(ui *UI, char *FondiNimi)
{
for(int i = 0; i < UI->TabidN; i++)
{
gtk_widget_modify_font(UI->Tabid[i].TextView, pango_font_description_from_string(FondiNimi));
}
}
// Sea kõikdele vahekaartidele uus SourceView stiil
void SeaStiil(ui *UI, GtkSourceStyleScheme *Stiil)
{
for(int i = 0; i < UI->TabidN; i++)
{
gtk_source_buffer_set_style_scheme(UI->Tabid[i].Puhver, Stiil);
}
}
// Sea kõikdele vahekaartidele süntaksi värvimise valik
void SeaVarvimine(ui *UI, gboolean Varvi)
{
for(int i = 0; i < UI->TabidN; i++)
{
gtk_source_buffer_set_highlight_syntax(UI->Tabid[i].Puhver, Varvi);
}
}
// Loo uus vahekaart ja pane see lõppu
void LisaTab(ui *UI)
{
int TabidN = UI->TabidN;
if(TabidN == 0)
{
UI->Tabid = g_malloc(sizeof(tab)); // Loo massiiv, kui see pole olemas
}
else
{
UI->Tabid = g_realloc(UI->Tabid, sizeof(tab) * (TabidN + 1)); // Lisa vahekaart massiivi
for(int i = 0; i < UI->TabidN; i++)
{
tab *Tab = &UI->Tabid[i];
g_signal_handler_disconnect(Tab->Puhver, Tab->MuudetudID);
Tab->MuudetudID = g_signal_connect(Tab->Puhver, "modified-changed", G_CALLBACK(UuendaTabMuudetud), Tab);
}
}
tab *Tab = &UI->Tabid[TabidN];
UI->TabidN++;
Tab->FailiNimi = 0; // Faili veel pole
Tab->Aken = UI->Aken;
// Tekstiaken
Tab->TextView = gtk_source_view_new(); // Loo tekstiaken
Tab->Puhver = gtk_text_view_get_buffer(GTK_TEXT_VIEW(Tab->TextView)); // Tekstiakna teksti puhver
// Kui font on seadistatud, siis kasuta seda
char *FondiNimi = g_key_file_get_string(UI->Seaded, "Seaded", "font", NULL);
if(FondiNimi)
{
gtk_widget_modify_font(Tab->TextView, pango_font_description_from_string(FondiNimi));
g_free(FondiNimi);
}
// Otsing
GtkWidget *hbox = gtk_hbox_new (FALSE, 2);
Tab->search_entry = gtk_entry_new ();
GtkWidget *Otsi_nupp = gtk_button_new_with_label ("Otsi"); // Otsi nupp
g_signal_connect (G_OBJECT (Otsi_nupp), "clicked",
G_CALLBACK (Otsi_nupp_vajutatud), &UI->Tabid[TabidN]);
GtkWidget *Jargmine_nupp = gtk_button_new_with_label ("Järgmine"); // Järmine nupp
g_signal_connect (G_OBJECT (Jargmine_nupp), "clicked",
G_CALLBACK (Jargmine_nupp_vajutatud), &UI->Tabid[TabidN]);
// Teksti asendamine
Tab->replace_entry = gtk_entry_new ();
GtkWidget *Asenda_nupp =gtk_button_new_with_label ("Asenda"); // Asenda teksti nupp
gtk_box_pack_start (GTK_BOX (hbox), Tab->search_entry, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), Otsi_nupp, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), Jargmine_nupp, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), Tab->replace_entry, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), Asenda_nupp, FALSE, FALSE, 0);
g_signal_connect (G_OBJECT (Asenda_nupp), "clicked",
G_CALLBACK (Asenda_nupp_vajutatud), &UI->Tabid[TabidN]);
// Scroll window
Tab->ScrollWindow = gtk_scrolled_window_new(NULL, NULL); // Loo scroll aken
gtk_container_add(GTK_CONTAINER(Tab->ScrollWindow), Tab->TextView); // Scroll aknasse läheb tekstiaken
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Tab->ScrollWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); // Konfigureerimine
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(Tab->ScrollWindow), GTK_SHADOW_ETCHED_IN);
// Status bar
Tab->StatusBar = gtk_statusbar_new();
// Modified callback
Tab->MuudetudID = g_signal_connect(Tab->Puhver, "modified-changed", G_CALLBACK(UuendaTabMuudetud), Tab);
// Teksti muutuse callback
g_signal_connect_object(Tab->Puhver, "mark_set", G_CALLBACK(TekstMarkSet), Tab->StatusBar, 0);
// Box
Tab->Box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Vertikaalne box, 0px vahe
gtk_box_pack_start(GTK_BOX(Tab->Box), hbox, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(Tab->Box), Tab->ScrollWindow, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(Tab->Box), Tab->StatusBar, FALSE, FALSE, 0);
// Pealkiri
Tab->Pealkiri = gtk_label_new("(uus)");
Tab->PealkiriTekst = "(uus)";
// Language manager (süntaksi värvimine)
Tab->LangManager = gtk_source_language_manager_get_default();
Tab->Language = gtk_source_language_manager_get_language(Tab->LangManager, "c");
gtk_source_buffer_set_language(Tab->Puhver, Tab->Language);
// Kui süntaksi värvimise valik on salvestatud, siis kasuta seda
GError *VViga = NULL;
gboolean Varvimine = g_key_file_get_boolean(UI->Seaded, "Seaded", "varvi_suntaksi", &VViga);
if(!VViga) gtk_source_buffer_set_highlight_syntax(Tab->Puhver, Varvimine);
else g_error_free(VViga);
gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(Tab->TextView), TRUE); // Näita reanumbreid
char *StiilID = g_key_file_get_string(UI->Seaded, "Seaded", "sourceview_stiil", NULL);
if(StiilID)
{
GtkSourceStyleScheme *Stiil = gtk_source_style_scheme_manager_get_scheme(UI->SchemeManager, StiilID);
gtk_source_buffer_set_style_scheme(Tab->Puhver, Stiil);
g_free(StiilID);
}
// Lisa loodud tab notebook'i
gtk_notebook_append_page(GTK_NOTEBOOK(UI->Notebook), Tab->Box, Tab->Pealkiri);
gtk_widget_show_all(UI->Notebook); // Värskenda, et näha oleks
UuendaRidaVeerg(GTK_TEXT_BUFFER(Tab->Puhver), GTK_STATUSBAR(Tab->StatusBar)); // Uuenda status bar'i, et seal midagi oleks
}
#ifndef TAB_H
#define TAB_H
#include "ceditor.h"
#include "statusbar.h"
#include "search.h"
#include "textview.h"
void LisaTab(ui *UI);
void KustutaTab(ui *UI, int Indeks);
void UuendaTabiPealkirja(tab *Tab, char *Nimi);
void TabMuudetud(GtkWidget *Notebook, GtkWidget *Tab, guint Indeks, gpointer Data);
int SulgeTab(ui *UI, int Indeks);
void SeaFont(ui *UI, char *FondiNimi);
void SeaStiil(ui *UI, GtkSourceStyleScheme *Stiil);
void SeaVarvimine(ui *UI, gboolean Varvi);
#endif // TAB_H
#include "textview.h"
// Kutsutakse copy/paste lohistamise korral, praegu lihtsalt uuendab rida/veergu
void TekstMarkSet(GtkTextBuffer *Puhver, const GtkTextIter *new_location, GtkTextMark *Mark, gpointer Data)
{
UuendaRidaVeerg(Puhver, GTK_STATUSBAR(Data));
}
#ifndef TEXTVIEW_H
#define TEXTVIEW_H
#include "ceditor.h"
void TekstModified(GtkTextBuffer *Puhver, tab *Tab);
void TekstMarkSet(GtkTextBuffer *Puhver, const GtkTextIter *new_location, GtkTextMark *Mark, gpointer Data);
#endif // TEXTVIEW_H
#include "ui.h"
// Sulge programm, tagastab 1 kui kõik vahekaardid sulgeti, 0 kui mitte
int Sulge(ui *UI)
{
for(int i = UI->TabidN - 1; i > -1; i--)
{
gtk_notebook_set_current_page(UI->Notebook, i);
if(SulgeTab(UI, i))
{
continue;
}
else
{
gtk_notebook_set_current_page(UI->Notebook, UI->PraeguneTab);
return 0;
}
}
return 1;
}
gboolean SulgeAken(GtkWidget *Nupp, GdkEvent *Event, gpointer Data)
{
ui *UI = (ui *)Data;
if(Sulge(UI))
{
// Salvesta akna pikkus ja laius
int Pikkus, Laius;
gtk_window_get_size(UI->Aken, &Laius, &Pikkus);
g_key_file_set_integer(UI->Seaded, "Seaded", "akna_pikkus", Pikkus);
g_key_file_set_integer(UI->Seaded, "Seaded", "akna_laius", Laius);
g_key_file_save_to_file(UI->Seaded, UI->SeadedNimi, 0);
gtk_main_quit();
return FALSE;
} else return TRUE;
}
// Väljub rakendusest
void Valju(GtkWidget *Nupp, gpointer Data)
{
ui *UI = (ui *)Data;
if(Sulge(UI))
{
// Salvesta akna pikkus ja laius
int Pikkus, Laius;
gtk_window_get_size(UI->Aken, &Laius, &Pikkus);
g_key_file_set_integer(UI->Seaded, "Seaded", "akna_pikkus", Pikkus);
g_key_file_set_integer(UI->Seaded, "Seaded", "akna_laius", Laius);
g_key_file_save_to_file(UI->Seaded, UI->SeadedNimi, 0);
gtk_main_quit();
}
}
// Lisa menüüsse menu item
void LisaMenuItem(ui *UI, GtkWidget *Menu, GtkWidget *MenuItem, void *Callback, guint Nupp, GdkModifierType NuppMask)
{
gtk_menu_shell_append(GTK_MENU_SHELL(Menu), MenuItem);
g_signal_connect(MenuItem, "activate", G_CALLBACK(Callback), UI);
if(Nupp) gtk_widget_add_accelerator(MenuItem, "activate", UI->AccelGroup, Nupp, NuppMask, GTK_ACCEL_VISIBLE);
}
// Loo programmi kasutajaliides
ui *LooUI()
{
ui *UI = g_malloc(sizeof(ui));
// Aken
UI->Aken = gtk_window_new(GTK_WINDOW_TOPLEVEL); // Loo aken
gtk_window_set_position(GTK_WINDOW(UI->Aken), GTK_WIN_POS_CENTER); // Aken ekraani keskel
gtk_window_set_default_size(GTK_WINDOW(UI->Aken), 800, 600); // Akna suurus
gtk_window_set_title(GTK_WINDOW(UI->Aken), PEALKIRI); // Pealkiri
g_signal_connect(UI->Aken, "delete-event", G_CALLBACK(SulgeAken), UI); // Close nupu callback
// Seadete fail
UI->Seaded = g_key_file_new();
char *SeadedKaust = g_build_filename(g_get_home_dir(), "ceditor", NULL);
char *SeadedNimi = g_build_filename(SeadedKaust, "settings.ini", NULL);
UI->SeadedNimi = strdup(SeadedNimi);
GError *Viga = NULL;
// Ava seadete fail
if(!g_key_file_load_from_file(UI->Seaded, SeadedNimi, G_KEY_FILE_NONE, &Viga))
{
// Ei õnnestunud avada
if(Viga->code == G_FILE_ERROR_NOENT) // Faili pole olemas, loo see
{
g_mkdir_with_parents(SeadedKaust, 0700);
g_key_file_save_to_file(UI->Seaded, SeadedNimi, NULL);
}
else
{
printf("Viga settings.ini avamisel: %s\n", Viga->message);
}
g_error_free(Viga);
}
// Loe failist akna pikkus ja laius, kui on olemas
gint AknaPikkus = 600;
gint AknaLaius = 800;
Viga = NULL;
gint Pikkus = g_key_file_get_integer(UI->Seaded, "Seaded", "akna_pikkus", &Viga);
if(!Viga) AknaPikkus = Pikkus;
else g_error_free(Viga);
Viga = NULL;
gint Laius = g_key_file_get_integer(UI->Seaded, "Seaded", "akna_laius", &Viga);
if(!Viga) AknaLaius = Laius;
else g_error_free(Viga);
gtk_window_set_default_size(UI->Aken, AknaLaius, AknaPikkus);
// Box
UI->Box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); // Vertikaalne box, 0px vahe
gtk_container_add(GTK_CONTAINER(UI->Aken), UI->Box); // Pane box aknasse
// Notebook
UI->Notebook = gtk_notebook_new();
gtk_notebook_set_scrollable(UI->Notebook, TRUE); // Tee vahekaartide riba scrollitavaks
g_signal_connect(UI->Notebook, "switch-page", G_CALLBACK(TabMuudetud), UI); // Tab'i muutmise callback
// SourceView stiil
UI->SchemeManager = gtk_source_style_scheme_manager_get_default();
// Loo esimene tab
UI->TabidN = 0;
LisaTab(UI);
UI->PraeguneTab = 0;
// Accel group
UI->AccelGroup = gtk_accel_group_new();
gtk_window_add_accel_group(UI->Aken, UI->AccelGroup);
// Menu bar
UI->MenuBar = gtk_menu_bar_new(); // Loo menu bar
GtkWidget *FailMenuNupp = gtk_menu_item_new_with_label("Fail"); // Fail
GtkWidget *KompMenuNupp = gtk_menu_item_new_with_label("Kompileeri"); // Kompileeri
GtkWidget *SeadedMenuNupp = gtk_menu_item_new_with_label("Seaded"); // Seaded
// Fail menüü
GtkWidget *FailMenu = gtk_menu_new();
GtkWidget *FailMenuUus = gtk_menu_item_new_with_label("Uus vahekaart"); // Fail->Uus vahekaart
GtkWidget *FailMenuAva = gtk_menu_item_new_with_label("Ava"); // Fail->Ava
UI->FailMenuAva = FailMenuAva;
GtkWidget *FailMenuSalvesta = gtk_menu_item_new_with_label("Salvesta"); // Fail->Salvesta
UI->FailMenuSalvesta = FailMenuSalvesta;
GtkWidget *FailMenuSalvestaN = gtk_menu_item_new_with_label("Salvesta nimega"); // Fail->Salvesta nimega
UI->FailMenuSalvestaN = FailMenuSalvestaN;
GtkWidget *FailMenuSulgeV = gtk_menu_item_new_with_label("Sulge vahekaart"); // Fail->Sulge vahekaart
UI->FailMenuSulgeV = FailMenuSulgeV;
GtkWidget *FailMenuValju = gtk_menu_item_new_with_label("Välju"); // Fail->Välju
// Kompileeri menüü
GtkWidget *KompMenu = gtk_menu_new();
GtkWidget *KompMenuSeaded = gtk_menu_item_new_with_label("Kompilaatori seaded"); // Kompileeri->Kompilaatori seaded
GtkWidget *KompMenuKompileeri = gtk_menu_item_new_with_label("Kompileeri"); // Kompileeri->Kompileeri
GtkWidget *KompMenuKaivita = gtk_menu_item_new_with_label("Käivita programm"); // Kompileeri->Käivita programm
// Seaded menüü
GtkWidget *SeadedMenu = gtk_menu_new();
GtkWidget *SeadedMenuFont = gtk_menu_item_new_with_label("Teksti font"); // Seaded->Teksti font
GtkWidget *SeadedMenuSVarv = gtk_menu_item_new_with_label("Süntaksi värvimine"); // Seaded->Süntaksi värvimine
// Menüü nupud menu bar'i
gtk_menu_shell_append(GTK_MENU_SHELL(UI->MenuBar), FailMenuNupp);
gtk_menu_shell_append(GTK_MENU_SHELL(UI->MenuBar), KompMenuNupp);
gtk_menu_shell_append(GTK_MENU_SHELL(UI->MenuBar), SeadedMenuNupp);
// Menüüd nuppudesse
gtk_menu_item_set_submenu(GTK_MENU_ITEM(FailMenuNupp), FailMenu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(KompMenuNupp), KompMenu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(SeadedMenuNupp), SeadedMenu);
// Fail menüü
LisaMenuItem(UI, FailMenu, FailMenuUus, Uus, GDK_KEY_N, GDK_CONTROL_MASK); // Fail->Uus vahekaart
MenuSeparator(FailMenu);
LisaMenuItem(UI, FailMenu, FailMenuAva, Ava, GDK_KEY_O, GDK_CONTROL_MASK); // Fail->Ava
LisaMenuItem(UI, FailMenu, FailMenuSalvesta, Salvesta, GDK_KEY_S, GDK_CONTROL_MASK); // Fail->Salvesta
LisaMenuItem(UI, FailMenu, FailMenuSalvestaN, SalvestaNimega, GDK_KEY_S, GDK_CONTROL_MASK|GDK_MOD1_MASK); // Fail->Salvesta nimega
MenuSeparator(FailMenu);
LisaMenuItem(UI, FailMenu, FailMenuSulgeV, SulgeVahekaart, GDK_KEY_W, GDK_CONTROL_MASK); // Fail->Sulge vahekaart
MenuSeparator(FailMenu);
LisaMenuItem(UI, FailMenu, FailMenuValju, Valju, GDK_KEY_Q, GDK_CONTROL_MASK|GDK_SHIFT_MASK); // Fail->Välju
// Kompileeri menüü
LisaMenuItem(UI, KompMenu, KompMenuSeaded, KompilaatoriSeaded, 0, 0); // Kompileeri->Kompilaatori seaded
MenuSeparator(KompMenu);
LisaMenuItem(UI, KompMenu, KompMenuKompileeri, Kompileeri, GDK_KEY_C, GDK_CONTROL_MASK|GDK_SHIFT_MASK); // Kompileeri->Kompileeri
LisaMenuItem(UI, KompMenu, KompMenuKaivita, KaivitaProgramm, GDK_KEY_R, GDK_CONTROL_MASK|GDK_SHIFT_MASK); // Kompileeri->Käivita programm
// Seaded menüü
LisaMenuItem(UI, SeadedMenu, SeadedMenuFont, FontSeaded, 0, 0); // Seaded->Teksti font
LisaMenuItem(UI, SeadedMenu, SeadedMenuSVarv, SVarvSeaded, 0, 0);
//ToolBar
UI->ToolBar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(UI->ToolBar), GTK_TOOLBAR_ICONS);
GtkWidget *UndoIcon = gtk_image_new_from_icon_name("edit-undo", 5);
UI->Undo = gtk_tool_button_new(UndoIcon, "undo");
GtkWidget *RedoIcon = gtk_image_new_from_icon_name("edit-redo", 5);
UI->Redo = gtk_tool_button_new(RedoIcon, "redo");
//nupud toolbarile
gtk_toolbar_insert(GTK_TOOLBAR(UI->ToolBar), UI->Undo, -1);
gtk_toolbar_insert(GTK_TOOLBAR(UI->ToolBar), UI->Redo, -1);
// Pane kõik õiges järjekorras box'i
gtk_box_pack_start(GTK_BOX(UI->Box), UI->MenuBar, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(UI->Box), UI->ToolBar, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(UI->Box), UI->Notebook, TRUE, TRUE, 0);
return UI;
}
#ifndef UI_H
#define UI_H
#include "ceditor.h"
#include "tab.h"
#include "menubar.h"
#include "compiler.h"
#include "settings.h"
#define PEALKIRI "CEditor"
#define MenuSeparator(M) gtk_menu_shell_append(GTK_MENU_SHELL(M), gtk_separator_menu_item_new())
ui *LooUI();
#endif // UI_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment