moved code here. still needs to update gh
This commit is contained in:
33
ncursescalander/backup/Makefile
Normal file
33
ncursescalander/backup/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
# Compiler and Flags
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -std=c11 -g
|
||||
LDFLAGS = -lncurses
|
||||
|
||||
# Source Files
|
||||
SRCS = main.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
# Output Binary
|
||||
TARGET = calendar
|
||||
|
||||
# Default Target
|
||||
all: $(TARGET)
|
||||
|
||||
# Build Target
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LDFLAGS)
|
||||
|
||||
# Object Files
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# Clean Target
|
||||
clean:
|
||||
rm -f $(OBJS) $(TARGET)
|
||||
|
||||
# Run Target
|
||||
run: $(TARGET)
|
||||
./$(TARGET)
|
||||
|
||||
# Phony Targets
|
||||
.PHONY: all clean run
|
||||
BIN
ncursescalander/backup/calendar
Executable file
BIN
ncursescalander/backup/calendar
Executable file
Binary file not shown.
326
ncursescalander/backup/main.c
Normal file
326
ncursescalander/backup/main.c
Normal file
@@ -0,0 +1,326 @@
|
||||
#include <ncurses.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define MAX_TITLE_LEN 50
|
||||
#define MAX_CALENDAR_LEN 30
|
||||
#define MAX_NOTES_LEN 256
|
||||
|
||||
void draw_calendar(int month, int year, int selected_day);
|
||||
void draw_day_view(int *day, int *month, int *year);
|
||||
void open_add_event_tui();
|
||||
void open_repeat_tui();
|
||||
|
||||
int main() {
|
||||
int ch, month, year, day = 1;
|
||||
time_t now;
|
||||
struct tm *local;
|
||||
|
||||
// Initialize ncurses
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
start_color();
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK); // Red color pair for the current time
|
||||
|
||||
// Get current date
|
||||
now = time(NULL);
|
||||
local = localtime(&now);
|
||||
month = local->tm_mon + 1;
|
||||
year = local->tm_year + 1900;
|
||||
day = local->tm_mday;
|
||||
|
||||
// Main loop
|
||||
while ((ch = getch()) != 'q') {
|
||||
bool redraw = false;
|
||||
switch (ch) {
|
||||
case KEY_LEFT:
|
||||
case 'j':
|
||||
if (day > 1) {
|
||||
day--;
|
||||
redraw = true;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case 'k':
|
||||
if (day < 31) { // Simplified for demo purposes
|
||||
day++;
|
||||
redraw = true;
|
||||
}
|
||||
break;
|
||||
case 'a': // 'a' for "Add Event"
|
||||
open_add_event_tui();
|
||||
redraw = true;
|
||||
break;
|
||||
case '\n': // Enter key to open the day view
|
||||
draw_day_view(&day, &month, &year);
|
||||
redraw = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Calendar View - Press 'a' to Add Event");
|
||||
draw_calendar(month, year, day);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// End ncurses mode
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void draw_calendar(int month, int year, int selected_day) {
|
||||
mvprintw(1, 0, "Month: %d, Year: %d", month, year);
|
||||
mvprintw(2, 0, "Su Mo Tu We Th Fr Sa");
|
||||
|
||||
// Placeholder for calendar drawing
|
||||
for (int i = 1; i <= 30; i++) { // Simplified example for 30 days
|
||||
if (i == selected_day) {
|
||||
attron(A_REVERSE); // Highlight the selected day
|
||||
}
|
||||
mvprintw(3 + (i / 7), (i % 7) * 3, "%2d", i);
|
||||
if (i == selected_day) {
|
||||
attroff(A_REVERSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_day_view(int *day, int *month, int *year) {
|
||||
time_t now;
|
||||
struct tm *local;
|
||||
int ch;
|
||||
bool redraw = true;
|
||||
|
||||
while (true) {
|
||||
if (redraw) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Day View");
|
||||
mvprintw(1, 0, "Date: %02d-%02d-%04d", *day, *month, *year);
|
||||
|
||||
// Draw the hours of the day
|
||||
for (int i = 0; i < 24; i++) {
|
||||
mvprintw(i + 3, 0, "%02d:00 |", i);
|
||||
mvhline(i + 3, 8, ' ', COLS - 8);
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
local = localtime(&now);
|
||||
|
||||
if (local->tm_mday == *day && (local->tm_mon + 1) == *month && (local->tm_year + 1900) == *year) {
|
||||
int current_hour = local->tm_hour;
|
||||
int current_minute = local->tm_min;
|
||||
|
||||
attron(COLOR_PAIR(1)); // Red color
|
||||
mvhline(current_hour + 3, 8, '-', COLS - 8);
|
||||
mvprintw(current_hour + 3, 0, "%02d:%02d |", current_hour, current_minute);
|
||||
attroff(COLOR_PAIR(1));
|
||||
}
|
||||
|
||||
refresh();
|
||||
redraw = false;
|
||||
}
|
||||
|
||||
nodelay(stdscr, TRUE); // Make getch non-blocking
|
||||
ch = getch();
|
||||
|
||||
if (ch == 'q') break; // Exit to Calendar View
|
||||
if (ch == KEY_LEFT || ch == 'j') {
|
||||
if (*day > 1) {
|
||||
(*day)--;
|
||||
} else {
|
||||
if (*month > 1) {
|
||||
(*month)--;
|
||||
} else {
|
||||
*month = 12;
|
||||
(*year)--;
|
||||
}
|
||||
*day = 31; // Simplified for demo purposes
|
||||
}
|
||||
redraw = true;
|
||||
} else if (ch == KEY_RIGHT || ch == 'k') {
|
||||
if (*day < 31) { // Simplified for demo purposes
|
||||
(*day)++;
|
||||
} else {
|
||||
*day = 1;
|
||||
if (*month < 12) {
|
||||
(*month)++;
|
||||
} else {
|
||||
*month = 1;
|
||||
(*year)++;
|
||||
}
|
||||
}
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
napms(1000);
|
||||
}
|
||||
|
||||
nodelay(stdscr, FALSE);
|
||||
}
|
||||
|
||||
void open_add_event_tui() {
|
||||
char title[MAX_TITLE_LEN] = "";
|
||||
char calendar[MAX_CALENDAR_LEN] = "";
|
||||
char notes[MAX_NOTES_LEN] = "";
|
||||
int ch;
|
||||
bool all_day = false;
|
||||
int start_day = 1, end_day = 1;
|
||||
int start_hour = 9, start_minute = 0;
|
||||
int end_hour = 10, end_minute = 0;
|
||||
int repeat_option = 0;
|
||||
char repeat_options[4][20] = {"Never", "Every Day", "Every Week", "Custom"};
|
||||
|
||||
int cursor_pos = 0;
|
||||
|
||||
while (true) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Add New Event");
|
||||
|
||||
// Title input
|
||||
mvprintw(2, 0, "Title: ");
|
||||
if (cursor_pos == 0) attron(A_REVERSE);
|
||||
mvprintw(2, 7, title);
|
||||
if (cursor_pos == 0) attroff(A_REVERSE);
|
||||
|
||||
// All-day toggle
|
||||
mvprintw(4, 0, "All Day: ");
|
||||
if (cursor_pos == 1) attron(A_REVERSE);
|
||||
mvprintw(4, 9, all_day ? "[X]" : "[ ]");
|
||||
if (cursor_pos == 1) attroff(A_REVERSE);
|
||||
|
||||
// Start day and time
|
||||
mvprintw(6, 0, "Start Day: %02d", start_day);
|
||||
mvprintw(7, 0, "Start Time: ");
|
||||
if (cursor_pos == 2) attron(A_REVERSE);
|
||||
mvprintw(7, 12, "%02d:%02d", start_hour, start_minute);
|
||||
if (cursor_pos == 2) attroff(A_REVERSE);
|
||||
|
||||
// End day and time
|
||||
mvprintw(9, 0, "End Day: %02d", end_day);
|
||||
mvprintw(10, 0, "End Time: ");
|
||||
if (cursor_pos == 3) attron(A_REVERSE);
|
||||
mvprintw(10, 10, "%02d:%02d", end_hour, end_minute);
|
||||
if (cursor_pos == 3) attroff(A_REVERSE);
|
||||
|
||||
// Repeat options
|
||||
mvprintw(12, 0, "Repeat: ");
|
||||
if (cursor_pos == 4) attron(A_REVERSE);
|
||||
mvprintw(12, 8, repeat_options[repeat_option]);
|
||||
if (cursor_pos == 4) attroff(A_REVERSE);
|
||||
|
||||
// Calendar name input
|
||||
mvprintw(14, 0, "Calendar: ");
|
||||
if (cursor_pos == 5) attron(A_REVERSE);
|
||||
mvprintw(14, 10, calendar);
|
||||
if (cursor_pos == 5) attroff(A_REVERSE);
|
||||
|
||||
// Notes input
|
||||
mvprintw(16, 0, "Notes: ");
|
||||
if (cursor_pos == 6) attron(A_REVERSE);
|
||||
mvprintw(17, 0, notes);
|
||||
if (cursor_pos == 6) attroff(A_REVERSE);
|
||||
|
||||
// Instructions
|
||||
mvprintw(19, 0, "Press 'q' to cancel, 's' to save");
|
||||
|
||||
refresh();
|
||||
|
||||
ch = getch();
|
||||
if (ch == 'q') break; // Exit without saving
|
||||
if (ch == 's') {
|
||||
// Here, you would normally save the event
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle navigation
|
||||
if (ch == KEY_DOWN || ch == 'j') {
|
||||
cursor_pos = (cursor_pos + 1) % 7;
|
||||
} else if (ch == KEY_UP || ch == 'k') {
|
||||
cursor_pos = (cursor_pos - 1 + 7) % 7;
|
||||
}
|
||||
|
||||
// Handle specific field input
|
||||
if (cursor_pos == 0 && ch != KEY_DOWN && ch != KEY_UP && ch != 's' && ch != 'q') {
|
||||
int len = strlen(title);
|
||||
if (ch == KEY_BACKSPACE || ch == 127) {
|
||||
if (len > 0) title[len - 1] = '\0';
|
||||
} else if (len < MAX_TITLE_LEN - 1) {
|
||||
title[len] = ch;
|
||||
title[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 1 && (ch == ' ' || ch == '\n')) {
|
||||
all_day = !all_day;
|
||||
} else if (cursor_pos == 2 && (ch == ' ' || ch == '\n')) {
|
||||
// Placeholder: Handle start day and time input
|
||||
} else if (cursor_pos == 3 && (ch == ' ' || ch == '\n')) {
|
||||
// Placeholder: Handle end day and time input
|
||||
} else if (cursor_pos == 4 && (ch == ' ' || ch == '\n')) {
|
||||
// Open repeat TUI
|
||||
open_repeat_tui();
|
||||
} else if (cursor_pos == 5 && ch != KEY_DOWN && ch != KEY_UP && ch != 's' && ch != 'q') {
|
||||
int len = strlen(calendar);
|
||||
if (ch == KEY_BACKSPACE || ch == 127) {
|
||||
if (len > 0) calendar[len - 1] = '\0';
|
||||
} else if (len < MAX_CALENDAR_LEN - 1) {
|
||||
calendar[len] = ch;
|
||||
calendar[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 6 && ch != KEY_DOWN && ch != KEY_UP && ch != 's' && ch != 'q') {
|
||||
int len = strlen(notes);
|
||||
if (ch == KEY_BACKSPACE || ch == 127) {
|
||||
if (len > 0) notes[len - 1] = '\0';
|
||||
} else if (len < MAX_NOTES_LEN - 1) {
|
||||
notes[len] = ch;
|
||||
notes[len + 1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void open_repeat_tui() {
|
||||
int ch;
|
||||
int cursor_pos = 0;
|
||||
|
||||
while (true) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Repeat Options");
|
||||
|
||||
mvprintw(2, 0, "1. Never");
|
||||
if (cursor_pos == 0) attron(A_REVERSE);
|
||||
mvprintw(2, 10, "Select");
|
||||
if (cursor_pos == 0) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(4, 0, "2. Every Day");
|
||||
if (cursor_pos == 1) attron(A_REVERSE);
|
||||
mvprintw(4, 10, "Select");
|
||||
if (cursor_pos == 1) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(6, 0, "3. Every Week");
|
||||
if (cursor_pos == 2) attron(A_REVERSE);
|
||||
mvprintw(6, 10, "Select");
|
||||
if (cursor_pos == 2) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(8, 0, "4. Custom");
|
||||
if (cursor_pos == 3) attron(A_REVERSE);
|
||||
mvprintw(8, 10, "Select");
|
||||
if (cursor_pos == 3) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(10, 0, "Press 'q' to return");
|
||||
|
||||
refresh();
|
||||
|
||||
ch = getch();
|
||||
if (ch == 'q') break; // Return to the add event TUI
|
||||
if (ch == KEY_DOWN || ch == 'j') {
|
||||
cursor_pos = (cursor_pos + 1) % 4;
|
||||
} else if (ch == KEY_UP || ch == 'k') {
|
||||
cursor_pos = (cursor_pos - 1 + 4) % 4;
|
||||
} else if (ch == '\n') {
|
||||
// Here, you would handle selection logic
|
||||
break; // Return after selection for now
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
ncursescalander/backup/main.o
Normal file
BIN
ncursescalander/backup/main.o
Normal file
Binary file not shown.
26
ncursescalander/build/Makefile
Normal file
26
ncursescalander/build/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Makefile for ncurses calendar app
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -I../include
|
||||
LDFLAGS = -lncurses -lsqlite3
|
||||
SRC_DIR = ../src
|
||||
BUILD_DIR = ../build
|
||||
|
||||
SRC_FILES = $(wildcard $(SRC_DIR)/*.c)
|
||||
OBJ_FILES = $(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(SRC_FILES))
|
||||
|
||||
TARGET = calendar_app
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ_FILES)
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(BUILD_DIR)/*.o $(TARGET)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
BIN
ncursescalander/build/add_event.o
Normal file
BIN
ncursescalander/build/add_event.o
Normal file
Binary file not shown.
BIN
ncursescalander/build/calendar.o
Normal file
BIN
ncursescalander/build/calendar.o
Normal file
Binary file not shown.
BIN
ncursescalander/build/calendar_app
Executable file
BIN
ncursescalander/build/calendar_app
Executable file
Binary file not shown.
BIN
ncursescalander/build/day_view.o
Normal file
BIN
ncursescalander/build/day_view.o
Normal file
Binary file not shown.
BIN
ncursescalander/build/main.o
Normal file
BIN
ncursescalander/build/main.o
Normal file
Binary file not shown.
BIN
ncursescalander/build/repeat_tui.o
Normal file
BIN
ncursescalander/build/repeat_tui.o
Normal file
Binary file not shown.
BIN
ncursescalander/databases/calendar_database.db
Normal file
BIN
ncursescalander/databases/calendar_database.db
Normal file
Binary file not shown.
29
ncursescalander/include/add_event.h
Normal file
29
ncursescalander/include/add_event.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef ADD_EVENT_H
|
||||
#define ADD_EVENT_H
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MAX_TITLE_LEN 50
|
||||
#define MAX_CALENDAR_LEN 30
|
||||
#define MAX_NOTES_LEN 256
|
||||
#define MAX_DATE_LEN 50
|
||||
|
||||
typedef struct {
|
||||
char title[MAX_TITLE_LEN];
|
||||
bool all_day;
|
||||
char start_date[MAX_DATE_LEN];
|
||||
char end_date[MAX_DATE_LEN];
|
||||
int start_hour, start_minute;
|
||||
int end_hour, end_minute;
|
||||
int repeat_option;
|
||||
char calendar[MAX_CALENDAR_LEN];
|
||||
char notes[MAX_NOTES_LEN];
|
||||
} Event;
|
||||
|
||||
Event *create_event();
|
||||
void save_event_to_db(sqlite3 *db, Event *event);
|
||||
sqlite3* open_database();
|
||||
void open_add_event_tui(sqlite3 *db);
|
||||
|
||||
#endif
|
||||
8
ncursescalander/include/calendar.h
Normal file
8
ncursescalander/include/calendar.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef CALENDAR_H
|
||||
#define CALENDAR_H
|
||||
|
||||
int is_leap_year(int year);
|
||||
int days_in_month(int month, int year);
|
||||
void draw_calendar(int month, int year, int selected_day);
|
||||
|
||||
#endif
|
||||
7
ncursescalander/include/day_view.h
Normal file
7
ncursescalander/include/day_view.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef DAY_VIEW_H
|
||||
#define DAY_VIEW_H
|
||||
|
||||
void draw_day_view(int *day, int *month, int *year);
|
||||
|
||||
#endif
|
||||
|
||||
7
ncursescalander/include/repeat_tui.h
Normal file
7
ncursescalander/include/repeat_tui.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef REPEAT_TUI_H
|
||||
#define REPEAT_TUI_H
|
||||
|
||||
void open_repeat_tui();
|
||||
|
||||
#endif
|
||||
|
||||
292
ncursescalander/src/add_event.c
Normal file
292
ncursescalander/src/add_event.c
Normal file
@@ -0,0 +1,292 @@
|
||||
#include "add_event.h"
|
||||
#include "repeat_tui.h"
|
||||
#include <ncurses.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <sqlite3.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Create and initialize a new event
|
||||
Event *create_event() {
|
||||
Event *event = (Event *)malloc(sizeof(Event));
|
||||
if (event) {
|
||||
memset(event, 0, sizeof(Event));
|
||||
strcpy(event->start_date, "01/01/2000");
|
||||
strcpy(event->end_date, "01/01/2000");
|
||||
event->start_hour = 9;
|
||||
event->start_minute = 0;
|
||||
event->end_hour = 10;
|
||||
event->end_minute = 0;
|
||||
event->repeat_option = 0;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
// Function to open the SQLite database
|
||||
|
||||
sqlite3* open_database() {
|
||||
char path[PATH_MAX];
|
||||
char base_dir[PATH_MAX];
|
||||
char db_path[PATH_MAX];
|
||||
|
||||
// Get the current working directory
|
||||
if (getcwd(path, sizeof(path)) != NULL) {
|
||||
printf("Current working directory: %s\n", path);
|
||||
|
||||
// Go up one directory level to the 'ncursescalander' directory
|
||||
strncpy(base_dir, path, sizeof(base_dir));
|
||||
dirname(base_dir);
|
||||
printf("Base directory (one level up): %s\n", base_dir);
|
||||
|
||||
// Calculate required size
|
||||
int required_size = snprintf(NULL, 0, "%s/databases/calendar_database.db", base_dir) + 1;
|
||||
if (required_size > (int)sizeof(db_path)) { // Cast to int for comparison
|
||||
fprintf(stderr, "Error: Path length exceeds buffer size.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Construct the final path to the database file
|
||||
snprintf(db_path, sizeof(db_path), "%s/databases/calendar_database.db", base_dir);
|
||||
printf("Final database path: %s\n", db_path);
|
||||
|
||||
sqlite3 *db;
|
||||
if (sqlite3_open(db_path, &db)) {
|
||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||
return NULL;
|
||||
} else {
|
||||
printf("Opened database successfully\n");
|
||||
return db;
|
||||
}
|
||||
} else {
|
||||
perror("getcwd() error");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to save an event to the SQLite database
|
||||
void save_event_to_db(sqlite3 *db, Event *event) {
|
||||
// Set default values if necessary
|
||||
if (strlen(event->title) == 0) {
|
||||
strcpy(event->title, "Untitled");
|
||||
}
|
||||
if (strlen(event->calendar) == 0) {
|
||||
strcpy(event->calendar, "");
|
||||
}
|
||||
if (strlen(event->notes) == 0) {
|
||||
strcpy(event->notes, "");
|
||||
}
|
||||
|
||||
// Prepare SQL statement
|
||||
char *sql = "INSERT INTO events (title, all_day, start_date, end_date, start_time, end_time, repeat_option, calendar, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
|
||||
sqlite3_stmt *stmt;
|
||||
|
||||
if (sqlite3_prepare_v2(db, sql, -1, &stmt, 0) == SQLITE_OK) {
|
||||
// Bind values to SQL statement
|
||||
sqlite3_bind_text(stmt, 1, event->title, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(stmt, 2, event->all_day);
|
||||
sqlite3_bind_text(stmt, 3, event->start_date, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 4, event->end_date, -1, SQLITE_STATIC);
|
||||
|
||||
// Format time as HH:MM
|
||||
char start_time[6];
|
||||
snprintf(start_time, sizeof(start_time), "%02d:%02d", event->start_hour, event->start_minute);
|
||||
sqlite3_bind_text(stmt, 5, start_time, -1, SQLITE_STATIC);
|
||||
|
||||
char end_time[6];
|
||||
snprintf(end_time, sizeof(end_time), "%02d:%02d", event->end_hour, event->end_minute);
|
||||
sqlite3_bind_text(stmt, 6, end_time, -1, SQLITE_STATIC);
|
||||
|
||||
sqlite3_bind_int(stmt, 7, event->repeat_option);
|
||||
sqlite3_bind_text(stmt, 8, event->calendar, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 9, event->notes, -1, SQLITE_STATIC);
|
||||
|
||||
// Execute the SQL statement
|
||||
if (sqlite3_step(stmt) != SQLITE_DONE) {
|
||||
fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
|
||||
} else {
|
||||
printf("Event saved successfully.\n");
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
} else {
|
||||
fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
|
||||
}
|
||||
}
|
||||
|
||||
// Function to display the Add Event TUI and handle user input
|
||||
void open_add_event_tui(sqlite3 *db) {
|
||||
Event *event = create_event();
|
||||
int ch;
|
||||
int cursor_pos = 0;
|
||||
bool exit = false;
|
||||
|
||||
while (!exit) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Add New Event");
|
||||
|
||||
// Title input
|
||||
mvprintw(2, 0, "Title: ");
|
||||
if (cursor_pos == 0) attron(A_REVERSE);
|
||||
mvprintw(2, 7, event->title);
|
||||
if (cursor_pos == 0) attroff(A_REVERSE);
|
||||
|
||||
// All-day toggle
|
||||
mvprintw(4, 0, "All Day: ");
|
||||
if (cursor_pos == 1) attron(A_REVERSE);
|
||||
mvprintw(4, 9, event->all_day ? "[X]" : "[ ]");
|
||||
if (cursor_pos == 1) attroff(A_REVERSE);
|
||||
|
||||
// Start date input
|
||||
mvprintw(6, 0, "Start Date: ");
|
||||
if (cursor_pos == 2) attron(A_REVERSE);
|
||||
mvprintw(6, 12, event->start_date);
|
||||
if (cursor_pos == 2) attroff(A_REVERSE);
|
||||
|
||||
// End date input
|
||||
mvprintw(8, 0, "End Date: ");
|
||||
if (cursor_pos == 3) attron(A_REVERSE);
|
||||
mvprintw(8, 10, event->end_date);
|
||||
if (cursor_pos == 3) attroff(A_REVERSE);
|
||||
|
||||
// Start time input
|
||||
mvprintw(10, 0, "Start Time: ");
|
||||
if (cursor_pos == 4) attron(A_REVERSE);
|
||||
mvprintw(10, 12, "%02d:%02d", event->start_hour, event->start_minute);
|
||||
if (cursor_pos == 4) attroff(A_REVERSE);
|
||||
|
||||
// End time input
|
||||
mvprintw(12, 0, "End Time: ");
|
||||
if (cursor_pos == 5) attron(A_REVERSE);
|
||||
mvprintw(12, 10, "%02d:%02d", event->end_hour, event->end_minute);
|
||||
if (cursor_pos == 5) attroff(A_REVERSE);
|
||||
|
||||
// Repeat options
|
||||
mvprintw(14, 0, "Repeat: ");
|
||||
if (cursor_pos == 6) attron(A_REVERSE);
|
||||
mvprintw(14, 8, "Choose..."); // Display the repeat choice interactively
|
||||
if (cursor_pos == 6) attroff(A_REVERSE);
|
||||
|
||||
// Calendar name input
|
||||
mvprintw(16, 0, "Calendar: ");
|
||||
if (cursor_pos == 7) attron(A_REVERSE);
|
||||
mvprintw(16, 10, event->calendar);
|
||||
if (cursor_pos == 7) attroff(A_REVERSE);
|
||||
|
||||
// Notes input
|
||||
mvprintw(18, 0, "Notes: ");
|
||||
if (cursor_pos == 8) attron(A_REVERSE);
|
||||
mvprintw(19, 0, event->notes);
|
||||
if (cursor_pos == 8) attroff(A_REVERSE);
|
||||
|
||||
// Instructions
|
||||
mvprintw(21, 0, "Esc: Cancel Ctrl+S: Save");
|
||||
|
||||
refresh();
|
||||
|
||||
ch = getch();
|
||||
switch (ch) {
|
||||
case 27: // ESC to cancel
|
||||
exit = true;
|
||||
break;
|
||||
case 19: // Ctrl+S to save (^S)
|
||||
save_event_to_db(db, event);
|
||||
exit = true; // Return to calendar view after saving
|
||||
break;
|
||||
case KEY_DOWN: // Navigate down
|
||||
cursor_pos = (cursor_pos + 1) % 9;
|
||||
break;
|
||||
case KEY_UP: // Navigate up
|
||||
cursor_pos = (cursor_pos - 1 + 9) % 9;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
case 'j': // Decrease minute
|
||||
if (cursor_pos == 4) {
|
||||
event->start_minute = (event->start_minute > 0) ? event->start_minute - 1 : 59;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_minute = (event->end_minute > 0) ? event->end_minute - 1 : 59;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case 'k': // Increase minute
|
||||
if (cursor_pos == 4) {
|
||||
event->start_minute = (event->start_minute < 59) ? event->start_minute + 1 : 0;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_minute = (event->end_minute < 59) ? event->end_minute + 1 : 0;
|
||||
}
|
||||
break;
|
||||
case KEY_SLEFT:
|
||||
case 'h': // Decrease hour (Shift+Left or 'h')
|
||||
if (cursor_pos == 4) {
|
||||
event->start_hour = (event->start_hour > 0) ? event->start_hour - 1 : 23;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_hour = (event->end_hour > 0) ? event->end_hour - 1 : 23;
|
||||
}
|
||||
break;
|
||||
case KEY_SRIGHT:
|
||||
case 'l': // Increase hour (Shift+Right or 'l')
|
||||
if (cursor_pos == 4) {
|
||||
event->start_hour = (event->start_hour < 23) ? event->start_hour + 1 : 0;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_hour = (event->end_hour < 23) ? event->end_hour + 1 : 0;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
if (cursor_pos == 1) {
|
||||
event->all_day = !event->all_day;
|
||||
} else if (cursor_pos == 6) {
|
||||
open_repeat_tui(); // Placeholder for opening the repeat TUI
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (cursor_pos == 0 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->title);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->title[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_TITLE_LEN - 1) {
|
||||
event->title[len] = ch;
|
||||
event->title[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 2 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->start_date);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->start_date[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_DATE_LEN - 1) {
|
||||
event->start_date[len] = ch;
|
||||
event->start_date[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 3 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->end_date);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->end_date[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_DATE_LEN - 1) {
|
||||
event->end_date[len] = ch;
|
||||
event->end_date[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 7 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->calendar);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->calendar[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_CALENDAR_LEN - 1) {
|
||||
event->calendar[len] = ch;
|
||||
event->calendar[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 8 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->notes);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->notes[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_NOTES_LEN - 1) {
|
||||
event->notes[len] = ch;
|
||||
event->notes[len + 1] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(event); // Free the allocated memory
|
||||
}
|
||||
225
ncursescalander/src/add_event.c.bak
Normal file
225
ncursescalander/src/add_event.c.bak
Normal file
@@ -0,0 +1,225 @@
|
||||
#include "add_event.h"
|
||||
#include "repeat_tui.h"
|
||||
#include <ncurses.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define MAX_TITLE_LEN 50
|
||||
#define MAX_CALENDAR_LEN 30
|
||||
#define MAX_NOTES_LEN 256
|
||||
#define MAX_DATE_LEN 50
|
||||
|
||||
typedef struct {
|
||||
char title[MAX_TITLE_LEN];
|
||||
bool all_day;
|
||||
char start_date[MAX_DATE_LEN];
|
||||
char end_date[MAX_DATE_LEN];
|
||||
int start_hour, start_minute;
|
||||
int end_hour, end_minute;
|
||||
int repeat_option;
|
||||
char calendar[MAX_CALENDAR_LEN];
|
||||
char notes[MAX_NOTES_LEN];
|
||||
} Event;
|
||||
|
||||
Event *create_event() {
|
||||
Event *event = (Event *)malloc(sizeof(Event));
|
||||
if (event) {
|
||||
memset(event, 0, sizeof(Event));
|
||||
strcpy(event->start_date, "01/01/2000");
|
||||
strcpy(event->end_date, "01/01/2000");
|
||||
event->start_hour = 9;
|
||||
event->start_minute = 0;
|
||||
event->end_hour = 10;
|
||||
event->end_minute = 0;
|
||||
event->repeat_option = 0;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
void save_event(Event *event) {
|
||||
FILE *file = fopen("events.txt", "a");
|
||||
if (file) {
|
||||
fprintf(file, "Title: %s\nAll Day: %d\nStart Date: %s\nEnd Date: %s\nStart: %02d:%02d\nEnd: %02d:%02d\nRepeat: %d\nCalendar: %s\nNotes: %s\n\n",
|
||||
event->title, event->all_day, event->start_date, event->end_date, event->start_hour, event->start_minute,
|
||||
event->end_hour, event->end_minute, event->repeat_option, event->calendar, event->notes);
|
||||
fclose(file);
|
||||
} else {
|
||||
mvprintw(23, 0, "Error saving event!"); // Error message
|
||||
refresh();
|
||||
getch(); // Pause to let the user see the error
|
||||
}
|
||||
}
|
||||
|
||||
void open_add_event_tui() {
|
||||
Event *event = create_event();
|
||||
int ch;
|
||||
int cursor_pos = 0;
|
||||
bool exit = false;
|
||||
|
||||
while (!exit) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Add New Event");
|
||||
|
||||
// Title input
|
||||
mvprintw(2, 0, "Title: ");
|
||||
if (cursor_pos == 0) attron(A_REVERSE);
|
||||
mvprintw(2, 7, event->title);
|
||||
if (cursor_pos == 0) attroff(A_REVERSE);
|
||||
|
||||
// All-day toggle
|
||||
mvprintw(4, 0, "All Day: ");
|
||||
if (cursor_pos == 1) attron(A_REVERSE);
|
||||
mvprintw(4, 9, event->all_day ? "[X]" : "[ ]");
|
||||
if (cursor_pos == 1) attroff(A_REVERSE);
|
||||
|
||||
// Start date input
|
||||
mvprintw(6, 0, "Start Date: ");
|
||||
if (cursor_pos == 2) attron(A_REVERSE);
|
||||
mvprintw(6, 12, event->start_date);
|
||||
if (cursor_pos == 2) attroff(A_REVERSE);
|
||||
|
||||
// End date input
|
||||
mvprintw(8, 0, "End Date: ");
|
||||
if (cursor_pos == 3) attron(A_REVERSE);
|
||||
mvprintw(8, 10, event->end_date);
|
||||
if (cursor_pos == 3) attroff(A_REVERSE);
|
||||
|
||||
// Start time input
|
||||
mvprintw(10, 0, "Start Time: ");
|
||||
if (cursor_pos == 4) attron(A_REVERSE);
|
||||
mvprintw(10, 12, "%02d:%02d", event->start_hour, event->start_minute);
|
||||
if (cursor_pos == 4) attroff(A_REVERSE);
|
||||
|
||||
// End time input
|
||||
mvprintw(12, 0, "End Time: ");
|
||||
if (cursor_pos == 5) attron(A_REVERSE);
|
||||
mvprintw(12, 10, "%02d:%02d", event->end_hour, event->end_minute);
|
||||
if (cursor_pos == 5) attroff(A_REVERSE);
|
||||
|
||||
// Repeat options
|
||||
mvprintw(14, 0, "Repeat: ");
|
||||
if (cursor_pos == 6) attron(A_REVERSE);
|
||||
mvprintw(14, 8, "Choose..."); // Display the repeat choice interactively
|
||||
if (cursor_pos == 6) attroff(A_REVERSE);
|
||||
|
||||
// Calendar name input
|
||||
mvprintw(16, 0, "Calendar: ");
|
||||
if (cursor_pos == 7) attron(A_REVERSE);
|
||||
mvprintw(16, 10, event->calendar);
|
||||
if (cursor_pos == 7) attroff(A_REVERSE);
|
||||
|
||||
// Notes input
|
||||
mvprintw(18, 0, "Notes: ");
|
||||
if (cursor_pos == 8) attron(A_REVERSE);
|
||||
mvprintw(19, 0, event->notes);
|
||||
if (cursor_pos == 8) attroff(A_REVERSE);
|
||||
|
||||
// Instructions
|
||||
mvprintw(21, 0, "Esc: Cancel Ctrl+S: Save");
|
||||
|
||||
refresh();
|
||||
|
||||
ch = getch();
|
||||
switch (ch) {
|
||||
case 27: // ESC to cancel
|
||||
exit = true;
|
||||
break;
|
||||
case 19: // Ctrl+S to save (^S)
|
||||
save_event(event);
|
||||
exit = true; // Return to calendar view after saving
|
||||
break;
|
||||
case KEY_DOWN: // Navigate down
|
||||
cursor_pos = (cursor_pos + 1) % 9;
|
||||
break;
|
||||
case KEY_UP: // Navigate up
|
||||
cursor_pos = (cursor_pos - 1 + 9) % 9;
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
case 'j': // Decrease minute
|
||||
if (cursor_pos == 4) {
|
||||
event->start_minute = (event->start_minute > 0) ? event->start_minute - 1 : 59;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_minute = (event->end_minute > 0) ? event->end_minute - 1 : 59;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case 'k': // Increase minute
|
||||
if (cursor_pos == 4) {
|
||||
event->start_minute = (event->start_minute < 59) ? event->start_minute + 1 : 0;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_minute = (event->end_minute < 59) ? event->end_minute + 1 : 0;
|
||||
}
|
||||
break;
|
||||
case KEY_SLEFT:
|
||||
case 'h': // Decrease hour (Shift+Left or 'h')
|
||||
if (cursor_pos == 4) {
|
||||
event->start_hour = (event->start_hour > 0) ? event->start_hour - 1 : 23;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_hour = (event->end_hour > 0) ? event->end_hour - 1 : 23;
|
||||
}
|
||||
break;
|
||||
case KEY_SRIGHT:
|
||||
case 'l': // Increase hour (Shift+Right or 'l')
|
||||
if (cursor_pos == 4) {
|
||||
event->start_hour = (event->start_hour < 23) ? event->start_hour + 1 : 0;
|
||||
} else if (cursor_pos == 5) {
|
||||
event->end_hour = (event->end_hour < 23) ? event->end_hour + 1 : 0;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\n':
|
||||
if (cursor_pos == 1) {
|
||||
event->all_day = !event->all_day;
|
||||
} else if (cursor_pos == 6) {
|
||||
open_repeat_tui(); // Placeholder for opening the repeat TUI
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (cursor_pos == 0 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->title);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->title[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_TITLE_LEN - 1) {
|
||||
event->title[len] = ch;
|
||||
event->title[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 2 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->start_date);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->start_date[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_DATE_LEN - 1) {
|
||||
event->start_date[len] = ch;
|
||||
event->start_date[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 3 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->end_date);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->end_date[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_DATE_LEN - 1) {
|
||||
event->end_date[len] = ch;
|
||||
event->end_date[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 7 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->calendar);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->calendar[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_CALENDAR_LEN - 1) {
|
||||
event->calendar[len] = ch;
|
||||
event->calendar[len + 1] = '\0';
|
||||
}
|
||||
} else if (cursor_pos == 8 && ch != KEY_DOWN && ch != KEY_UP) {
|
||||
int len = strlen(event->notes);
|
||||
if ((ch == KEY_BACKSPACE || ch == 127) && len > 0) {
|
||||
event->notes[len - 1] = '\0';
|
||||
} else if (isprint(ch) && len < MAX_NOTES_LEN - 1) {
|
||||
event->notes[len] = ch;
|
||||
event->notes[len + 1] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(event); // Free the allocated memory
|
||||
}
|
||||
56
ncursescalander/src/calendar.c
Normal file
56
ncursescalander/src/calendar.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "calendar.h"
|
||||
#include <ncurses.h>
|
||||
|
||||
// Function to determine if a year is a leap year
|
||||
int is_leap_year(int year) {
|
||||
if (year % 4 == 0) {
|
||||
if (year % 100 == 0) {
|
||||
if (year % 400 == 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Function to get the number of days in a given month and year
|
||||
int days_in_month(int month, int year) {
|
||||
switch (month) {
|
||||
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
|
||||
return 31;
|
||||
case 4: case 6: case 9: case 11:
|
||||
return 30;
|
||||
case 2:
|
||||
if (is_leap_year(year))
|
||||
return 29;
|
||||
else
|
||||
return 28;
|
||||
default:
|
||||
return 30; // Fallback, though we shouldn't hit this
|
||||
}
|
||||
}
|
||||
|
||||
void draw_calendar(int month, int year, int selected_day) {
|
||||
int days = days_in_month(month, year);
|
||||
|
||||
// Adjust selected_day if it exceeds the number of days in the month
|
||||
if (selected_day > days) {
|
||||
selected_day = days;
|
||||
}
|
||||
|
||||
mvprintw(1, 0, "Month: %d, Year: %d", month, year);
|
||||
mvprintw(2, 0, "Su Mo Tu We Th Fr Sa");
|
||||
|
||||
// Placeholder for calendar drawing
|
||||
for (int i = 1; i <= days; i++) {
|
||||
if (i == selected_day) {
|
||||
attron(A_REVERSE); // Highlight the selected day
|
||||
}
|
||||
mvprintw(3 + (i / 7), (i % 7) * 3, "%2d", i);
|
||||
if (i == selected_day) {
|
||||
attroff(A_REVERSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
127
ncursescalander/src/day_view.c
Normal file
127
ncursescalander/src/day_view.c
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "day_view.h"
|
||||
#include <ncurses.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_TITLE_LEN 50
|
||||
|
||||
typedef struct {
|
||||
char title[MAX_TITLE_LEN];
|
||||
int start_hour;
|
||||
int start_minute;
|
||||
int end_hour;
|
||||
int end_minute;
|
||||
int event_day;
|
||||
int event_month;
|
||||
int event_year;
|
||||
} DisplayEvent;
|
||||
|
||||
void load_events(DisplayEvent *events, int *count, int day, int month, int year) {
|
||||
FILE *file = fopen("events.txt", "r");
|
||||
if (file) {
|
||||
char line[256];
|
||||
int current_day, current_month, current_year;
|
||||
while (fgets(line, sizeof(line), file)) {
|
||||
if (sscanf(line, "Date: %d-%d-%d", ¤t_day, ¤t_month, ¤t_year) == 3) {
|
||||
if (current_day == day && current_month == month && current_year == year) {
|
||||
fgets(line, sizeof(line), file);
|
||||
sscanf(line, "Start: %02d:%02d", &events[*count].start_hour, &events[*count].start_minute);
|
||||
fgets(line, sizeof(line), file);
|
||||
sscanf(line, "End: %02d:%02d", &events[*count].end_hour, &events[*count].end_minute);
|
||||
fgets(line, sizeof(line), file);
|
||||
sscanf(line, "Title: %49[^\n]", events[*count].title);
|
||||
events[*count].event_day = current_day;
|
||||
events[*count].event_month = current_month;
|
||||
events[*count].event_year = current_year;
|
||||
(*count)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_day_view(int *day, int *month, int *year) {
|
||||
time_t now;
|
||||
struct tm *local;
|
||||
int ch;
|
||||
bool redraw = true;
|
||||
|
||||
DisplayEvent events[10];
|
||||
int event_count = 0;
|
||||
load_events(events, &event_count, *day, *month, *year);
|
||||
|
||||
while (true) {
|
||||
if (redraw) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Day View");
|
||||
mvprintw(1, 0, "Date: %02d-%02d-%04d", *day, *month, *year);
|
||||
|
||||
// Draw the hours of the day
|
||||
for (int i = 0; i < 24; i++) {
|
||||
mvprintw(i + 3, 0, "%02d:00 |", i);
|
||||
mvhline(i + 3, 8, ' ', COLS - 8);
|
||||
}
|
||||
|
||||
// Display events
|
||||
for (int i = 0; i < event_count; i++) {
|
||||
mvprintw(events[i].start_hour + 3, 10, "%s", events[i].title);
|
||||
mvhline(events[i].start_hour + 3, 10 + strlen(events[i].title), '-', COLS - 20);
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
local = localtime(&now);
|
||||
|
||||
if (local->tm_mday == *day && (local->tm_mon + 1) == *month && (local->tm_year + 1900) == *year) {
|
||||
int current_hour = local->tm_hour;
|
||||
int current_minute = local->tm_min;
|
||||
|
||||
attron(COLOR_PAIR(1)); // Red color
|
||||
mvhline(current_hour + 3, 8, '-', COLS - 8);
|
||||
mvprintw(current_hour + 3, 0, "%02d:%02d |", current_hour, current_minute);
|
||||
attroff(COLOR_PAIR(1));
|
||||
}
|
||||
|
||||
refresh();
|
||||
redraw = false;
|
||||
}
|
||||
|
||||
nodelay(stdscr, TRUE); // Make getch non-blocking
|
||||
ch = getch();
|
||||
|
||||
if (ch == 'q') break; // Exit to Calendar View
|
||||
if (ch == KEY_LEFT || ch == 'j') {
|
||||
if (*day > 1) {
|
||||
(*day)--;
|
||||
} else {
|
||||
if (*month > 1) {
|
||||
(*month)--;
|
||||
} else {
|
||||
*month = 12;
|
||||
(*year)--;
|
||||
}
|
||||
*day = 31; // Simplified for demo purposes
|
||||
}
|
||||
redraw = true;
|
||||
} else if (ch == KEY_RIGHT || ch == 'k') {
|
||||
if (*day < 31) { // Simplified for demo purposes
|
||||
(*day)++;
|
||||
} else {
|
||||
*day = 1;
|
||||
if (*month < 12) {
|
||||
(*month)++;
|
||||
} else {
|
||||
*month = 1;
|
||||
(*year)++;
|
||||
}
|
||||
}
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
napms(1000);
|
||||
}
|
||||
|
||||
nodelay(stdscr, FALSE);
|
||||
}
|
||||
|
||||
106
ncursescalander/src/main.c
Normal file
106
ncursescalander/src/main.c
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <ncurses.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "calendar.h"
|
||||
#include "day_view.h"
|
||||
#include "add_event.h"
|
||||
|
||||
int main() {
|
||||
int ch, month, year, day = 1;
|
||||
time_t now;
|
||||
struct tm *local;
|
||||
|
||||
// Open the SQLite database
|
||||
sqlite3 *db = open_database();
|
||||
if (db == NULL) {
|
||||
return 1; // Exit if the database can't be opened
|
||||
}
|
||||
|
||||
// Initialize ncurses
|
||||
initscr();
|
||||
cbreak();
|
||||
noecho();
|
||||
keypad(stdscr, TRUE);
|
||||
start_color();
|
||||
init_pair(1, COLOR_RED, COLOR_BLACK); // Red color pair for the current time
|
||||
|
||||
// Get current date
|
||||
now = time(NULL);
|
||||
local = localtime(&now);
|
||||
month = local->tm_mon + 1;
|
||||
year = local->tm_year + 1900;
|
||||
day = local->tm_mday;
|
||||
|
||||
// Main loop
|
||||
while ((ch = getch()) != 'q') {
|
||||
int days_in_current_month = days_in_month(month, year);
|
||||
bool redraw = false;
|
||||
|
||||
switch (ch) {
|
||||
case KEY_LEFT:
|
||||
case 'j':
|
||||
if (day > 1) {
|
||||
day--;
|
||||
redraw = true;
|
||||
}
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case 'k':
|
||||
if (day < days_in_current_month) {
|
||||
day++;
|
||||
redraw = true;
|
||||
}
|
||||
break;
|
||||
case 'a': // 'a' for "Add Event"
|
||||
open_add_event_tui(db); // Pass the database connection here
|
||||
redraw = true;
|
||||
break;
|
||||
case '\n': // Enter key to open the day view
|
||||
draw_day_view(&day, &month, &year);
|
||||
redraw = true;
|
||||
break;
|
||||
case 'h': // 'h' for previous month
|
||||
case KEY_SLEFT: // Left Shift for previous month
|
||||
if (month > 1) {
|
||||
month--;
|
||||
} else {
|
||||
month = 12;
|
||||
year--;
|
||||
}
|
||||
// Adjust the day if it exceeds the number of days in the new month
|
||||
if (day > days_in_month(month, year)) {
|
||||
day = days_in_month(month, year);
|
||||
}
|
||||
redraw = true;
|
||||
break;
|
||||
case 'l': // 'l' for next month
|
||||
case KEY_SRIGHT: // Right Shift for next month
|
||||
if (month < 12) {
|
||||
month++;
|
||||
} else {
|
||||
month = 1;
|
||||
year++;
|
||||
}
|
||||
// Adjust the day if it exceeds the number of days in the new month
|
||||
if (day > days_in_month(month, year)) {
|
||||
day = days_in_month(month, year);
|
||||
}
|
||||
redraw = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Calendar View - Press 'a' to Add Event");
|
||||
draw_calendar(month, year, day);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// Close the SQLite database connection
|
||||
sqlite3_close(db);
|
||||
|
||||
// End ncurses mode
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
||||
48
ncursescalander/src/repeat_tui.c
Normal file
48
ncursescalander/src/repeat_tui.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <ncurses.h>
|
||||
#include "repeat_tui.h"
|
||||
|
||||
void open_repeat_tui() {
|
||||
int ch;
|
||||
int cursor_pos = 0;
|
||||
|
||||
while (true) {
|
||||
clear();
|
||||
mvprintw(0, 0, "Repeat Options");
|
||||
|
||||
mvprintw(2, 0, "1. Never");
|
||||
if (cursor_pos == 0) attron(A_REVERSE);
|
||||
mvprintw(2, 10, "Select");
|
||||
if (cursor_pos == 0) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(4, 0, "2. Every Day");
|
||||
if (cursor_pos == 1) attron(A_REVERSE);
|
||||
mvprintw(4, 10, "Select");
|
||||
if (cursor_pos == 1) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(6, 0, "3. Every Week");
|
||||
if (cursor_pos == 2) attron(A_REVERSE);
|
||||
mvprintw(6, 10, "Select");
|
||||
if (cursor_pos == 2) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(8, 0, "4. Every Other Day");
|
||||
if (cursor_pos == 3) attron(A_REVERSE);
|
||||
mvprintw(8, 18, "Select");
|
||||
if (cursor_pos == 3) attroff(A_REVERSE);
|
||||
|
||||
mvprintw(10, 0, "Press 'q' to return");
|
||||
|
||||
refresh();
|
||||
|
||||
ch = getch();
|
||||
if (ch == 'q') break; // Return to the add event TUI
|
||||
if (ch == KEY_DOWN || ch == 'j') {
|
||||
cursor_pos = (cursor_pos + 1) % 4;
|
||||
} else if (ch == KEY_UP || ch == 'k') {
|
||||
cursor_pos = (cursor_pos - 1 + 4) % 4;
|
||||
} else if (ch == '\n') {
|
||||
// Here, you would handle selection logic
|
||||
break; // Return after selection for now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user