Compare commits

..

No commits in common. "fcf6a47a1298a8df44279867968d2d4dffa52d23" and "b9f7c2eeebbe24c57dffbedfb7b9f9ed77146dd1" have entirely different histories.

15 changed files with 168 additions and 697 deletions

View File

@ -18,15 +18,11 @@ endif()
project(vis
VERSION 1.0
DESCRIPTION "Vi Scheduler (vis) is a simple TUI program built for managing your schedules in a calendar-like grid."
LANGUAGES CXX C)
LANGUAGES CXX)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
add_subdirectory(src)
find_library(NCURSES_LIB NAMES ncurses)
target_link_libraries(vis ncurses)
install(TARGETS vis DESTINATION bin)

View File

@ -2,58 +2,55 @@
Vi Scheduler (VIS) is a lightweight tool that brings a Vim-like calendar to your terminal. It allows you to quickly view and edit your schedule, appointments, and tasks without leaving your command-line interface.
Built using C++ and the Ncurses library, vis offers a fast and efficient way to manage your time in the terminal. It suppors various navigation and editing commands inspired by Vim, such as navigating between days or months, adding and deleting events.
Built using C++ and the Ncurses library, Vis offers a fast and efficient way to manage your time in the terminal. It suppors various navigation and editing commands inspired by Vim, such as navigating between days or months, adding and deleting events, and setting reminders.
![Vi Scheduler - Preview](./preview/preview.png)
# Features
- Vim-like navigation and editing commands
- Multiple view modes: month, week
# Dependencies
The following is a list of dependencies that your system needs in order to be able to run vis.
The following is a list of dependencies that your system needs in order to be able to run Vis.
- [The Ncurses library](https://invisible-island.net/ncurses/announce.html)
- [Moreutils](https://joeyh.name/code/moreutils/)
# Building & Installation
# Building
To build vis, simply clone this repository and run `mkdir build; cd build; cmake ..; make`
To build Vis, simply clone this repository and run `mkdir build; cd build; cmake ..; make`
Resulting binary will be generated inside the `/build/src/` folder called.
For installation, you can run `sudo make install` (from the /build directory)
# Usage
To start vis simply run the `vis` binary in your terminal alongside the name of the calendar file.
To start Vis simply run the `vis` binary in your terminal alongside the name of the calendar file.
For example: `vis school.cal`
This will open the default view mode (month) and display the current month's calendar. From there, you can use the following commands to navigate and edit the calendar:
- `h/j/k/l` - Move 1 day left/down/up/right
- `u/o` - Move 1 month left/right
- `g` - Go to the beginning of the month
- `gg` - Go to the beginning of the month
- `G` - Go to the end of the month
- `i` - Enter insert mode for selected day.
- `x` - Delete event from selected day.
- `y` - Copy event
- `p` - Paste event
- `w` - Write changes to file (i.e. save)
- `i` - Enter insert mode for the active day.
- `q` - Quit and save the calendar
# Todos
The following is a list of things that have been/still have to be completed.
- ~~Basic prototype with vipe (in memory only)~~
- ~~Finish all the basic shortcuts~~
- ~~Ability to write a calendar to a file~~
- ~~Ability to read a calendar from a file~~
- Basic prototype with vipe (in memory only)
- Finish all the basic shortcuts
- Ability to write a calendar to a file
- Ability to read a calendar from a file
- Alerting function for errors and issues
- Logging / Debug flag
- Read input from stdin
- ~~Shortcut: ability to clone an event into another day~~
- Set reminders
# Contributions
Contributions and feedback are welcome! If you have any ideas or suggestions for improving vis, please submit a pull request or open an issue on Github. Let's make the FOSS community better, together!
Contributions and feedback are welcome! If you have any ideas or suggestions for improving Vis, please submit a pull request or open an issue on Github. Let's make the FOSS community better, together!
# License

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

@ -1,12 +1,7 @@
add_subdirectory(engine)
add_subdirectory(calendar)
add_subdirectory(base64)
add_executable(vis main.cpp)
target_link_libraries(vis engine)
target_link_libraries(vis calendar)
target_link_libraries(vis base64)
set(installable_libs engine calendar base64)
install(TARGETS ${installable_libs} DESTINATION lib)

View File

@ -1,2 +0,0 @@
add_library(base64 SHARED base64.c)
install(FILES base64.h DESTINATION include)

View File

@ -1,209 +0,0 @@
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
/* Base64 encoder/decoder. Originally Apache file ap_base64.c
*/
#include <string.h>
#include "base64.h"
/* aaaack but it's fast and const should make it shared text page. */
static const unsigned char pr2six[256] =
{
/* ASCII table */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
int Base64decode_len(const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
register int nprbytes;
bufin = (const unsigned char *) bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
return nbytesdecoded + 1;
}
int Base64decode(char *bufplain, const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
register unsigned char *bufout;
register int nprbytes;
bufin = (const unsigned char *) bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
bufout = (unsigned char *) bufplain;
bufin = (const unsigned char *) bufcoded;
while (nprbytes > 4) {
*(bufout++) =
(unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
*(bufout++) =
(unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
*(bufout++) =
(unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
bufin += 4;
nprbytes -= 4;
}
/* Note: (nprbytes == 1) would be an error, so just ingore that case */
if (nprbytes > 1) {
*(bufout++) =
(unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
}
if (nprbytes > 2) {
*(bufout++) =
(unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
}
if (nprbytes > 3) {
*(bufout++) =
(unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
}
*(bufout++) = '\0';
nbytesdecoded -= (4 - nprbytes) & 3;
return nbytesdecoded;
}
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int Base64encode_len(int len)
{
return ((len + 2) / 3 * 4) + 1;
}
int Base64encode(char *encoded, const char *string, int len)
{
int i;
char *p;
p = encoded;
for (i = 0; i < len - 2; i += 3) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) |
((int) (string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) |
((int) (string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1)) {
*p++ = basis_64[((string[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = basis_64[((string[i] & 0x3) << 4) |
((int) (string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
*p++ = '\0';
return p - encoded;
}

View File

@ -1,101 +0,0 @@
/*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* ====================================================================
* Copyright (c) 1995-1999 The Apache Group. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* 4. The names "Apache Server" and "Apache Group" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the Apache Group
* for use in the Apache HTTP server project (http://www.apache.org/)."
*
* THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Group and was originally based
* on public domain software written at the National Center for
* Supercomputing Applications, University of Illinois, Urbana-Champaign.
* For more information on the Apache Group and the Apache HTTP server
* project, please see <http://www.apache.org/>.
*
*/
#ifndef _BASE64_H_
#define _BASE64_H_
#ifdef __cplusplus
extern "C" {
#endif
int Base64encode_len(int len);
int Base64encode(char * coded_dst, const char *plain_src,int len_plain_src);
int Base64decode_len(const char * coded_src);
int Base64decode(char * plain_dst, const char *coded_src);
#ifdef __cplusplus
}
#endif
#endif //_BASE64_H_

View File

@ -1,2 +1 @@
add_library(calendar SHARED calendar.cpp)
install(FILES calendar.hpp DESTINATION include)

View File

@ -11,13 +11,6 @@ calendar_information::calendar_information() {
current_month_days = Calendar::get_days_in_month(current_month, current_year);
}
calendar_information::calendar_information(int cday, int cmonth, int cyear) {
current_day = cday;
current_month = cmonth;
current_year = cyear;
current_month_days = Calendar::get_days_in_month(current_month, current_year);
}
int Calendar::get_days_in_month(int month, int year) {
tm date = {0};
date.tm_year = year - 1900;
@ -52,12 +45,7 @@ calendar_information Calendar::get_info() {
return this->info;
}
calendar_information Calendar::get_current_date() {
return this->current_date;
}
Calendar::Calendar(calendar_information *preinfo) {
this->current_date = calendar_information();
this->info = *preinfo;
if (preinfo != nullptr)
@ -65,28 +53,3 @@ Calendar::Calendar(calendar_information *preinfo) {
this->info = calendar_information();
}
// https://stackoverflow.com/questions/6054016/c-program-to-find-day-of-week-given-date
// RETURNS:
// Number of the given day in its week.
// Note: it starts with sunday being 0
int get_weekday(calendar_information *date_info) {
if (date_info == nullptr)
return 0;
int d = date_info->current_day;
int m = date_info->current_month;
int y = date_info->current_year;
return (d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7;
}
int datecmp(calendar_information *one, calendar_information *two) {
if (one->current_day != two->current_day) return 0;
if (one->current_month != two->current_month) return 0;
if (one->current_month_days != two->current_month_days) return 0;
if (one->current_year != two->current_year) return 0;
return 1;
}

View File

@ -10,7 +10,6 @@ struct calendar_information {
int current_year;
calendar_information();
calendar_information(int cday, int cmonth, int cyear);
};
const bool operator<(const calendar_information& first, const calendar_information& second) {
@ -24,17 +23,11 @@ class Calendar {
void set_day(int day);
void set_month(int month);
void set_year(int year);
calendar_information get_info();
calendar_information get_current_date();
Calendar(calendar_information *preinfo = nullptr);
private:
calendar_information info; // mutable date that can be changed
calendar_information current_date; // current date
calendar_information info;
};
int get_weekday(calendar_information *date_info = nullptr);
int datecmp(calendar_information *one, calendar_information *two);
#endif

View File

@ -1,2 +1 @@
add_library(engine SHARED engine.cpp)
install(FILES engine.hpp DESTINATION include)

View File

@ -1,12 +1,13 @@
#include <stdlib.h>
#include <string>
#include <string.h>
#include <ncurses.h>
#include <signal.h>
#include "engine.hpp"
Engine::Engine(int padding) {
Engine::Engine(int padding, calendar_view_mode view_mode) {
this->padding = padding;
this->view_mode = view_mode;
this->cells_table = std::vector<engine_child>();
calendar_information date_info = calendar_information();
this->calendar = new Calendar(&date_info);
@ -18,34 +19,31 @@ Engine::~Engine() {
}
void Engine::ui_draw(WINDOW *win) {
int screen_width, screen_height;
getmaxyx(win, screen_height, screen_width);
this->cells_table.clear();
if (screen_height < 25 || screen_width < 70) {
this->ui_warning_draw(win, "Window resolution too small, please resize it.");
return;
}
low_res_flag = 0;
box(win, 0, 0);
wrefresh(win);
keypad(win, TRUE);
keypad(stdscr, TRUE);
this->ui_month_draw(win);
switch (this->view_mode) {
case MONTH_VIEW:
this->ui_month_draw(win);
break;
case WEEK_VIEW:
this->ui_week_draw(win);
break;
case MONTHS_VIEW:
this->ui_months_draw(win);
break;
}
this->ui_top_draw(win);
this->ui_bottom_draw(win);
wrefresh(win);
}
void Engine::ui_warning_draw(WINDOW *win, const char *message) {
low_res_flag = 1;
mvwprintw(win, 0, 0, "%s", message);
wrefresh(win);
}
void Engine::ui_month_draw(WINDOW *win) {
calendar_information date_info = this->calendar->get_info();
int z = COLS - this->padding;
@ -54,35 +52,25 @@ void Engine::ui_month_draw(WINDOW *win) {
int x_location = this->padding + ((z/7) * (i%7));
int y_location = this->padding + (q/(date_info.current_month_days/7) * (i/7));
// check if day has an event
// TODO: Temporary solution
calendar_information tmp_date = date_info;
tmp_date.current_day = i+1;
if (this->events_map.count(tmp_date) > 0)
wattron(win, COLOR_PAIR(2));
calendar_information current_date = this->calendar->get_current_date();
if (datecmp(&current_date, &tmp_date))
wattron(win, COLOR_PAIR(3));
if (this->active_cell == i)
wattron(win, COLOR_PAIR(1));
std::string weekday_prefix = weekday_prefixes[get_weekday(&tmp_date)];
// mvwprintw(win, y_location, x_location, "D%d", i+1);
mvwprintw(win, y_location, x_location, "%s[%d]", weekday_prefix.c_str(), i+1);
wattroff(win, COLOR_PAIR(1));
wattroff(win, COLOR_PAIR(2));
wattroff(win, COLOR_PAIR(3));
if (this->active_cell == i) wattron(win, COLOR_PAIR(1));
mvwprintw(win, y_location, x_location, "D%d", i+1);
if (this->active_cell == i) wattroff(win, COLOR_PAIR(1));
}
}
void Engine::ui_week_draw(WINDOW *win) {
}
void Engine::ui_months_draw(WINDOW *win) {
}
void Engine::ui_top_draw(WINDOW *win) {
if (VIS_COLORING) wattron(win, COLOR_PAIR(1));
mvwprintw(win, 1, 1, "Vi Scheduler");
mvwprintw(win, 2, 1, "@0xdeadbeer");
if (VIS_COLORING) wattroff(win, COLOR_PAIR(1));
}
@ -91,29 +79,71 @@ void Engine::ui_bottom_draw(WINDOW *win) {
if (VIS_COLORING) wattron(win, COLOR_PAIR(1));
calendar_information date_info = this->calendar->get_info();
std::string current_view_mode = calendar_view_mode_str[this->view_mode];
mvwprintw(win, LINES-2, 1, "Year: %d, Month: %d, Day: %d\n", date_info.current_year, date_info.current_month, date_info.current_day);
mvwprintw(win, LINES-2, 1, "Year: %d, Month: %d, Day: %d, Mode: %s\n", date_info.current_year, date_info.current_month, date_info.current_day, current_view_mode.c_str());
if (VIS_COLORING) wattroff(win, COLOR_PAIR(1));
}
void Engine::input_handle(WINDOW *win) {
void Engine::input_handle_month(WINDOW *win) {
char key = getch();
if (key == ERR) return;
if (low_res_flag) return;
calendar_information date_info = this->calendar->get_info();
if (this->input_handle_universal(win, key))
return;
this->input_handle_month(win, key);
}
bool Engine::input_handle_universal(WINDOW *win, char key) {
int day;
int day, month, res;
switch (key) {
case 'i': { // TODO: Break down this monstrocity of a case
endwin();
case 'h':
if (this->calendar->get_info().current_day <= 1) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(--day);
--this->active_cell;
break;
case 'l':
if (this->calendar->get_info().current_day >= this->calendar->get_info().current_month_days) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(++day);
++this->active_cell;
break;
case 'j':
if (this->calendar->get_info().current_day+7 > this->calendar->get_info().current_month_days) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(day+7);
this->active_cell += 7;
break;
case 'k':
if (this->calendar->get_info().current_day-7 < 1) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(day-7);
this->active_cell -= 7;
break;
case 'u':
if (this->calendar->get_info().current_month <= 1) break;
month = this->calendar->get_info().current_month;
this->calendar->set_month(--month);
this->calendar->set_day(1);
this->active_cell = 0;
break;
case 'o':
if (this->calendar->get_info().current_month >= 12) break;
month = this->calendar->get_info().current_month;
this->calendar->set_month(++month);
this->calendar->set_day(1);
this->active_cell = 0;
break;
case 'i': {
int vipe_out[2], vipe_in[2];
char output_buffer[4096];
memset(output_buffer, 0, sizeof(output_buffer));
@ -142,102 +172,12 @@ bool Engine::input_handle_universal(WINDOW *win, char key) {
close(vipe_in[1]);
int nbytes = read(vipe_out[0], output_buffer, sizeof(output_buffer));
if (nbytes > 0)
this->events_map[this->calendar->get_info()] = output_buffer;
else
this->events_map.erase(this->calendar->get_info());
this->events_map[this->calendar->get_info()] = output_buffer;
}
wclear(win);
wrefresh(win);
break;
}
case 'x': {
calendar_information date_info = this->calendar->get_info();
this->events_map.erase(date_info);
break;
}
case 'w':
this->write_calendar();
break;
case 'q':
endwin();
this->calendar_file.close();
exit(EXIT_SUCCESS);
break;
case 'y':
this->clipboard_day = this->calendar->get_info();
break;
case 'p':
if (this->events_map.find(this->clipboard_day) == this->events_map.end())
break;
this->events_map[this->calendar->get_info()] = this->events_map[this->clipboard_day];
break;
default:
return false;
break;
}
return true;
}
void Engine::input_handle_month(WINDOW *win, char key) {
calendar_information date_info = this->calendar->get_info();
int day, month;
switch (key) {
case 'h':
if (this->calendar->get_info().current_day <= 1) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(--day);
--this->active_cell;
break;
case 'l':
if (this->calendar->get_info().current_day >= this->calendar->get_info().current_month_days) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(++day);
++this->active_cell;
break;
case 'j':
if (this->calendar->get_info().current_day+7 > this->calendar->get_info().current_month_days) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(day+7);
this->active_cell += 7;
break;
case 'k':
if (this->calendar->get_info().current_day-7 < 1) break;
day = this->calendar->get_info().current_day;
this->calendar->set_day(day-7);
this->active_cell -= 7;
break;
case 'u':
if (this->calendar->get_info().current_month <= 1) break;
month = this->calendar->get_info().current_month;
this->calendar->set_month(--month);
this->calendar->set_day(1);
this->active_cell = 0;
break;
case 'o':
if (this->calendar->get_info().current_month >= 12) break;
month = this->calendar->get_info().current_month;
this->calendar->set_month(++month);
this->calendar->set_day(1);
this->active_cell = 0;
break;
}
case 'g':
this->calendar->set_day(1);
this->active_cell = 0;
@ -246,92 +186,17 @@ void Engine::input_handle_month(WINDOW *win, char key) {
this->calendar->set_day(this->calendar->get_info().current_month_days);
this->active_cell = this->calendar->get_info().current_month_days-1;
break;
}
}
calendar_information Engine::parse_date(std::string date) {
char *token = strtok((char *) date.c_str(), ".");
std::vector<int> tokens;
while (token != NULL) {
try {
tokens.push_back(std::stoi(token));
} catch (...) {
std::cout << "Error parsing calendar file. Suspected incorrect format." << std::endl;
exit(EXIT_FAILURE);
}
token = strtok(NULL, ".");
case 't':
this->view_mode = WEEK_VIEW;
wclear(win);
break;
}
return calendar_information(tokens[0], tokens[1], tokens[2]);
}
void Engine::parse_line(std::string line) {
char *token = strtok((char *) line.c_str(), " ");
std::vector<std::string> tokens;
void Engine::input_handle_week(WINDOW *win) {
while (token != NULL) {
tokens.push_back(token);
token = strtok(NULL, " ");
}
if (tokens.size() != 2)
return;
// decode the event from base64 before adding it into the events_map
calendar_information event_date = this->parse_date(tokens[0]);
int decoded_length = Base64decode_len((const char *) tokens[1].c_str());
char *event_decoded = (char *) malloc(decoded_length);
Base64decode(event_decoded, tokens[1].c_str());
this->events_map[event_date] = event_decoded;
free(event_decoded);
}
void Engine::open_calendar(char *filename) {
this->calendar_file.open(filename, std::ios::in);
this->calendar_file_location = filename;
// If the file does not exist,
// we'll create and reopen it later ('write' shortcut)
if (this->calendar_file.fail())
return;
std::string line;
while (std::getline(this->calendar_file, line))
this->parse_line(line);
}
bool Engine::write_calendar() {
this->calendar_file.close();
this->calendar_file.open(this->calendar_file_location, std::ios::out | std::ios::trunc);
if (this->calendar_file.fail()) {
mvprintw(0, 0, "Error saving file.");
refresh();
getch();
return false;
}
for (auto const& event : this->events_map) {
std::stringstream output_line;
calendar_information date = event.first;
int encoded_length = Base64encode_len(event.second.length());
char *event_encoded = (char *) malloc(encoded_length);
Base64encode(event_encoded, event.second.c_str(), event.second.length());
output_line << date.current_day << ".";
output_line << date.current_month << ".";
output_line << date.current_year << " ";
output_line << event_encoded;
this->calendar_file << output_line.str() << std::endl;
free(event_encoded);
}
return true;
void Engine::input_handle_months(WINDOW *win) {
// TODO
}

View File

@ -2,58 +2,59 @@
#define ENGINE_HPP
#include <iostream>
#include <sstream>
#include <fstream>
#include <ncurses.h>
#include <vector>
// #include <unordered_map>
#include <map>
#include "../base64/base64.h"
#include "../calendar/calendar.hpp"
#include "../global/global.hpp"
std::string weekday_prefixes[] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
struct engine_child {
int x;
int y;
};
enum calendar_view_mode {
MONTH_VIEW = 0,
WEEK_VIEW,
MONTHS_VIEW
};
std::string calendar_view_mode_str[] = {
"MONTH_VIEW",
"WEEK_VIEW",
"MONTHS_VIEW"
};
// title: drawing engine
// description: use for drawing the TUI and interact with the cells
class Engine {
public:
Engine(int padding);
Engine(int padding = 10, calendar_view_mode view_mode = MONTH_VIEW);
~Engine();
void ui_draw(WINDOW *win);
void ui_warning_draw(WINDOW *win, const char *message);
void ui_month_draw(WINDOW *win);
void ui_week_draw(WINDOW *win);
void ui_months_draw(WINDOW *win);
void ui_bottom_draw(WINDOW *win);
void ui_top_draw(WINDOW *win);
bool input_block;
void input_handle(WINDOW* win);
bool input_handle_universal(WINDOW *win, char key);
void input_handle_month(WINDOW *win, char key);
calendar_information parse_date(std::string date);
void parse_line(std::string line);
void open_calendar(char *filename);
bool write_calendar();
void input_handle_month(WINDOW *win);
void input_handle_week(WINDOW *win);
void input_handle_months(WINDOW *win);
Calendar *calendar;
// std::unordered_map<calendar_information, std::string> events_map;
std::map<calendar_information, std::string> events_map;
int active_cell;
int padding; // GUI padding
calendar_view_mode view_mode;
int padding; // padding
private:
std::fstream calendar_file;
char *calendar_file_location;
calendar_information clipboard_day;
std::vector<engine_child> cells_table;
};
#endif

View File

@ -1,11 +1,8 @@
#ifndef VIS_GLOBAL
#define VIS_GLOBAL
#include <signal.h>
#include <ncurses.h>
#define VIS_COLORING has_colors() && can_change_color()
volatile sig_atomic_t winch_flag = 0; // DESCRIPTION: flags if the resolution of the terminal has changed
volatile sig_atomic_t low_res_flag = 0; // DESCRIPTION: flags if the resolution of the terminal is too small
#endif

View File

@ -6,51 +6,36 @@
#include "engine/engine.hpp"
#include "global/global.hpp"
Engine engine(10);
Engine engine = Engine(10, MONTH_VIEW);
WINDOW *main_win;
void sig_winch(int sig) {
winch_flag = 1;
if (isendwin()) return;
endwin();
wclear(main_win);
wrefresh(main_win);
wresize(main_win, LINES, COLS);
mvwin(main_win, 0, 0);
// redraw the TUI after the resize signal
engine.ui_draw(main_win);
flushinp();
return;
}
void signals() {
signal(SIGWINCH, sig_winch);
}
void print_help() {
std::cout << "\
VIS - Vim Scheduler\
\n\
\nUsage: vis [file]\
\n\
\nModes: \
\n - Month view (default): view the current month\
\n - Week view: view the current week\
\n - Months view: view the current year\
" << std::endl;
}
bool check_args(int argc, char **argv) {
if (argc != 2) {
print_help();
return false;
}
engine.open_calendar(argv[1]);
return true;
}
int main(int argc, char **argv) {
if (!check_args(argc, argv))
return EXIT_FAILURE;
int main() {
initscr();
refresh();
curs_set(0); // invisible cursor
noecho();
halfdelay(1);
refresh();
main_win = newwin(LINES, COLS, 0, 0);
@ -63,28 +48,21 @@ int main(int argc, char **argv) {
init_pair(0, COLOR_WHITE, COLOR_BLACK);
init_pair(1, COLOR_BLACK, COLOR_WHITE);
init_pair(2, COLOR_BLACK, COLOR_RED);
init_pair(3, COLOR_BLACK, COLOR_GREEN);
}
// handle required signals
signals();
for (;;) {
if (winch_flag) {
winch_flag = 0;
endwin();
wrefresh(main_win);
wclear(main_win);
wresize(main_win, LINES, COLS);
mvwin(main_win, 0, 0);
}
engine.ui_draw(main_win);
engine.input_handle(main_win);
}
if (engine.view_mode == MONTH_VIEW)
engine.input_handle_month(main_win);
if (engine.view_mode == WEEK_VIEW)
engine.input_handle_week(main_win);
else if (engine.view_mode == MONTHS_VIEW)
engine.input_handle_months(main_win);
}
endwin();