Untitled

 avatar
unknown
plain_text
a year ago
20 kB
0
Indexable
import pygame
import openpyxl
from datetime import date, timedelta
from bidi.algorithm import get_display  # Import the get_display function for text mirroring
from datetime import datetime
from openpyxl.utils.dataframe import dataframe_to_rows
from operator import itemgetter
import pygame.colordict
import sys

# Initialize Pygame
pygame.init()

# Set up the display
screen = pygame.display.set_mode((800, 600))
button_width = 30
button_hight = 30
pygame.display.set_caption("Speech Organizer")
file_path = r"C:\Users\user\Downloads\speech maneger\speeches.xlsx"
occupied_dates_file = r"C:\Users\user\Downloads\speech maneger\occupied_dates.txt"

# Import images
search_button_initial_image = pygame.image.load(r"C:\Users\user\Downloads\speech maneger\Magnifying Glass.png")
search_button_hover_image = pygame.image.load(r"C:\Users\user\Downloads\speech maneger\Magnifying Glass hover.png")
search_button_initial_image = pygame.transform.scale(search_button_initial_image, (button_width,button_hight))
search_button_hover_image = pygame.transform.scale(search_button_hover_image, (button_width,button_hight))
logo_image = pygame.image.load(r"C:\Users\user\Downloads\speech maneger\לוגו למנהל נאומים לוגו.png")
logo_image = pygame.transform.scale(logo_image, (50, 50))

# Colors
BACKGROUND_COLOR = (242, 242, 242)
INPUT_COLOR = (220, 220, 220)
TEXT_COLOR = (30, 30, 30)
CURSOR_COLOR = (0, 0, 0)
PRIMARY_COLOR = (74, 144, 226)  
SECONDARY_COLOR = (255, 120, 82)  
BUTTON_COLOR = (35, 35, 35)
MENU_COLOR = (74, 144, 226) 

# Load a font that supports English and Hebrew characters
FONT_PATH = r"C:\Users\user\Downloads\tahoma.ttf" 
FONT_SIZE = 36
FONT = pygame.font.Font(FONT_PATH, FONT_SIZE)
FONT2 = pygame.font.Font(FONT_PATH, 50)

# Load recets
logo_rect = (screen.get_width() - logo_image.get_width() - 10, 10) 
menu_button_rect = pygame.Rect(screen.get_width() - 780, 20, 30, 30)
s1_menu_button_rect = pygame.Rect(screen.get_width() - 780, 20, 30, 3)
search_button_rect = search_button_initial_image.get_rect(center=(230, 30))
search_input_rect = pygame.Rect(50, 140, 700, 50)

# Variables
menu_width = 300
mouse_x, mouse_y = pygame.mouse.get_pos()
running = True
input_name = ""
input_topic = ""
input_phone = ""
input_date = ""
active_input = "name"
cursor_visible = True
cursor_timer = 0
menu_open = False
search_open = False

# Load the existing Excel file or create a new one if it doesn't exist
try:
    workbook = openpyxl.load_workbook(file_path)
except FileNotFoundError:
    workbook = openpyxl.Workbook()

sheet = workbook.active
sheet.title = 'Speeches'

def button_animation(button_rect, button_initial, button_hover):
    if button_rect.collidepoint(mouse_x, mouse_y):	# Check if mouse is hovering over the replay button
        screen.blit(button_hover, button_rect)    # Blit the hover state image
    else:
        screen.blit(button_initial, button_rect)    # Blit the initial state image

# Find the next available Saturday
def find_next_available_saturday(current_date):
    with open(occupied_dates_file, 'r') as f:
        occupied_dates = [line.strip() for line in f]
    while current_date.weekday() != 5 or str(current_date) in occupied_dates:
        current_date += timedelta(days=1)
    return current_date

def is_hebrew(sentence):
    for char in sentence:
        if not ('\u0590' <= char <= '\u05FF'):
            return False
    return True

def draw_menu_button():
    pygame.draw.rect(screen, BUTTON_COLOR, s1_menu_button_rect)
    pygame.draw.rect(screen, BUTTON_COLOR, s1_menu_button_rect.move(0, 10))
    pygame.draw.rect(screen, BUTTON_COLOR, s1_menu_button_rect.move(0, 20))

def search_button():
    screen.blit(search_button_initial_image ,search_button_rect)
    button_animation(search_button_rect, search_button_initial_image, search_button_hover_image)

