All pastes #2064859 Raw Edit

main.cc - Birthdaydb

public cpp v1 · immutable
#2064859 ·published 2011-05-19 16:16 UTC
rendered paste body
////////////////////////////////////////////////////////////////////////// @file main.cc/// @author Kevin P. Rowe/// @date May 13, 2011/// @version 0.99/// @brief Main application./// @details Contains basically two compilation paths, one for curses/// interface, and one for standard C++ I/O if curses is not found or/// specifically disabled. Configure with --disable-curses to force/// curses support off. The program loads a data file (defaults to:/// "data/friendFile") into memory and displays information about a/// people and their birthdays. The data file should be in the following/// format:/// @code/// Kevin Rowe/// 111-555-1212/// 5/21/// Someone Else/// 222-555-1212/// 4/1/// @endcode////// @note The date is in format 'mm/dd' for the birthday. Make sure you/// use a forward slash ('/') for the separator.///////////////////////////////////////////////////////////////////////#include <iostream>#include <fstream>#include <sstream>#include <string>#include <cstring>#include "config.h"#include "node.h"#include "bdaybook.h"#ifdef HAVE_CURSES_H#include <curses.h>#undef clear#endif#ifdef HAVE_NCURSES_H#include <ncurses.h>#undef clear#endif#if defined( HAVE_CURSES_H ) || defined( HAVE_NCURSES_H )#define USE_CURSES 1#else#define USE_CURSES 0#endifusing namespace std;/// The createNode function./// Creates a new dynamic node of type @e bdayNode and returns a/// pointer to it./// @param name string name of person/// @param phone string phone number/// @param month int numeric month/// @param day int numeric day/// @return pointer to new bdayNode objectbdayNodePtr createNode( string name, string phone, int month , int day );/// printMenu function. Convenience function to save space. Prints menu/// using stdout.void printMenu();/// addNode function. Convenience function to save space. Gets input/// from stdin, creates a bdayNode object and adds it to BDayList @e l.void addNode( BDayList &l );#if defined( HAVE_CURSES_H ) || defined( HAVE_NCURSES_H )/// genCursesMenu function. Creates the curses menu on curses window/// @e scr. Uses color if available./// @todo Do screen bounds checking to make sure menu fits on screen/// properly.void genCursesMenu( WINDOW *scr );/// create_newwin function. Creates a new curses window with dimensions/// given and prints a border around it./// @return pointer to new WINDOW objectWINDOW *create_newwin( int, int, int, int );/// destroy_win function. Destroys window object @e local_win./// @note This does not clear window content, please do that before/// calling this function.void destroy_win(WINDOW *local_win);#endifint main( int argc, char *argv[] ){    // Some initial main variables. They are reused in various places,    // however their names always coincide with their use.    string filename = "data/friendFile"; // default file to load    string name, phone, date;    stringstream inDate;    int month, day, found;    BDayList list;    bdayNodePtr newNode;    char choice;    int cchoice;    if ( argc > 1 ) // Allow specifying a different filename on command                    // line.    {        if ( !strcmp( "-f", argv[1]))        {            filename = argv[2];        }    }    fstream file;    file.open( filename.c_str(), fstream::in );    if ( file.fail() )    {        cout << "Error opening file \"" << filename << "\"!" << endl;        return 1;    }    while ( file.good() ) // Load in the main DB file    {            getline( file, name );            getline( file, phone );            getline( file, date );            inDate.str( date );            inDate >> month;            inDate.ignore( 1, '/' );            inDate >> day;            if ( !file.eof() )            {                newNode = createNode( name, phone, month, day );                list.insert( newNode );            }            inDate.clear();    }    file.close();    list.sort();    bool loopVar = true;    bool *map;#if USE_CURSES    // Do some curses initialization stuff if it's enabled    initscr();    noecho();    cbreak();    nonl();    intrflush( stdscr, FALSE );    keypad( stdscr, TRUE );    int pminrow = 0;    int pmincol = 0;    int sminrow = 2;    int smaxrow = LINES - 2;    int smincol = 0;    int smaxcol = COLS - 3;    char inName[30];    char inPhone[20];    char winDate[11];    bool monthMode = false;    int setMonth;    string fName, fPhone;    stringstream fBirthday;    WINDOW *popupWin, *mainPad, *rightWin;#endif    while ( loopVar ) // Main application loop    {#if USE_CURSES // Curses I/O if enabled        // Curses window pointers        mainPad = newpad( list.getSize(), 44 );        if (has_colors())            {                start_color();                init_pair(1, COLOR_RED,     COLOR_BLACK);                init_pair(2, COLOR_GREEN,   COLOR_BLACK);                init_pair(3, COLOR_YELLOW,  COLOR_BLACK);                init_pair(4, COLOR_BLUE,    COLOR_BLACK);                init_pair(5, COLOR_CYAN,    COLOR_BLACK);                init_pair(6, COLOR_MAGENTA, COLOR_BLACK);                init_pair(7, COLOR_WHITE,   COLOR_BLACK);            }        genCursesMenu( stdscr );        if( has_colors() )            attron( A_BOLD | COLOR_PAIR(4));        else            attron( A_BOLD );        mvprintw( 1, 2, "Name:" );        mvprintw( 1, 21, "Phone num:" );        mvprintw( 1, 35, "Birthday:" );        if( has_colors() )            attroff( A_BOLD | COLOR_PAIR(4));        else            attroff( A_BOLD );        list.sort();        for ( int i = 0; i < list.getSize(); i++ )        {            if ( list[i].month == setMonth && monthMode )            {                wattron( mainPad, A_BOLD | A_STANDOUT );                if ( has_colors() )                    wattron( mainPad, COLOR_PAIR(1));                mvwprintw( mainPad, i, 0, "                                           ");            }            mvwprintw( mainPad, i, 1, "%s", list[i].name.c_str() );            mvwprintw( mainPad, i, 20, "%s", list[i].phone.c_str() );            mvwprintw( mainPad, i, 37, "%d/%d", list[i].month, list[i].day );            if ( list[i].month == setMonth && monthMode )            {                wattroff( mainPad, A_BOLD | A_STANDOUT );                if ( has_colors() )                    wattroff( mainPad, COLOR_PAIR(1));            }        }        rightWin = create_newwin( 10, 30, (LINES - 10) / 2, ((COLS + ( COLS/2 ) - 30 )/2) );        mvwprintw( rightWin, 1, 2, "File: %s", filename.c_str());        mvwprintw( rightWin, 3, 2, "Records: %d", list.getSize());        if ( fName.size() > 0 )        {            wattron( rightWin, A_BOLD );            mvwprintw( rightWin, 5, 2, "Record Search: " );            mvwprintw( rightWin, 6, 4, "Name:" );            mvwprintw( rightWin, 7, 4, "Phone:");            mvwprintw( rightWin, 8, 4, "Birthday:");            wattroff( rightWin, A_BOLD );            mvwprintw( rightWin, 6, 10, "%s", fName.c_str() );            mvwprintw( rightWin, 7, 11, "%s", fPhone.c_str() );            mvwprintw( rightWin, 8, 14, "%s", (fBirthday.str()).c_str() );        }        wrefresh( rightWin );        prefresh( mainPad, pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol );        refresh();        cchoice = getch();        switch( cchoice )        {            case KEY_F(5): // F5 Key - Add New Record                // Create popup Window to get user input for name                popupWin = create_newwin( 3, 35, (LINES - 5)/2, (COLS - 35)/2 );                wbkgd( popupWin, A_STANDOUT );                mvwprintw( popupWin, 1, 2, "Enter name: ");                wrefresh( popupWin );                // Get user input                echo();                wgetnstr( popupWin, inName, 25 );                noecho();                // Clear and destroy popup window                werase( popupWin );                destroy_win( popupWin );                // Create another popup for second input                popupWin = create_newwin( 3, 51, (LINES - 5)/2, (COLS - 51)/2 );                wbkgd( popupWin, A_STANDOUT );                mvwprintw( popupWin, 1, 2, "Enter phone num. ( 123-456-7890 ): ");                wrefresh( popupWin );                // Get input                echo();                wgetnstr( popupWin, inPhone, 15 );                noecho();                // Clear and destroy popup window                werase( popupWin );                destroy_win( popupWin );                // Create another popup                popupWin = create_newwin( 3, 34, (LINES - 5)/2, (COLS - 34)/2 );                wbkgd( popupWin, A_STANDOUT );                mvwprintw( popupWin, 1, 2, "Enter birthdate (mm/dd): ");                wrefresh( popupWin );                // Get input                echo();                wgetnstr( popupWin, winDate, 10 );                noecho();                // Clear and destroy window                werase( popupWin );                destroy_win( popupWin );                // Convert c-strings to strings and such                name = inName;                phone = inPhone;                inDate.str( winDate );                inDate >> month;                inDate.ignore( 1, '/' );                inDate >> day;                // Create and insert node into linked list                newNode = createNode( name, phone, month, day );                list.insert( newNode );                // Stringstreams don't clear themselves so we need this                inDate.clear();                break;            case KEY_F(6): // F6 - Delete a record                // Create new popup win for user input                popupWin = create_newwin( 3, 43, (LINES - 5)/2, (COLS - 43)/2 );                wbkgd( popupWin, A_STANDOUT );                mvwprintw( popupWin, 1, 2, "Enter name to delete: ");                wrefresh( popupWin );                // Get input                echo();                wgetnstr( popupWin, inName, 19 );                noecho();                // Clear and destroy popup                werase( popupWin );                destroy_win( popupWin );                // C-string to string                name = inName;                // If found, then remove, otherwise make another                // popup that says it was not found.                if ( list.findByName( name ) != -1 )                    list.remove( list.findByName( name ));                else                {                    popupWin = create_newwin( 3, 19, (LINES - 5)/2, (COLS - 43)/2 );                    wbkgd( popupWin, A_STANDOUT );                    mvwprintw( popupWin, 1, 2, "Name not found!");                    wrefresh( popupWin );                    getch(); // wait for key press                    // erase and destroy popup                    werase( popupWin );                    destroy_win( popupWin );                }                break;            case KEY_F(7): // F7 - Find a specific name                // Create new popup win for user input                popupWin = create_newwin( 3, 43, (LINES - 5)/2, (COLS - 43)/2 );                wbkgd( popupWin, A_STANDOUT );                mvwprintw( popupWin, 1, 2, "Enter name to find: ");                wrefresh( popupWin );                // Get input                echo();                wgetnstr( popupWin, inName, 19 );                noecho();                // Clear and destroy popup                werase( popupWin );                destroy_win( popupWin );                // C-string to string                name = inName;                // If found, then remove, otherwise make another                // popup that says it was not found.                if ( list.findByName( name ) != -1 )                {                    fName = list[list.findByName( name )].name;                    fPhone = list[list.findByName( name )].phone;                    fBirthday.str("");                    fBirthday.clear();                    fBirthday << list[list.findByName(name)].month                              << '/'                              << list[list.findByName(name)].day;                }                else                {                    popupWin = create_newwin( 3, 19, (LINES - 5)/2, (COLS - 43)/2 );                    wbkgd( popupWin, A_STANDOUT );                    mvwprintw( popupWin, 1, 2, "Name not found!");                    wrefresh( popupWin );                    getch(); // wait for key press                    // erase and destroy popup                    werase( popupWin );                    destroy_win( popupWin );                }                break;            case KEY_F(8):  // F8 - List highlight month                // Create new popup win for user input                popupWin = create_newwin( 3, 39, (LINES - 5)/2, (COLS - 39)/2 );                wbkgd( popupWin, A_STANDOUT );                mvwprintw( popupWin, 1, 2, "Enter month to highlight (1-12): ");                wrefresh( popupWin );                // Get input                echo();                wgetnstr( popupWin, winDate, 4 );                noecho();                // Clear and destroy popup                werase( popupWin );                destroy_win( popupWin );                // Quick string to int conversion                inDate.str( winDate );                inDate >> setMonth;                inDate.clear();                // If month is between 1-12 inclusive, turn on                // month highlight mode.                if ( setMonth > 0 && setMonth < 13 )                    monthMode = true;                else                {                    popupWin = create_newwin( 3, 18, (LINES - 5)/2, (COLS - 18)/2 );                    wbkgd( popupWin, A_STANDOUT );                    mvwprintw( popupWin, 1, 2, "Invalid Entry!" );                    getch();                    werase( popupWin );                    destroy_win( popupWin );                }                break;            case KEY_F(9): // F9 - Exit                loopVar = false;                break;            case KEY_UP: // Up arrow key - Scroll up                if ( pminrow > 0 )                    pminrow--;                break;            case KEY_DOWN: // Down arrow key - Scroll down                if ( pminrow <= list.getSize() - smaxrow )                    pminrow++;                break;            default:                break;        }        wclear( mainPad );        delwin( mainPad );        werase( rightWin );        destroy_win( rightWin );        refresh();#else  // Standard I/O if compiled without Curses support        printMenu();        cout << "Enter a menu option: ";        cin.get( choice );        cin.ignore( 1, '\n' );        switch( choice )        {            case 'A':            case 'a':                addNode( list );                list.sort();                break;            case 'D':            case 'd':                cout << "* Enter a name to delete: ";                getline( cin, name );                if ( list.findByName( name ) != -1 )                    list.remove( list.findByName( name ));                else                    cout << "* Record not found!" << endl;                break;            case 'P':            case 'p':                list.output( cout );                break;            case 'M':            case 'm':                cout << "* Enter month to list ( numeric 1-12 ): ";                cin >> month;                cin.ignore( 1, '\n');                map = list.findByMonth( month );                for ( int i = 0; i < list.getSize(); i++ )                {                    if ( map[i] )                    {                        cout << "Name: " << list[i].name << endl                             << "Phone Num.: " << list[i].phone << endl                             << "Birthday: " << list[i].month << '/'                             << list[i].day << endl                             << endl;                    }                }                break;            case 'F':            case 'f':                cout << "Enter name to search for: ";                getline( cin, name );                found = list.findByName( name );                if ( found != -1 )                {                    cout << "Name: " << list[found].name << endl                         << "Phone Num.: " << list[found].phone << endl                         << "Birthday: " << list[found].month                         << '/' << list[found].day << endl << endl;                }                else                    cout << endl << "* Name not found" << endl;                break;            case 'Q':            case 'q':                loopVar = false;                break;            default:                cout << "* Invalid choice!" << endl;                break;        } // End switch#endif   // END USE_CURSES    } // End While#if USE_CURSES    endwin();#endif    file.open( filename.c_str(), fstream::out );    if ( file.fail() )    {        cout << "Error opening file for writing!" << endl;    }    else    {        list.output( file );        file.close();    }    return 0;}bdayNodePtr createNode( string name, string phone, int month, int day ){    bdayNodePtr node = new bdayNode;    node->name = name;    node->phone = phone;    node->month = month;    node->day = day;    node->next = NULL;    return node;}void printMenu() {    cout << "----------Birthday DB Main Menu----------" << endl << endl         << "\ta. Add new record" << endl         << "\td. Delete a record" << endl         << "\tp. View all records" << endl         << "\tm. Find all records in a month" << endl         << "\tf. Find a record by name" << endl         << "\tq. Save and quit" << endl << endl;}#if defined( HAVE_CURSES_H ) || defined( HAVE_NCURSES_H )void genCursesMenu( WINDOW *win ){    int row, col;    curs_set( 0 );    if ( has_colors() )    {        attron( A_BOLD | COLOR_PAIR(1) );        mvprintw( 0, (COLS - 21)/2, "Birthday DB Main Menu" );        attron( A_BOLD | COLOR_PAIR(2) );    }    else        attron( A_BOLD );    mvprintw( LINES - 1, (COLS - 77)/2, "F5" );    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 9, "F6" );    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 9, "F7" );    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 10, "F8" );    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 16, "F9" );    if ( has_colors() )    {        attroff( A_BOLD | COLOR_PAIR(2) );        attron( COLOR_PAIR(4) );    }    else        attroff( A_BOLD );    mvprintw( LINES - 1, (COLS - 81)/2, "|");    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 4, "- Add |");    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 4,"- Del |");    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 4, "- Find |");    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 4, "- Find/Month |" );    getyx( stdscr, row, col );    mvprintw( LINES - 1, col + 4, "- Quit |" );    refresh();    if ( has_colors() )        attroff( COLOR_PAIR(4) );}WINDOW *create_newwin(int height, int width, int starty, int startx){    WINDOW *local_win;    local_win = newwin(height, width, starty, startx);    box(local_win, 0 , 0);    wrefresh(local_win);    return local_win;}void destroy_win(WINDOW *local_win){    wbkgd( local_win, A_NORMAL );    wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' ');    wrefresh(local_win);    delwin(local_win);}#endifvoid addNode( BDayList &l ){    string name, phone, date;    stringstream inDate;    int month, day;    cout << "Enter name: ";    getline( cin, name );    cout << "Enter phone number (In the following format: 123-456-7890): ";    getline( cin, phone );    cout << "Enter birthday ( mm/dd ): ";    getline( cin, date );    inDate.str( date );    inDate >> month;    inDate.ignore( 1, '/' );    inDate >> day;    bdayNodePtr newNode = createNode( name, phone, month, day );    l.insert( newNode );}