G

Untitled

public
Guest Jan 10, 2025 Never 45
Clone
Plaintext paste1.txt 280 lines (224 loc) | 10.01 KB
1
#include <iostream>
2
#include <string>
3
#include <map>
4
#include <sstream>
5
#include <sys/socket.h>
6
#include <arpa/inet.h>
7
#include <unistd.h>
8
#include <gtk/gtk.h>
9
10
#define PORT 8080
11
12
int clientSocket;
13
bool isConnected = false;
14
15
int selectedDay = 1;
16
int selectedMonth = 0;
17
int selectedYear = 2024;
18
19
// Będziemy pamiętać o wydarzeniach lokalnie,
20
// by móc je łatwo zaznaczać w kalendarzu.
21
std::map<std::string, std::string> localCalendar;
22
23
// Referencja do GtkCalendar i do etykiety informacyjnej
24
GtkWidget *calendarWidget = nullptr;
25
GtkWidget *infoLabel = nullptr;
26
27
// Pomocnicza funkcja do zaznaczania dni w kalendarzu
28
// w których istnieją wydarzenia.
29
void updateCalendarMarks() {
30
// Czyścimy dotychczasowe zaznaczenia
31
gtk_calendar_clear_marks(GTK_CALENDAR(calendarWidget));
32
33
34
// Dla każdego wpisu w localCalendar parsujemy datę i zaznaczamy w kalendarzu
35
for (auto &pair : localCalendar) {
36
// format daty: YYYY-MM-DD
37
std::string dateStr = pair.first;
38
// event: pair.second
39
40
int year, month, day;
41
if (sscanf(dateStr.c_str(), "%d-%d-%d", &year, &month, &day) == 3) {
42
43
g_print("Year: %d, Month: %d, Day: %d\n", year, month + 1, day);
44
45
46
47
// Uwaga: w GtkCalendar miesiące liczone są od 0,
48
// a lata musimy podawać normalnie (np. 2025).
49
// Dni również są 1-based, więc day jest OK.
50
// Zaznaczamy dzień
51
// Jeżeli chcemy ograniczyć się tylko do bieżącego widoku miesiąca,
52
// to można sprawdzić, czy (year,month) == (aktualnyRok, aktualnyMiesiac),
53
// ale tutaj zaznaczmy wszystkie.
54
55
56
gtk_calendar_mark_day(GTK_CALENDAR(calendarWidget), day);
57
}
58
59
}
60
}
61
62
// Funkcja wywoływana przy zmianie dnia w kalendarzu (kliknięcie)
63
extern "C" void on_calendar_day_selected(GtkCalendar *calendar, gpointer user_data) {
64
// Pobieramy aktualnie wybraną datę
65
guint year, month, day;
66
gtk_calendar_get_date(calendar, &year, &month, &day);
67
// month jest 0-based
68
69
gtk_calendar_get_date(calendar, (guint*)&selectedYear, (guint*)&selectedMonth, (guint*)&selectedDay);
70
selectedMonth += 1;
71
72
73
char dateBuffer[11];
74
snprintf(dateBuffer, sizeof(dateBuffer), "%04u-%02u-%02u", year, month+1, day);
75
std::string selectedDate = dateBuffer;
76
77
auto it = localCalendar.find(selectedDate);
78
if (it != localCalendar.end()) {
79
// Mamy wydarzenie
80
std::string msg = "Wydarzenie: " + it->second;
81
gtk_label_set_text(GTK_LABEL(infoLabel), msg.c_str());
82
} else {
83
gtk_label_set_text(GTK_LABEL(infoLabel), "Brak wydarzenia w tym dniu.");
84
}
85
}
86
87
// Funkcja obsługująca przycisk "Connect to Server"
88
extern "C" void on_connect_button_clicked(GtkWidget *widget, gpointer data) {
89
if (isConnected) {
90
gtk_label_set_text(GTK_LABEL(data), "Already connected!");
91
return;
92
}
93
94
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
95
if (clientSocket < 0) {
96
gtk_label_set_text(GTK_LABEL(data), "Socket creation failed!");
97
return;
98
}
99
100
sockaddr_in serverAddress;
101
serverAddress.sin_family = AF_INET;
102
serverAddress.sin_port = htons(PORT);
103
inet_pton(AF_INET, "127.0.0.1", &serverAddress.sin_addr);
104
105
if (connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
106
gtk_label_set_text(GTK_LABEL(data), "Connection failed!");
107
close(clientSocket);
108
return;
109
}
110
111
gtk_label_set_text(GTK_LABEL(data), "Connected to server!");
112
isConnected = true;
113
}
114
115
// Funkcja obsługująca przycisk "Add Event"
116
extern "C" void on_add_event_button_clicked(GtkWidget *widget, gpointer data) {
117
GtkWidget **widgets = (GtkWidget **)data;
118
GtkWidget *eventEntry = widgets[0];
119
GtkWidget *dateEntry = widgets[1];
120
GtkWidget *statusLabel = widgets[2];
121
122
if (!isConnected) {
123
gtk_label_set_text(GTK_LABEL(statusLabel), "Connect to server first!");
124
return;
125
}
126
127
const char *eventText = gtk_entry_get_text(GTK_ENTRY(eventEntry));
128
const char *dateText = gtk_entry_get_text(GTK_ENTRY(dateEntry));
129
130
if (strlen(eventText) == 0 || strlen(dateText) == 0) {
131
gtk_label_set_text(GTK_LABEL(statusLabel), "Enter both date and event!");
132
return;
133
}
134
135
// Komunikat do serwera
136
std::string fullEventText = "ADD " + std::string(dateText) + " " + std::string(eventText);
137
send(clientSocket, fullEventText.c_str(), fullEventText.size(), 0);
138
139
// Odczyt odpowiedzi
140
char buffer[1024] = {0};
141
int bytesRead = read(clientSocket, buffer, sizeof(buffer));
142
if (bytesRead > 0) {
143
gtk_label_set_text(GTK_LABEL(statusLabel), buffer);
144
} else {
145
gtk_label_set_text(GTK_LABEL(statusLabel), "Failed to add event!");
146
}
147
148
// Dodajemy do lokalnej struktury i odświeżamy kalendarz
149
localCalendar[dateText] = eventText;
150
updateCalendarMarks();
151
152
// Czyścimy pola
153
gtk_entry_set_text(GTK_ENTRY(eventEntry), "");
154
gtk_entry_set_text(GTK_ENTRY(dateEntry), "");
155
}
156
157
// Funkcja obsługująca przycisk "View Events"
158
extern "C" void on_view_events_button_clicked(GtkWidget *widget, gpointer data) {
159
GtkWidget *statusLabel = GTK_WIDGET(data);
160
161
if (!isConnected) {
162
gtk_label_set_text(GTK_LABEL(statusLabel), "Connect to server first!");
163
return;
164
}
165
166
const char *viewCommand = "VIEW";
167
send(clientSocket, viewCommand, strlen(viewCommand), 0);
168
169
char buffer[1024] = {0};
170
int bytesRead = read(clientSocket, buffer, sizeof(buffer));
171
if (bytesRead > 0) {
172
// Wyświetlamy w statusLabel pełną listę
173
gtk_label_set_text(GTK_LABEL(statusLabel), buffer);
174
175
// Parsujemy to, co przyszło, i aktualizujemy localCalendar
176
localCalendar.clear();
177
std::stringstream ss(buffer);
178
std::string line;
179
while (std::getline(ss, line)) {
180
// Linia ma format: YYYY-MM-DD: event
181
// Przykład: 2025-01-10: Urodziny babci
182
if (line.find(":") != std::string::npos) {
183
auto pos = line.find(":");
184
std::string datePart = line.substr(0, pos);
185
std::string eventPart = line.substr(pos + 2); // omijamy ": " (2 znaki)
186
if (!datePart.empty()) {
187
localCalendar[datePart] = eventPart;
188
}
189
}
190
}
191
updateCalendarMarks();
192
193
} else {
194
gtk_label_set_text(GTK_LABEL(statusLabel), "Failed to retrieve events!");
195
}
196
}
197
198
// Funkcja obsługująca przycisk "Disconnect"
199
extern "C" void on_exit_button_clicked(GtkWidget *widget, gpointer data) {
200
if (isConnected) {
201
const char *exitCommand = "EXIT";
202
send(clientSocket, exitCommand, strlen(exitCommand), 0);
203
close(clientSocket);
204
isConnected = false;
205
gtk_label_set_text(GTK_LABEL(data), "Disconnected.");
206
} else {
207
gtk_label_set_text(GTK_LABEL(data), "No active connection.");
208
}
209
}
210
211
// Główna funkcja programu
212
int main(int argc, char *argv[]) {
213
gtk_init(&argc, &argv);
214
215
// Główne okno
216
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
217
gtk_window_set_title(GTK_WINDOW(window), "Calendar Client GUI");
218
gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);
219
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
220
221
// Główny kontener pionowy
222
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
223
gtk_container_add(GTK_CONTAINER(window), vbox);
224
225
// Etykieta statusu/informacji
226
infoLabel = gtk_label_new("Status: Disconnected");
227
gtk_box_pack_start(GTK_BOX(vbox), infoLabel, FALSE, FALSE, 0);
228
229
// Kalendarz
230
calendarWidget = gtk_calendar_new();
231
gtk_calendar_set_display_options(
232
GTK_CALENDAR(calendarWidget),
233
static_cast<GtkCalendarDisplayOptions>(
234
GTK_CALENDAR_SHOW_HEADING
235
| GTK_CALENDAR_SHOW_DAY_NAMES
236
| GTK_CALENDAR_SHOW_WEEK_NUMBERS
237
)
238
);
239
240
// Gdy użytkownik kliknie w dzień w kalendarzu
241
g_signal_connect(calendarWidget, "day-selected",
242
G_CALLBACK(on_calendar_day_selected), nullptr);
243
244
gtk_box_pack_start(GTK_BOX(vbox), calendarWidget, FALSE, FALSE, 0);
245
246
// Pola do wpisywania daty i wydarzenia
247
GtkWidget *dateEntry = gtk_entry_new();
248
gtk_entry_set_placeholder_text(GTK_ENTRY(dateEntry), "Enter date (YYYY-MM-DD)");
249
gtk_box_pack_start(GTK_BOX(vbox), dateEntry, FALSE, FALSE, 0);
250
251
GtkWidget *eventEntry = gtk_entry_new();
252
gtk_entry_set_placeholder_text(GTK_ENTRY(eventEntry), "Enter event");
253
gtk_box_pack_start(GTK_BOX(vbox), eventEntry, FALSE, FALSE, 0);
254
255
// Przyciski
256
GtkWidget *connectButton = gtk_button_new_with_label("Connect to Server");
257
GtkWidget *addEventButton = gtk_button_new_with_label("Add Event");
258
GtkWidget *viewEventsButton = gtk_button_new_with_label("View Events");
259
GtkWidget *exitButton = gtk_button_new_with_label("Disconnect");
260
261
gtk_box_pack_start(GTK_BOX(vbox), connectButton, FALSE, FALSE, 0);
262
gtk_box_pack_start(GTK_BOX(vbox), addEventButton, FALSE, FALSE, 0);
263
gtk_box_pack_start(GTK_BOX(vbox), viewEventsButton, FALSE, FALSE, 0);
264
gtk_box_pack_start(GTK_BOX(vbox), exitButton, FALSE, FALSE, 0);
265
266
// Tablica wskaźników do przekazania w callbacku (wygoda)
267
GtkWidget *widgets[3] = { eventEntry, dateEntry, infoLabel };
268
269
// Przypinamy sygnały
270
g_signal_connect(connectButton, "clicked", G_CALLBACK(on_connect_button_clicked), infoLabel);
271
g_signal_connect(addEventButton, "clicked", G_CALLBACK(on_add_event_button_clicked), widgets);
272
g_signal_connect(viewEventsButton, "clicked", G_CALLBACK(on_view_events_button_clicked), infoLabel);
273
g_signal_connect(exitButton, "clicked", G_CALLBACK(on_exit_button_clicked), infoLabel);
274
275
// Wyświetlamy wszystko
276
gtk_widget_show_all(window);
277
gtk_main();
278
279
return 0;
280
}