def search_button_sc(scroll_y):
    search_button_rect = search_button_initial_image.get_rect(center=(230, 30))
    screen.blit(search_button_initial_image, (search_button_rect.x, search_button_rect.y + scroll_y))
    button_animation(search_button_rect, search_button_initial_image, search_button_hover_image)

def menu_logic():
        # Adjust the position of other elements based on the menu state
        if menu_open:
            input_rect_x = 50 + menu_width
            input_label_text_x = 50 + menu_width
            s1_menu_button_rect.x = menu_width - 40
            menu_button_rect.x = menu_width - 40
            # Draw the menu window
            menu_rect = pygame.Rect(0, 0, menu_width, screen.get_height())
            pygame.draw.rect(screen, MENU_COLOR, menu_rect)
            draw_menu_button()
            search_button()
        else:
            # Adjust the position of other elements based on the menu state
            logo_rect = (screen.get_width() - logo_image.get_width() - 10, 10)
            s1_menu_button_rect.x = screen.get_width() - 780
            menu_button_rect.x = screen.get_width() - 780

def cursor_logic():
    global cursor_timer
    global cursor_visible
    global search_input_rect
    # Cursor blinking
    cursor_timer += 0.2
    if cursor_timer >= 30:
        cursor_timer = 0
        cursor_visible = not cursor_visible
    if cursor_visible:
        cursor_x = input_rect.x + 10  # Default cursor position
        if active_input != "date":  # Adjust cursor position for non-date inputs
            cursor_x += input_text_surface.get_width()
        cursor_y = input_rect.y + 10
        pygame.draw.rect(screen, CURSOR_COLOR, (cursor_x, cursor_y, 2, 36))

def draw_logo_and_header():
    # Draw the logo and header
    pygame.draw.rect(screen, (255, 255, 255), (0, 0, screen.get_width(), 70))
    logo_rect = (screen.get_width() - logo_image.get_width() - 10, 10)
    draw_menu_button()
    screen.blit(logo_image, logo_rect)

