#!/usr/bin/env python ## CURSES BASIC-MAIL GUI # This is the Basic-Mail program, a basic email client written in python # with a curses interface. # # To Run: Go to the Basic-Mail directory and type "python Basic-Mail.py", # without the quotes. ## ## basic-mail.py ## # This is the main file, where the interface is created and where the user # interacts with the program. ## ## VERSION HISTORY.. ANYONE? ... BEUHLER? ## ## Version 0.8 - April 20th, 2006 # The code is now much more organized and the functions better explained. ## ## Version 0.7 - April 12th, 2006 # Includes working pop-ups and tab displays, though you cannot open and close # tabs. ## ## Version 0.6 - April 8th, 2006 # Has working menus and tabs, though tab displaying is not quite worked out. ## ## Version 0.5 - April 5th, 2006 # The Chat GUI stripped down to its basic functionality. ## ## A more detailed version history is available in versions.txt ## ## IMPORTS ## import curses, curses.ascii, curses.panel # Curses imports import traceback, os, sys, select, string # Random imports # Other Basic-Mail files and functions from interface import * from chat import * ## Function: Draws all the unselected menus and tabs to the screen. def draw_screen(): # Fills Title Line. fill_line(stdscr, 80, program_title,' ',2,0) # Creates the Menu and Tab Bars. create_bar(menu_bar,menu,bar_width,2) # Last number is the space between create_bar(tab_bar,tabs,bar_width,1) # Highlight Active Tab if active_tab == tab1: select_bar(tab_bar,tabs,0,10,10,0) # Highlights first tab elif active_tab == tab2: select_bar(tab_bar,tabs,1,10,10,0) # Highlights first tab elif active_tab == tab3: select_bar(tab_bar,tabs,2,10,10,0) # Highlights first tab elif active_tab == tab4: select_bar(tab_bar,tabs,3,10,10,0) # Highlights first tab elif active_tab == tab5: select_bar(tab_bar,tabs,4,10,10,0) # Highlights first tab ## MAIN CODE ## # "try" is used in case of GUI failure. try: # Initializes Main Window and Curses Options. global stdscr stdscr = curses.initscr() # Open Curses Window curses.cbreak() # Takes input before the enter key is pressed curses.noecho() # Stops echo of input to screen curses.curs_set(1) # Sets the cursor visibility, 0-2 # Initializes and Globalizes (?) the Menus, Tabs, and Title. global menu, tabs, program_title # Menu Matrix: # Menu[0] = Menu options. # Menu[1] = The character in each menu option to be highlighted. # Menu[2:] = The options within each menu option. menu = [["File","Edit","View","Message"],\ [0,0,0,0],\ ["New Folder","Close Tab","Quit"],\ [0,0,0],\ ["Accounts"],\ [0],\ ["Inbox","Address Book","Outbox","Sentmail"],\ [0,0,0,0],\ ["New Message","Reply"],\ [0,0]] # Tab Array: An array of the open tabs. tabs = [["\Inbox:1/", "\Address Book:2/", "\Sent Mail:3/", "\Outbox:4/"],\ [-2,-2,-2,-2]] # Letter to highlight in each corresponding word program_title = "Basic-Mail Client - Press Ctrl-C to Exit" # Initializes tabs and menus within other files initialize_interface_variables(menu,tabs,program_title) initialize_chat_variables(menu,tabs,program_title) # Initializes default color combinations. curses.start_color() curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_CYAN) curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK) # Creating the Menu Bar and Tab Bar. global bar_width, bar_height, menu_bar bar_width = 80 bar_height = 1 menu_bar = curses.newwin(bar_height, bar_width, 1, 0) global tab_bar tab_bar = curses.newwin(bar_height, bar_width, 29, 0) # Creating tab window. global main_height, main_width, main, win1, win2, win3, win4, win5 main_height = 27 main_width = 78 win1 = curses.newwin(main_height, main_width, 2, 1) win2 = curses.newwin(main_height, main_width, 2, 1) win3 = curses.newwin(main_height, main_width, 2, 1) win4 = curses.newwin(main_height, main_width, 2, 1) win5 = curses.newwin(main_height, main_width, 2, 1) draw_borders(stdscr, 80, 30) # Draws the screen border # Initialize Tabs tab1 = curses.panel.new_panel(win1) win1.addstr(0,60,tabs[0][0][1:-3]+"!") if len(tabs[0]) > 1: tab2 = curses.panel.new_panel(win2) win2.addstr(0,60,tabs[0][1][1:-3]+"!") if len(tabs[0]) > 2: tab3 = curses.panel.new_panel(win3) win3.addstr(0,60,tabs[0][2][1:-3]+"!") if len(tabs[0]) > 3: tab4 = curses.panel.new_panel(win4) win4.addstr(0,60,tabs[0][3][1:-3]+"!") if len(tabs[0]) > 4: tab5 = curses.panel.new_panel(win5) win5.addstr(0,60,tabs[0][4][1:-3]+"!") tab1.top() global active_tab, active_win active_tab = tab1 active_win = win1 curses.panel.update_panels() draw_screen() # Draws the title, menu bar, and tab bar. # Begin Interacting With User. live = 1 menu_win_q = 0 while(live): curses.curs_set(0) # Makes Cursor invisible, 0-2 stdscr.move(0,0) # Moves cursor input = stdscr.getch(0,0) # Takes input at location # Decides what to do with the input # Checks for open menus if(menu_win_q): count = 0 for number in menu[location]: # Checks if the user has selected one of the menu options. if curses.ascii.unctrl(input) == \ string.lower(number[menu[location+1][count]]) or \ curses.ascii.unctrl(input) == \ string.upper(number[menu[location+1][count]]): # If the user has chosen to quit. if location == 2 and curses.ascii.unctrl(input) == 'q' or \ curses.ascii.unctrl(input) == 'Q': live = create_pop_up(location,count,menu) # If the user has chosen to close a tab if location == 2 and curses.ascii.unctrl(input) == 'c' or \ curses.ascii.unctrl(input) == 'C': # The user chooses to close a tab. if len(tabs[0]) == 1: create_pop_up(location,count,menu) else: active_tab = close_tab() if active_tab == tab1: active_win = win1 elif active_tab == tab2: active_win = win2 elif active_tab == tab3: active_win = win3 elif active_tab == tab4: active_win = win4 elif active_tab == tab5: active_win = win5 count += 1 menu_win_q = 0 menu_win.hide() curses.panel.update_panels() curses.doupdate() draw_screen() # Checks if user selected a menu count = 0 for number in menu[0]: # Checks if the input selects any of the menu options # In both lower case and upper case if curses.ascii.unctrl(input) == \ string.lower(number[menu[1][count]]) or \ curses.ascii.unctrl(input) == \ string.upper(number[menu[1][count]]): draw_screen() select_bar(menu_bar,menu,count,10,10,0) menu_win = create_menu(menu,count) location = (count * 2) + 2 menu_win_q = 1 count += 1 # Checks if the user selected one of the tabs count = 0 # Resets count for checking tabs for number in tabs[0]: # Checks if the input selects any of the tabs if curses.ascii.unctrl(input) == number[tabs[1][count]]: # Select_Bar(Window, list, count, height, width, options?=0/1) select_bar(tab_bar,tabs,count,10,10,0) # Opens appropriate panel in the main window. if count == 0: tab1.top() active_tab = tab1 active_win = win1 if count == 1 and len(tabs[0])>1: tab2.top() active_tab = tab2 active_win = win2 if count == 2 and len(tabs[0])>2: tab3.top() active_tab = tab3 active_win = win3 if count == 3 and len(tabs[0])>3: tab4.top() active_tab = tab4 active_win = win4 if count == 4 and len(tabs[0])>4: tab5.top() active_tab = tab5 active_win = win5 curses.panel.update_panels() curses.doupdate() draw_screen() count += 1 stdscr.keypad(0) curses.nocbreak() curses.echo() curses.endwin() # Closes Curses Window print "Thank you for trying the Basic-Mail client!" except: # Returns terminal to a normal state if error stdscr.keypad(0) curses.nocbreak() curses.echo() curses.endwin() # Closes Curses Window print "Thank you! The interface has broken and you have found a bug!"