def search_and_display_report(screen, sheet, menu_width):
    global s1_menu_button_rect
    global menu_button_rect
    global menu_open
    menu_button_rect = pygame.Rect(screen.get_width() - 780, 20, 30, 30)
    s1_menu_button_rect = pygame.Rect(screen.get_width() - 780, 20, 30, 3)
    pygame.display.flip()
    search_input = ""
    search_active = True
    menu_open = False
    result_offset = 0  # Starting offset for results
    scroll_position = 0
    scroll_speed = 5

    while search_active:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    search_active = False
                elif event.key == pygame.K_BACKSPACE:
                    search_input = search_input[:-1]
                else:
                    search_input += event.unicode
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # Left mouse button
                    if menu_button_rect.collidepoint(event.pos):
                        menu_open = not menu_open

        screen.fill(BACKGROUND_COLOR)
        draw_logo_and_header()
        # Render search input box
        search_input_rect = pygame.Rect(50, 140, 700, 50)
        pygame.draw.rect(screen, INPUT_COLOR, search_input_rect)
        search_input_text_surface = FONT.render(search_input, True, TEXT_COLOR)
        screen.blit(search_input_text_surface, (search_input_rect.x + 10, search_input_rect.y + 10))

        # Render search label text
        search_label_text = FONT.render("Enter Name to Search:", True, TEXT_COLOR)
        screen.blit(search_label_text, (50, 80))

        # Display the search input box
        search_input_rect = pygame.Rect(50, 140, 700, 50)
        pygame.draw.rect(screen, INPUT_COLOR, search_input_rect)

        # Apply mirroring to the search input and render it
        mirrored_search_input = get_display(search_input)
        search_input_text_surface = FONT.render(mirrored_search_input, True, TEXT_COLOR)

        screen.blit(search_input_text_surface, (search_input_rect.x + 10, search_input_rect.y + 10))
        cursor_logic()
        menu_logic()
        pygame.display.flip()

    # Search for the entered name in the Excel file
    matching_rows = []
    for row in sheet.iter_rows(min_row=2, values_only=True):
        if row[0] is not None and search_input.lower() in row[0].lower():
            matching_rows.append(row)
    screen.fill(BACKGROUND_COLOR)
	
    if matching_rows:
        # Render the matching speeches in search result style
        result_y = 200
        result_spacing = 20
        result_rect_width = 700
        result_rect_height = 100
        for i, speech in enumerate(matching_rows):
            result_rect = pygame.Rect(50, result_y, result_rect_width, result_rect_height)
            pygame.draw.rect(screen, (245, 245, 245), result_rect)
            pygame.draw.rect(screen, (200, 200, 200), result_rect, 2)
            name_text = get_display(speech[0])
            topic_text = get_display(speech[1])
            name_surface = FONT.render(name_text, True, (68, 68, 68))
            topic_surface = FONT.render(topic_text, True, (102, 102, 102))
            screen.blit(name_surface, (result_rect.x + 20, result_rect.y + 20))
            screen.blit(topic_surface, (result_rect.x + 20, result_rect.y + 50))
            result_y += result_rect_height + result_spacing

        displaying_results = True
        result_offset = 0  # Initial offset for spacing
        scroll_target_offset = result_offset
        scroll_y = 0
        current_page = 1
        results_per_page = 3  # Update this to display 3 results per page
        total_pages = (len(matching_rows) + results_per_page - 1) // results_per_page
		
        # Main loop for displaying results
        while displaying_results:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RETURN:
                        displaying_results = False
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:  # Left mouse button
                        if menu_button_rect.collidepoint(event.pos):
                            menu_open = not menu_open
                    elif prev_page_rect.collidepoint(event.pos) and current_page > 1:
                        current_page -= 1
                        current_page = max(current_page, 1)
                    elif next_page_rect.collidepoint(event.pos) and current_page < total_pages:
                        current_page += 1
            # Calculate which results to display on the current page
            start_idx = (current_page - 1) * results_per_page
            end_idx = min(start_idx + results_per_page, len(matching_rows))
            # Clear the screen
            screen.fill(BACKGROUND_COLOR)

            # Render search results
            if matching_rows:
                result_y = 200
                result_spacing = 20
                result_rect_width = 700
                result_rect_height = 100
    
                for i, speech in enumerate(matching_rows[result_offset:result_offset + results_per_page]):
                    result_rect = pygame.Rect(50, result_y + scroll_y, result_rect_width, result_rect_height)
                    pygame.draw.rect(screen, (245, 245, 245), result_rect)
                    pygame.draw.rect(screen, (200, 200, 200), result_rect, 2)
    
                    name_text = get_display(speech[0])
                    topic_text = get_display(speech[1])
    
                    name_surface = FONT.render(name_text, True, (68, 68, 68))
                    topic_surface = FONT.render(topic_text, True, (102, 102, 102))
    
                    screen.blit(name_surface, (result_rect.x + 20, result_rect.y + 20))
                    screen.blit(topic_surface, (result_rect.x + 20, result_rect.y + 50))
    
                    result_y += result_rect_height + result_spacing

            draw_logo_and_header()    # Draw the logo and header
            # Render pagination buttons with arrow symbols
            prev_page_text = FONT2.render("←", True, (68, 68, 68))  # Left arrow symbol
            next_page_text = FONT2.render("→", True, (68, 68, 68))  # Right arrow symbol
            
            prev_page_rect = prev_page_text.get_rect(right=screen.get_width() - 70, y=screen.get_height() - 70)
            next_page_rect = next_page_text.get_rect(right=screen.get_width() - 20, y=screen.get_height() - 70)
            
            screen.blit(prev_page_text, prev_page_rect)
            screen.blit(next_page_text,next_page_rect)
			
            # Display the page count
            page_count_text = FONT.render(f"{current_page} out of {total_pages}", True, (68, 68, 68))
            page_count_rect = page_count_text.get_rect(center=(screen.get_width() // 2, screen.get_height() - 50))
            screen.blit(page_count_text, page_count_rect)
        
            # Draw the menu if open
            menu_logic()
            pygame.display.flip()

        pygame.display.flip()

while running:
    screen.fill(BACKGROUND_COLOR)
    # Draw the logo and header
    pygame.draw.rect(screen, (255, 255, 255), (0, 0, screen.get_width(), 70))
    draw_menu_button()
    screen.blit(logo_image, logo_rect)

    # Update mouse coordinates
    mouse_x, mouse_y = pygame.mouse.get_pos()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                if active_input == "name":
                    active_input = "topic"
                elif active_input == "topic":
                    active_input = "phone"
                elif active_input == "phone":
                    active_input = "date"  # Activate the date input
                else:
                    # Handle adding the speech details and saving to Excel
                    new_row = [input_name, input_topic, input_phone, input_date]
                    sheet.append(new_row)
                    with open(occupied_dates_file, 'a') as f:
                        f.write(str(input_date) + '\n')
                    workbook.save(file_path)
                    print("Data saved to Excel.")

                    # Retrieve all rows and convert them into a list of dictionaries
                    all_rows = list(sheet.iter_rows(min_row=2, values_only=True))
                    sorted_rows = sorted(all_rows, key=itemgetter(3))  # Sort based on the date column (0-indexed)
                    
                    # Clear existing data in the sheet (except headers)
                    sheet.delete_rows(2, sheet.max_row)
                    
                    # Write sorted rows back to the sheet
                    for row in sorted_rows:
                        sheet.append(row)
                    
                    # Save the workbook after sorting
                    workbook.save(file_path)

                    if is_hebrew(input_name):
                        input_name = input_name[::-1]
                    if is_hebrew(input_topic):
                        input_topic = input_topic[::-1]

                    # Generate report for the newly added speech data
                    report_text = [
                        f"Speech Details:",
                        f"Name: {get_display(input_name)}",
                        f"Topic: {get_display(input_topic)}",
                        f"Phone: {get_display(input_phone)}",
                        f"Date: {get_display(input_date)}",
                        "",
                        f"Report generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"  # Include time
                    ]
                    
                    # Render report text
                    report_surfaces = [FONT.render(get_display(line), True, TEXT_COLOR) for line in report_text]
                    max_width = max(surface.get_width() for surface in report_surfaces)
                    report_height = sum(surface.get_height() for surface in report_surfaces) + 20
                    report_x = (screen.get_width() - max_width) // 2
                    report_y = (screen.get_height() - report_height) // 2
                    pygame.draw.rect(screen, INPUT_COLOR, (report_x - 10, report_y - 10, max_width + 20, report_height))
                    for surface in report_surfaces:
                        screen.blit(surface, (report_x, report_y))
                        report_y += surface.get_height()
                    
                    pygame.display.flip()
                    pygame.time.wait(5000)
                    input_name = ""
                    input_topic = ""
                    input_phone = ""
                    input_date = ""
                    active_input = "name"
            elif event.key == pygame.K_BACKSPACE:
                if active_input == "name":
                    input_name = input_name[:-1]
                elif active_input == "topic":
                    input_topic = input_topic[:-1]
                elif active_input == "phone":
                    input_phone = input_phone[:-1]
                elif active_input == "date":
                    input_date = input_date[:-1]
            else:
                if active_input == "name":
                    input_name += event.unicode
                elif active_input == "topic":
                    input_topic += event.unicode
                elif active_input == "phone":
                    input_phone += event.unicode
                elif active_input == "date":
                    input_date += event.unicode
					
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # Left mouse button
                if menu_button_rect.collidepoint(event.pos):
                    menu_open = not menu_open
            if event.button == 1:  # Left mouse button
                if search_button_rect.collidepoint(event.pos):
                    search_open = not search_open


    input_labels = {
        "name": "Orator's Name:",
        "topic": "Speech Topic:",
        "phone": "Phone Number:",
        "date": "Speech Date (YYYY-MM-DD):"
    }
	
    # Render input label text
    input_label_text = FONT.render(input_labels[active_input], True, TEXT_COLOR)

    # Display the input_text_surface based on the active input
    if active_input == "date":
        input_text = input_date
    elif active_input == "name":
        input_text = input_name
    elif active_input == "topic":
        input_text = input_topic
    else:
        input_text = input_phone

    # Mirrored text using bidi algorithm
    mirrored_input_text = get_display(input_text)
    input_text_surface = FONT.render(mirrored_input_text, True, TEXT_COLOR)
    input_rect = pygame.Rect(50, 140, 700, 50)
    pygame.draw.rect(screen, INPUT_COLOR, input_rect)
    screen.blit(input_text_surface, (input_rect.x + 10, input_rect.y + 10))

    # Display the input_text_surface based on the active input
    if active_input == "date":
        if not input_date:  # If no date is input, find next available Saturday
            input_date = find_next_available_saturday(date.today()).strftime("%Y-%m-%d")
        input_text_surface = FONT.render(input_date, True, TEXT_COLOR)
    else:
        mirrored_input_text = get_display(input_text)    # Mirrored text using bidi algorithm
        input_text_surface = FONT.render(mirrored_input_text, True, TEXT_COLOR)

    input_rect = pygame.Rect(50, 140, 700, 50)
    pygame.draw.rect(screen, INPUT_COLOR, input_rect)
    screen.blit(input_text_surface, (input_rect.x + 10, input_rect.y + 10))

    cursor_logic()
    screen.blit(input_label_text, (50, 80))
    menu_logic()    # Show menu

    if search_open and menu_open:
        search_and_display_report(screen, sheet, menu_width)
        search_button_sc(scroll_y)
		
    pygame.display.flip()

pygame.quit()