|
|
# -*- encoding: utf-8 -*-
|
|
|
"""
|
|
|
@File : test2.py
|
|
|
@License : (C)Copyright 2018-2022
|
|
|
|
|
|
@Modify Time @Author @Version @Description
|
|
|
------------ ------- -------- -----------
|
|
|
2023/8/21 13:45 zart20 1.0 None
|
|
|
"""
|
|
|
|
|
|
import re
|
|
|
import tkinter as tk
|
|
|
from tkinter import scrolledtext
|
|
|
from math import sin, cos, pi
|
|
|
import numpy as np
|
|
|
from PIL import Image, ImageTk
|
|
|
|
|
|
import read_bin
|
|
|
from files_sys_sim import *
|
|
|
|
|
|
file_name_set = set() # 文件项的唯一集合
|
|
|
blocks_label_set = set() # 文件标签的唯一集合
|
|
|
|
|
|
|
|
|
def find_missing_and_duplicates(lst):
|
|
|
print("列表长度:", len(lst))
|
|
|
expected_set = set(range(1, 100))
|
|
|
input_set = set(lst)
|
|
|
print("转换集合长度:", len(input_set))
|
|
|
|
|
|
missing_numbers = list(expected_set - input_set)
|
|
|
duplicate_numbers = list(input_set.intersection(expected_set))
|
|
|
|
|
|
print("缺失的数字:", missing_numbers)
|
|
|
print("重复的数字:", duplicate_numbers)
|
|
|
|
|
|
return missing_numbers, duplicate_numbers
|
|
|
|
|
|
|
|
|
def get_unique_tag(): # 获取唯一字母标签
|
|
|
for ascii_code in range(65, 91):
|
|
|
character = chr(ascii_code)
|
|
|
if character not in blocks_label_set:
|
|
|
blocks_label_set.add(character)
|
|
|
return character
|
|
|
|
|
|
|
|
|
def set_canvas_size(foreground_image, up_or_down=None):
|
|
|
# 调整前景
|
|
|
new_width = 555 # 新的宽度
|
|
|
if up_or_down == "up":
|
|
|
new_height = 245 # 新的高度
|
|
|
else:
|
|
|
new_height = 555 # 新的高度
|
|
|
foreground_image = foreground_image.resize((new_width, new_height), Image.LANCZOS)
|
|
|
foreground_photo = ImageTk.PhotoImage(foreground_image)
|
|
|
return foreground_photo
|
|
|
|
|
|
|
|
|
class InterfaceFile:
|
|
|
def __init__(self, root: tk.Tk):
|
|
|
self.current_step = None
|
|
|
self.file_modi_tag = False # 文件修改状态
|
|
|
self.massages = [] # 系统消息队列
|
|
|
self.sim_fat_copy = None # 仿真FAT表复制临时列表,用于校验
|
|
|
self.sim_file_copy = None # 仿真文件复制临时列表,用于校验
|
|
|
self.ex_disk_oc = True # 交替显示保存占用和添加占用标志
|
|
|
self.ex_disk_la = True # 修改保存标签和清除标签的标志
|
|
|
self.sim_disk_copy = None # 磁盘复制临时列表,用于校验
|
|
|
self.block_modi_tag = False # 磁盘块修改标志置否
|
|
|
self.block_modi_lb = None # 磁盘块标签值初始化
|
|
|
self.old_key = None # FAT表上一次的记录值
|
|
|
self.fat_modi_num = None # 打开下一个FAT单元格之前的修改数值
|
|
|
self.fat_modi_tag = False # 修改状态标签,为True时进入修改状态
|
|
|
self.clear_tag = True # 清除标签,让标签清理和fat清理操作互斥
|
|
|
self.check = None # 检查磁盘条件
|
|
|
self.code = None # 当前磁盘块标签字母
|
|
|
self.creating = True # 正在创建的状态
|
|
|
self.SimFAT = initialize_simfat() # SimFAT 表初始化
|
|
|
self.SimDisk = initialize_simdisk() # SimDisk 区域初始
|
|
|
self.FolderItems = [] # 文件项储存
|
|
|
self.fat_unique_set = {0} # fat表去重集合,防止在一个位置建立多个磁盘块
|
|
|
self.root = root
|
|
|
self.canvas_width = 1440
|
|
|
self.canvas_height = 830
|
|
|
# self.root.geometry(f'{self.canvas_width}x{self.canvas_height}+{2100}+{100}')
|
|
|
self.root.geometry(f'{self.canvas_width}x{self.canvas_height}')
|
|
|
self.root.title("文件系统仿真TK版")
|
|
|
|
|
|
self.canvas = tk.Canvas(root, width=self.canvas_width, height=self.canvas_height, bg="white")
|
|
|
self.canvas.pack(fill="both", expand=True)
|
|
|
|
|
|
self.fat_table_position_mapping = dict() # FAT表位置-序号映射字典
|
|
|
self.blocks_position_mapping = dict() # 磁盘块位置-序号映射字典
|
|
|
|
|
|
# 创建菜单栏
|
|
|
menubar = tk.Menu(self.root, font=("son", 16))
|
|
|
self.root.config(menu=menubar)
|
|
|
|
|
|
# 创建文件菜单
|
|
|
file_menu = tk.Menu(menubar, tearoff=0)
|
|
|
file_menu.configure(font=("son", 16))
|
|
|
menubar.add_cascade(label="真实磁盘操作", menu=file_menu)
|
|
|
|
|
|
# 在文件菜单中添加选项
|
|
|
sector_0 = read_bin.read_sector_0()
|
|
|
file_menu.add_command(label="读取磁盘文件0扇区", command=lambda: self.show_real_disk("磁盘0扇区", sector_0))
|
|
|
sector_FAT1_1 = read_bin.read_sector_FAT1()
|
|
|
file_menu.add_command(label="读取磁盘文件FAT1",
|
|
|
command=lambda: self.show_real_disk("FAT1_0扇区", sector_FAT1_1))
|
|
|
root_path0 = read_bin.read_sector_root_path(0)
|
|
|
file_menu.add_command(label="读取根目录0扇区",
|
|
|
command=lambda: self.show_real_disk("根目录0扇区", root_path0))
|
|
|
root_path1 = read_bin.read_sector_root_path(1)
|
|
|
file_menu.add_command(label="读取根目录1扇区",
|
|
|
command=lambda: self.show_real_disk("根目录1扇区", root_path1))
|
|
|
|
|
|
# 创建保存菜单
|
|
|
save_menu = tk.Menu(menubar, tearoff=0)
|
|
|
save_menu.configure(font=("son", 16))
|
|
|
menubar.add_cascade(label="手动保存", menu=save_menu)
|
|
|
save_menu.add_command(label="开启手动保存模式", command=lambda : self.manual_save())
|
|
|
|
|
|
# 将鼠标左键点击事件绑定到函数on_left_click
|
|
|
self.canvas.bind("<Button-1>", self.on_left_click)
|
|
|
|
|
|
background_image = Image.open("img/bg2.png")
|
|
|
background_image = background_image.resize((1440, 830))
|
|
|
background_photo = ImageTk.PhotoImage(background_image)
|
|
|
|
|
|
# 在Canvas上显示背景图片
|
|
|
self.canvas.create_image(0, 0, anchor="nw", image=background_photo)
|
|
|
|
|
|
# 载入前景图片
|
|
|
foreground_image_pink = Image.open("img/pink_bg.png")
|
|
|
foreground_photo_pink = set_canvas_size(foreground_image_pink, "up")
|
|
|
foreground_image_purple = Image.open("img/purple_bg.png")
|
|
|
foreground_photo_purple = set_canvas_size(foreground_image_purple, "up")
|
|
|
foreground_image_jb = Image.open("img/jade_blue_bg.png")
|
|
|
foreground_photo_jb = set_canvas_size(foreground_image_jb)
|
|
|
foreground_image_sky_blue = Image.open("img/sky_blue_bg.png")
|
|
|
foreground_photo_sky_blue = set_canvas_size(foreground_image_sky_blue)
|
|
|
|
|
|
x1, y1, x2, y2 = 1130, 10, 1433, 819
|
|
|
self.canvas_child = tk.Canvas(self.canvas,)
|
|
|
self.canvas_child.place(x=x1,y=y1)
|
|
|
self.canvas_child.config(width=303, height=809)
|
|
|
self.canvas_child.create_rectangle(x1, y1, x2, y2, outline="white", fill="white")
|
|
|
|
|
|
# 在Canvas上显示调整后大小的前景图片
|
|
|
self.canvas.create_image(10, 10, anchor="nw", image=foreground_photo_pink)
|
|
|
self.canvas.create_image(570, 10, anchor="nw", image=foreground_photo_purple)
|
|
|
self.canvas.create_image(10, 265, anchor="nw", image=foreground_photo_jb)
|
|
|
self.canvas.create_image(570, 265, anchor="nw", image=foreground_photo_sky_blue)
|
|
|
|
|
|
# 保留图片引用以防止垃圾回收
|
|
|
self.canvas.background_image = background_photo
|
|
|
self.canvas.foreground_image_pink = foreground_photo_pink
|
|
|
self.canvas.foreground_photo_purple = foreground_photo_purple
|
|
|
self.canvas.foreground_photo_jb = foreground_photo_jb
|
|
|
self.canvas.foreground_photo_sky_blue = foreground_photo_sky_blue
|
|
|
|
|
|
# 按键布局
|
|
|
image_create = Image.open("img/创建文件.png")
|
|
|
self.photo_create = ImageTk.PhotoImage(image_create)
|
|
|
self.set_canvas_button([348, 20], self.photo_create, self.creat_file, bg="#996BC7")
|
|
|
|
|
|
image_save = Image.open("img/保存.png")
|
|
|
self.photo_save = ImageTk.PhotoImage(image_save)
|
|
|
self.file_save_button = self.set_canvas_button([435, 20], self.photo_save, self.save_file, bg="#996BC7")
|
|
|
|
|
|
image_query = Image.open("img/查询.png")
|
|
|
self.photo_query = ImageTk.PhotoImage(image_query)
|
|
|
self.set_canvas_button([495, 20], self.photo_query, self.query_file, bg="#996BC7")
|
|
|
|
|
|
image_create_path = Image.open("img/创建目录项.png")
|
|
|
self.photo_create_path = ImageTk.PhotoImage(image_create_path)
|
|
|
self.creat_path_button = self.set_canvas_button([825, 20], self.photo_create_path, self.creat_path, bg="#785FDA")
|
|
|
|
|
|
image_clear_file = Image.open("img/清除目录项.png")
|
|
|
self.photo_clear_file = ImageTk.PhotoImage(image_clear_file)
|
|
|
self.clear_file_button = self.set_canvas_button([915, 20], self.photo_clear_file, self.clear_file_label, bg="#785FDA")
|
|
|
|
|
|
image_check = Image.open("img/文件校验.png")
|
|
|
self.photo_check = ImageTk.PhotoImage(image_check)
|
|
|
self.file_check_button = self.set_canvas_button([1015,20], self.photo_check, self.file_check)
|
|
|
|
|
|
image_reset = Image.open("img/重置.png")
|
|
|
self.photo_reset = ImageTk.PhotoImage(image_reset)
|
|
|
self.set_canvas_button([1065, 20], self.photo_reset, self.restart, bg="#785FDA")
|
|
|
|
|
|
image_fat_check = Image.open("img/校验.png")
|
|
|
self.photo_fat_check = ImageTk.PhotoImage(image_fat_check)
|
|
|
self.fat_check_button = self.set_canvas_button([165, 274], self.photo_fat_check, self.fat_checkout)
|
|
|
|
|
|
image_clear_form = Image.open("img/清除表单项.png")
|
|
|
self.photo_clear_form = ImageTk.PhotoImage(image_clear_form)
|
|
|
self.set_canvas_button([270, 274], self.photo_clear_form, self.clear_fat_label)
|
|
|
|
|
|
image_save_form = Image.open("img/保存表单项.png")
|
|
|
self.photo_save_form = ImageTk.PhotoImage(image_save_form)
|
|
|
self.set_canvas_button([368, 274], self.photo_save_form, self.modi_fat_save)
|
|
|
|
|
|
image_change_form = Image.open("img/修改表单项.png")
|
|
|
self.photo_change_form = ImageTk.PhotoImage(image_change_form)
|
|
|
self.set_canvas_button([465, 274], self.photo_change_form, self.modi_fat)
|
|
|
|
|
|
image_disk_check = Image.open("img/校验2.png")
|
|
|
self.photo_disk_check = ImageTk.PhotoImage(image_disk_check)
|
|
|
self.disk_check_button = self.set_canvas_button([680, 274], self.photo_disk_check, self.disk_checkout)
|
|
|
|
|
|
image_save_occupy = Image.open("img/保存占用.png")
|
|
|
self.photo_save_occupy = ImageTk.PhotoImage(image_save_occupy)
|
|
|
image_add_occupy = Image.open("img/添加占用.png")
|
|
|
self.photo_add_occupy = ImageTk.PhotoImage(image_add_occupy)
|
|
|
self.exchange_button_disk_occupy() # 动态按钮函数用于 表示交保存和添加占用
|
|
|
|
|
|
image_revamp_label = Image.open("img/修改标签.png")
|
|
|
self.photo_revamp_label = ImageTk.PhotoImage(image_revamp_label)
|
|
|
image_save_label = Image.open("img/保存标签.png")
|
|
|
self.photo_save_label = ImageTk.PhotoImage(image_save_label)
|
|
|
self.exchange_button_disk_label() # 动态标签函数用于 表示交换修改和保存标签
|
|
|
|
|
|
image_clear_label = Image.open("img/清除标签.png")
|
|
|
self.photo_clear_label = ImageTk.PhotoImage(image_clear_label)
|
|
|
self.set_canvas_button([1040, 274], self.photo_clear_label, self.clear_disk_label)
|
|
|
|
|
|
# 设置
|
|
|
self.file_name_label = self.set_canvas_label_entry([20, 21], "输入文件名", 10, [120, 20]) # 设置输入框和输入标签
|
|
|
self.blocks_num_label = self.set_canvas_label_entry([255, 21], "块数", 3, [295, 20]) # 设置输入框和输入标签
|
|
|
self.path_name_label = self.set_canvas_label_entry([580, 21], "文件夹(目录)", 10, [690, 20]) # 设置输入框和输入标签
|
|
|
|
|
|
# 设置canvas_label
|
|
|
self.canvas.create_text(20, 275, text="文件分配表FAT", anchor="nw", fill="white", font=("Arial", 14))
|
|
|
self.canvas.create_text(20, 65, text="初始文件模拟区:", anchor="nw", fill="white", font=("Arial", 14))
|
|
|
self.canvas.create_text(580, 275, text="磁盘模块", anchor="nw", fill="white", font=("Arial", 14))
|
|
|
self.canvas.create_text(575, 70, anchor=tk.NW, text="文件名\t首块\t块数\t标签", font=("Arial", 14),
|
|
|
fill="white", )
|
|
|
self.canvas_child.create_text(150, 21, text="操作指引", anchor=tk.CENTER, fill="black", font=("son", 14, "bold"))
|
|
|
self.canvas_child.create_text(150, 240, text="系统消息", anchor=tk.CENTER, fill="black", font=("son", 14, "bold"))
|
|
|
|
|
|
self.photo_fk3 = self.image_transition("img/fk3.png") # 黄色方块,创建文件用
|
|
|
self.photo_fk1 = self.image_transition("img/fk1.png") # 透明位置方块 提供棋盘
|
|
|
self.photo_fk2 = self.image_transition("img/fk2.png") # 灰色方块,代表未选择方块,或者占用方块
|
|
|
|
|
|
# FAT模块
|
|
|
self.draw_fat_line()
|
|
|
|
|
|
# 磁盘模块
|
|
|
self.draw_disk_background()
|
|
|
|
|
|
# 创建滚动文本框
|
|
|
self.info_text = scrolledtext.ScrolledText(self.canvas_child, wrap=tk.WORD, width=25, height=24)
|
|
|
self.info_text.place(x=10,y=265)
|
|
|
self.info_text.config(font=("Arial", 14))
|
|
|
|
|
|
self.canvas_child.bind("<Button-1>", self.info_xy)
|
|
|
|
|
|
def info_xy(self,event):
|
|
|
print(event.x,event.y)
|
|
|
|
|
|
def sys_info(self, massage):
|
|
|
'''系统消息'''
|
|
|
self.info_text.insert("end", massage+"\n")
|
|
|
self.info_text.see("end")
|
|
|
|
|
|
def special_info(self, s_msg):
|
|
|
'''操作指引消息'''
|
|
|
self.canvas_child.delete("s_msg")
|
|
|
s_msgs = s_msg.split("\n")
|
|
|
for i, msg in enumerate(s_msgs):
|
|
|
self.canvas_child.create_text(150,60+i*25,text=msg,font=("Arial", 14), anchor=tk.CENTER, tags="s_msg")
|
|
|
|
|
|
|
|
|
def exchange_button_disk_label(self):
|
|
|
if self.ex_disk_la:
|
|
|
self.set_canvas_button([950, 274], self.photo_revamp_label, self.modi_block_lb, tags="prl")
|
|
|
else:
|
|
|
self.set_canvas_button([950, 274], self.photo_save_label, self.modi_block_save, tags="psl")
|
|
|
|
|
|
def exchange_button_disk_occupy(self):
|
|
|
if self.ex_disk_oc:
|
|
|
self.add_occupy_button = self.set_canvas_button([860, 274], self.photo_add_occupy, self.add_occupy, tags="pao")
|
|
|
else:
|
|
|
self.set_canvas_button([860, 274], self.photo_save_occupy, self.save_occupy, tags="pso")
|
|
|
|
|
|
def set_canvas_label_entry(self, label_pot: list, label_text: str, entry_width: int, entry_pot: list):
|
|
|
self.canvas.create_text(label_pot[0], label_pot[1], text=label_text, anchor="nw", fill="white",
|
|
|
font=("Arial", 14))
|
|
|
return self.set_canvas_entry(entry_pot[0], entry_pot[1], entry_width, "")
|
|
|
|
|
|
def set_canvas_button(self, button_pot: list, button_photo: ImageTk.PhotoImage, command, tags=None, bg="#3E97C1"):
|
|
|
button = tk.Button(self.canvas, image=button_photo, command=command, bd=0, relief="raised",
|
|
|
highlightthickness=0, compound="center", bg=bg, activebackground=bg)
|
|
|
self.canvas.create_window(button_pot, anchor="nw", window=button, tags=tags)
|
|
|
return button
|
|
|
|
|
|
def set_canvas_entry(self, x, y, entry_width: int, default: str, tags=None, font_size=None):
|
|
|
if not font_size:
|
|
|
font_size = 16
|
|
|
entry_file_name = tk.Entry(self.root, width=entry_width, )
|
|
|
entry_file_name.configure(font=("Arial", font_size), borderwidth=1, relief="sunken", )
|
|
|
entry_file_name.insert(0, default)
|
|
|
self.canvas.create_window(x, y, anchor="nw", window=entry_file_name, tags=tags)
|
|
|
return entry_file_name
|
|
|
|
|
|
def show_fat(self, row, column, length_side=430):
|
|
|
"""映射显示FAT表"""
|
|
|
tags = "fat_tag" # 定义删除标志
|
|
|
side_half = length_side // 20 # 每行和每列的间隔距离的一半
|
|
|
num = self.SimFAT[row][column]
|
|
|
if num != 0:
|
|
|
x = self.fat_table_position_mapping[row, column][0] + side_half
|
|
|
y = self.fat_table_position_mapping[row, column][1] + side_half
|
|
|
self.canvas.create_text(x, y, anchor=tk.CENTER, text=num, font=("Arial", 16),
|
|
|
fill="white", tags=tags)
|
|
|
|
|
|
def show_all_fat(self):
|
|
|
self.canvas.delete("fat_tag")
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
self.show_fat(i, n)
|
|
|
|
|
|
def load_files_list(self, fat_ls: list[int], block_label="default"): # 直接根据含第一块位置的fat表生成fat和disk显示
|
|
|
# 假设block的去重在数据层面就已经处理好了
|
|
|
self.show_all_disk() # 更新磁盘显示
|
|
|
for i, value in enumerate(fat_ls):
|
|
|
row = value // 10
|
|
|
column = value % 10
|
|
|
if block_label == "default":
|
|
|
block_label = self.SimDisk[row][column][0]
|
|
|
if i < len(fat_ls) - 1:
|
|
|
self.SimFAT[row][column] = fat_ls[i + 1]
|
|
|
else:
|
|
|
self.SimFAT[row][column] = "FF"
|
|
|
self.SimDisk[row][column] = f"{block_label}{i + 1}"
|
|
|
self.show_disk(row, column, True) # 最后创建颜色才为黄色
|
|
|
self.show_all_fat() # 更新fat表显示
|
|
|
|
|
|
def draw_fat_line(self, left_top_point=(80, 365), length_side=430):
|
|
|
"""FAT框架显示"""
|
|
|
left_x, left_y = left_top_point # 偏移量x和y
|
|
|
short_side = length_side // 10 # 每行和每列的间隔距离
|
|
|
|
|
|
for i in range(10): # 坐标映射
|
|
|
for n in range(10):
|
|
|
x = short_side * i + left_x
|
|
|
y = short_side * n + left_y
|
|
|
self.fat_table_position_mapping[n, i] = [x, y]
|
|
|
|
|
|
for line in range(11): # 画线
|
|
|
x1, x2 = short_side * line + left_x, left_x
|
|
|
y1, y2 = short_side * line + left_y, left_y
|
|
|
self.canvas.create_line(x1, left_y, x1, left_y + length_side, fill="white", width=1)
|
|
|
self.canvas.create_line(left_x, y1, left_x + length_side, y1, fill="white", width=1)
|
|
|
|
|
|
for num in range(10): # 画序号
|
|
|
x, y = short_side * num + left_x + (short_side // 2), short_side * num + left_y + (short_side // 2)
|
|
|
self.canvas.create_text(x, left_y - 20, text=f"{num}", font=("Arial", 12), anchor="center", fill="white")
|
|
|
self.canvas.create_text(left_x - 20, y, text=f"{num}", font=("Arial", 12), anchor="center", fill="white")
|
|
|
|
|
|
return self.fat_table_position_mapping
|
|
|
|
|
|
def show_disk(self, row, column, color_tag=None):
|
|
|
"""映射显示单个磁盘块"""
|
|
|
tags = "fat_disk" # 定义删除标志
|
|
|
text = self.SimDisk[row][column]
|
|
|
if text != 0:
|
|
|
x = self.blocks_position_mapping[row, column][0] + 1
|
|
|
y = self.blocks_position_mapping[row, column][1] + 1
|
|
|
if color_tag:
|
|
|
self.draw_blocks(x, y, tags, text, "label_disk", self.photo_fk3)
|
|
|
else:
|
|
|
self.draw_blocks(x, y, tags, text, "label_disk", self.photo_fk2)
|
|
|
|
|
|
def show_all_disk(self):
|
|
|
"""显示所有磁盘块"""
|
|
|
self.canvas.delete("fat_disk")
|
|
|
self.canvas.delete("label_disk")
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
self.show_disk(i, n)
|
|
|
|
|
|
def draw_disk_background(self, left_top_point=(650, 365), length_side=430):
|
|
|
"""创建磁盘块图例,并返回每个磁盘块的磁盘块的序号位置映射关系"""
|
|
|
left_x, left_y = left_top_point # 偏移量x和y
|
|
|
short_side = length_side // 10 # 每行和每列的间隔距离
|
|
|
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
x, y = short_side * i + left_x, short_side * n + left_y
|
|
|
self.canvas.create_image(x, y, anchor=tk.NW, image=self.photo_fk1)
|
|
|
self.blocks_position_mapping[n, i] = [x, y] # 保存每个磁盘块的序号位置映射关系
|
|
|
|
|
|
for num in range(10):
|
|
|
i = num
|
|
|
x1, x2 = short_side * i + left_x + (short_side // 2), left_x - 20
|
|
|
y = short_side * i + left_y + (short_side // 2)
|
|
|
self.canvas.create_text(x1, left_y - 20, text=f"{num}", font=("Arial", 12), anchor="center", fill="white")
|
|
|
self.canvas.create_text(x2, y, text=f"{num}", font=("Arial", 12), anchor="center", fill="white")
|
|
|
|
|
|
return self.blocks_position_mapping
|
|
|
|
|
|
def modify_image_color(self, image, channel_offset): # 调整方块颜色
|
|
|
image_array = np.array(image) # 将图像转换为NumPy数组
|
|
|
modified_image_array = image_array + np.array(channel_offset) # 对每个通道进行加减操作(包括Alpha通道)
|
|
|
modified_image_array = np.clip(modified_image_array, 0, 255) # 限制像素值在0到255之间
|
|
|
modified_image = Image.fromarray(np.uint8(modified_image_array)) # 创建新的图像
|
|
|
return modified_image
|
|
|
|
|
|
def image_transition(self, file_path, side=43, channel_offset=(0, 0, 0, 0)):
|
|
|
"""修改图片大小和颜色"""
|
|
|
image = Image.open(file_path)
|
|
|
if sum(channel_offset) != 0:
|
|
|
image = self.modify_image_color(image, channel_offset) # 按RGBA调整颜色
|
|
|
image.thumbnail((side, side))
|
|
|
return ImageTk.PhotoImage(image)
|
|
|
|
|
|
def query_file(self):
|
|
|
'''查询功能'''
|
|
|
# self.sys_info("临时消息")
|
|
|
file_name = self.file_name_label.get()
|
|
|
if file_name in file_name_set:
|
|
|
for item in self.FolderItems:
|
|
|
if file_name == item[0]:
|
|
|
file_label = initialize_fileblock(item[2], item[3])
|
|
|
self.canvas.delete("fk3")
|
|
|
self.creat_file_blocks(file_label)
|
|
|
self.blocks_num_label.delete(0, tk.END)
|
|
|
block_nums = read_sim_fat(int(item[1]), self.SimFAT) # 通过首块fat获取全部文件fat
|
|
|
self.load_files_list(block_nums)
|
|
|
self.sys_info(f"查询成功!")
|
|
|
else:
|
|
|
print("文件夹中无该文件!")
|
|
|
self.sys_info("文件夹中无该文件!")
|
|
|
|
|
|
def check_condition(self, file_name, start_block_num, block_num): # 检查创建和保存条件
|
|
|
|
|
|
for row in self.SimFAT: # 更新唯一SimFAT表
|
|
|
self.fat_unique_set.update(row)
|
|
|
if 'FF' in self.fat_unique_set: # 判断磁盘空间时,排除掉非位置字符
|
|
|
self.fat_unique_set.remove('FF')
|
|
|
self.fat_unique_set.remove(100) # 收藏判断需要删除100这个非位置值
|
|
|
|
|
|
if self.clear_tag:
|
|
|
if file_name != "" and block_num != "": # 文件名和块数不为空才能保存
|
|
|
if block_num.isdigit(): # 填入块数为正整数才能保存
|
|
|
if file_name not in file_name_set: # 文件名不重复才能保存
|
|
|
if len(self.fat_unique_set) + int(block_num) <= 100:
|
|
|
if start_block_num:
|
|
|
if int(start_block_num) not in self.fat_unique_set:
|
|
|
# fat_arr = self.generate_fat_array(start_block_num, int(block_num), self.SimFAT) # 生成fat表
|
|
|
# if fat_arr: # 有返回才进行显示
|
|
|
return True
|
|
|
else:
|
|
|
self.sys_info("首块位置已被占用!")
|
|
|
else:
|
|
|
self.sys_info("磁盘已满!")
|
|
|
else:
|
|
|
self.sys_info("磁盘空间不足!")
|
|
|
else:
|
|
|
self.sys_info("文件名不能重复!")
|
|
|
else:
|
|
|
self.sys_info("请输入正整数!")
|
|
|
else:
|
|
|
self.sys_info("文件名或块数不能为空!")
|
|
|
else:
|
|
|
if self.fat_modi_tag:
|
|
|
self.sys_info("正在执行FAT表修改任务!\n请完成FAT校验后再进行操作!")
|
|
|
elif self.block_modi_tag:
|
|
|
self.sys_info("正在执行磁盘块修改任务!\n请完成磁盘块校验后再进行操作!")
|
|
|
|
|
|
def creat_file(self, file_name=None, f_block=None, block_num=None):
|
|
|
print("创建文件")
|
|
|
if not file_name:
|
|
|
file_name = self.file_name_label.get()
|
|
|
if not block_num:
|
|
|
block_num = self.blocks_num_label.get()
|
|
|
if not f_block:
|
|
|
f_block = self.select_fat_unique()
|
|
|
|
|
|
self.check = self.check_condition(file_name, f_block, block_num) # 执行数据合规检查
|
|
|
|
|
|
if self.check: # 合规时执行
|
|
|
if self.creating: # 初始时获取字母,
|
|
|
self.code = get_unique_tag()
|
|
|
self.creating = False # 获取后除非触发保存,下次创建不更新字母
|
|
|
file_label = initialize_fileblock(block_num, self.code)
|
|
|
self.canvas.delete("fk3") # 新创建文件前执行一次删除
|
|
|
self.creat_file_blocks(file_label)
|
|
|
self.sys_info("创建文件成功!")
|
|
|
|
|
|
def creat_file_start_end_label(self, i, n, left_x, left_y, side, tags): # 创建起始和尾部标签组件
|
|
|
if i == 0:
|
|
|
self.canvas.create_text(left_x, left_y - 50, anchor=tk.NW, text="起始", font=("Arial", 14), fill="white",
|
|
|
tags=tags)
|
|
|
offset = 15 # 箭头外扩端点偏移量
|
|
|
end_x = left_x + side - n * side * 0.3 # x轴线段从右到左节结束点x值
|
|
|
self.canvas.create_line(left_x + side, left_y - offset, end_x, left_y - offset, fill="white", tags=tags)
|
|
|
arrow_angle = 30 # 箭头的夹角
|
|
|
angle_rad = arrow_angle * (pi / 180) # 计算幅度
|
|
|
self.canvas.create_line(end_x, left_y - offset, end_x + 10 * cos(angle_rad),
|
|
|
left_y - offset + 10 * sin(angle_rad), fill="white", tags=tags)
|
|
|
self.canvas.create_line(end_x, left_y - offset, end_x + 10 * cos(-angle_rad),
|
|
|
left_y - offset + 10 * sin(-angle_rad), fill="white", tags=tags)
|
|
|
if i == n - 1:
|
|
|
self.canvas.create_text(left_x - i * side, left_y - 30, anchor=tk.NW, text="尾部", font=("Arial", 14),
|
|
|
fill="white", tags=tags)
|
|
|
|
|
|
def draw_blocks(self, x, y, tags, label_block, label_ctrl=None, image=None): # 画创建文件中的方块和文字
|
|
|
if not image:
|
|
|
image = self.photo_fk3
|
|
|
self.canvas.create_image(x, y, anchor=tk.NW,
|
|
|
image=image, tags=tags)
|
|
|
if label_ctrl:
|
|
|
tags = label_ctrl
|
|
|
self.canvas.create_text(x + 5, y + 12, anchor=tk.NW,
|
|
|
text=label_block, font=("Arial", 12), tags=tags)
|
|
|
|
|
|
def creat_file_blocks(self, list: list):
|
|
|
left_x = 465
|
|
|
left_y = 150
|
|
|
side = 43 # 元素边
|
|
|
tags = "fk3"
|
|
|
n = len(list)
|
|
|
if n <= 11:
|
|
|
for i in range(n):
|
|
|
x = left_x - i * side
|
|
|
y = left_y
|
|
|
self.draw_blocks(x, y, tags, f"{list[i]}")
|
|
|
self.creat_file_start_end_label(i, n, left_x, left_y, side, tags)
|
|
|
else:
|
|
|
end_i = n - 5 # 取最后5块
|
|
|
for i in range(n):
|
|
|
x = left_x - i * side
|
|
|
y = left_y
|
|
|
self.creat_file_start_end_label(i, 11, left_x, left_y, side, tags)
|
|
|
if i < 5:
|
|
|
self.draw_blocks(x, y, tags, f"{list[i]}")
|
|
|
elif i == 5:
|
|
|
self.draw_blocks(x, y, tags, "...")
|
|
|
elif i < 11:
|
|
|
self.draw_blocks(x, y, tags, f"{list[end_i]}")
|
|
|
end_i += 1
|
|
|
|
|
|
def creat_path(self):
|
|
|
print("创建目录项")
|
|
|
if self.clear_tag:
|
|
|
path_name = self.path_name_label.get() # 获取文件夹
|
|
|
text_ls = path_name.split(",")
|
|
|
if text_ls[0] not in file_name_set:
|
|
|
if len(text_ls) == 3 and text_ls[1].isdigit() and text_ls[2].isdigit(): # 确保格式和类型一致
|
|
|
if self.check_condition(text_ls[0], text_ls[1], text_ls[2]):
|
|
|
self.save_file(text_ls[0], text_ls[1], text_ls[2])
|
|
|
self.sys_info("创建目录成功!")
|
|
|
else:
|
|
|
self.sys_info("请检查输入格式{'str','int','int'}!")
|
|
|
else:
|
|
|
self.sys_info("文件名重复!")
|
|
|
else:
|
|
|
self.sys_info("目前正在执行磁盘修改任务!")
|
|
|
|
|
|
def show_path_info(self, ): # 显示文件目录信息
|
|
|
self.canvas.delete("creat_path") # 画新图前元素清空
|
|
|
start_x = 580
|
|
|
start_y = 96
|
|
|
tags = "creat_path" # 删除标签
|
|
|
word_high = 26 # 字高
|
|
|
self.path_delete_image = self.image_transition("img/删除.png")
|
|
|
self.path_edit_image = self.image_transition("img/编辑.png")
|
|
|
|
|
|
for i, item in enumerate(self.FolderItems):
|
|
|
item = [str(n) for n in item]
|
|
|
text = "\t".join(item) # 制表符加工
|
|
|
if start_y + i * word_high < 250: # 超出范围限制显示
|
|
|
self.canvas.create_text(start_x, start_y + i * word_high, anchor=tk.NW, text=text, font=("Arial", 14),
|
|
|
fill="white", tags=tags)
|
|
|
self.set_canvas_button([start_x + 440, start_y + i * word_high], self.path_edit_image,
|
|
|
lambda n=i, x=start_x, y=start_y: self.path_info_edit(n, x, y), tags,
|
|
|
bg="#434FC5")
|
|
|
self.set_canvas_button([start_x + 470, start_y + i * word_high], self.path_delete_image,
|
|
|
lambda n=i: self.path_info_delete(n), tags, bg="#434FC5")
|
|
|
else:
|
|
|
self.sys_info("文件显示将溢出")
|
|
|
break
|
|
|
|
|
|
def delete_edit_file(self, index): # 点击编辑后就先清空当前文件的保留
|
|
|
first_block = self.FolderItems[index][1] # 获取选中的文件的第一块位置
|
|
|
file_name = self.FolderItems[index][0]
|
|
|
fat_table = read_sim_fat(int(first_block), self.SimFAT) # 获取文件的fat表
|
|
|
file_name_set.remove(file_name)
|
|
|
for fat in fat_table:
|
|
|
row = fat // 10
|
|
|
column = fat % 10
|
|
|
self.SimFAT[row][column] = 0
|
|
|
self.SimDisk[row][column] = 0
|
|
|
self.fat_unique_set.remove(fat)
|
|
|
|
|
|
def path_info_edit(self, index, x, y):
|
|
|
print("文件修改")
|
|
|
if self.file_modi_tag:
|
|
|
self.special_info("正在修改文件,\n修改完成请保存。")
|
|
|
tags = "creat_path" # 删除标签
|
|
|
word_high = 26 # 字高
|
|
|
file_name = self.FolderItems[index][0]
|
|
|
first_block = self.FolderItems[index][1]
|
|
|
blocks = self.FolderItems[index][2]
|
|
|
mark_char = self.FolderItems[index][3]
|
|
|
self.path_save_image = self.image_transition("img/保存弹窗.png")
|
|
|
self.path_cancel_image = self.image_transition("img/取消弹窗.png")
|
|
|
y = y + index * word_high
|
|
|
self.file_name = self.set_canvas_entry(x, y, 6, file_name, tags) # 显示entry组件,输入字符
|
|
|
self.first_block = self.set_canvas_entry(x + 80, y, 6, first_block, tags)
|
|
|
self.blocks = self.set_canvas_entry(x + 160, y, 6, blocks, tags)
|
|
|
self.mark_char = self.set_canvas_entry(x + 240, y, 6, mark_char, tags)
|
|
|
self.set_canvas_button([x + 330, y], self.path_save_image, tags=tags, bg="#434FC5",
|
|
|
command=lambda: self.path_info_edit_save(index))
|
|
|
self.set_canvas_button([x + 380, y], self.path_cancel_image, tags=tags, bg="#434FC5",
|
|
|
command=lambda: self.path_info_edit_cancel())
|
|
|
self.sys_info(f"{file_name} 文件修改中...")
|
|
|
else:
|
|
|
self.sys_info("未开启文件校验流程,无法修改文件")
|
|
|
# def path_info_edit_save(self, index): # 文件项编辑的保存
|
|
|
# if self.file_modi_tag and not self.clear_tag:
|
|
|
# file_name = self.file_name.get()
|
|
|
# first_block = self.first_block.get()
|
|
|
# block_num = self.blocks.get()
|
|
|
# old_first_block = int(self.FolderItems[index][1])
|
|
|
# old_fat_table = read_sim_fat(int(old_first_block), self.SimFAT) # 获取文件的fat表
|
|
|
# if file_name != "" and first_block != "" and block_num != "":
|
|
|
# if first_block.isdigit() and block_num.isdigit():
|
|
|
# if int(first_block) not in self.fat_unique_set or int(first_block) in old_fat_table:
|
|
|
#
|
|
|
# if len(self.fat_unique_set) + int(block_num) - len(old_fat_table) <= 100:
|
|
|
# b_label = self.FolderItems[index][3]
|
|
|
# self.delete_edit_file(index) # 执行前先删除旧的记录
|
|
|
# self.FolderItems[index] = [file_name, first_block, block_num, b_label]
|
|
|
# fat_arr = self.generate_fat_array(int(first_block), int(block_num)) # 重新生成fat表
|
|
|
# file_name_set.add(file_name)
|
|
|
# self.load_files_list(fat_arr, b_label)
|
|
|
# self.show_path_info()
|
|
|
# self.sys_info("修改成功!")
|
|
|
# else:
|
|
|
# self.sys_info("磁盘空间不足!")
|
|
|
# else:
|
|
|
# self.sys_info("首块位置已被占用!")
|
|
|
# else:
|
|
|
# self.sys_info("请输入正整数!")
|
|
|
# else:
|
|
|
# self.sys_info("修改值不能为空!")
|
|
|
# else:
|
|
|
# self.sys_info("目前正在执行磁盘修改任务!")
|
|
|
|
|
|
def path_info_edit_save(self, index): # 文件项编辑的保存
|
|
|
print("文件保存")
|
|
|
if self.file_modi_tag and not self.clear_tag:
|
|
|
self.special_info("文件已保存,可以开始校验。")
|
|
|
file_name = self.file_name.get() # 文件名
|
|
|
first_block = self.first_block.get() # 磁盘首块
|
|
|
if first_block.isdigit():
|
|
|
first_block = int(first_block)
|
|
|
block_num = self.blocks.get() # 磁盘块数
|
|
|
mark_char = self.mark_char.get() # 磁盘标签
|
|
|
self.FolderItems[index] = [file_name, first_block, block_num, mark_char]
|
|
|
file_name_set.add(file_name)
|
|
|
self.show_path_info()
|
|
|
self.sys_info("修改成功!")
|
|
|
else:
|
|
|
self.sys_info("未开启文件修改任务")
|
|
|
|
|
|
def path_info_edit_cancel(self):
|
|
|
self.show_path_info()
|
|
|
self.sys_info("已取消操作!")
|
|
|
|
|
|
def path_info_delete(self, index):
|
|
|
if self.clear_tag:
|
|
|
self.delete_edit_file(index) # 清空disk和fat
|
|
|
file_info = self.FolderItems.pop(index) # 删除该索引指向的元素
|
|
|
blocks_label_set.remove(file_info[3])
|
|
|
self.canvas.delete("fk3")
|
|
|
self.show_path_info() # 重新显示文件信息
|
|
|
self.show_all_fat()
|
|
|
self.show_all_disk()
|
|
|
self.sys_info(f"文件 {file_info[0]} 删除成功!")
|
|
|
else:
|
|
|
self.sys_info("正在进行校验操作,无法执行删除操作!")
|
|
|
|
|
|
def select_fat_unique(self):
|
|
|
while True: # 确保每次不同的字符被选中
|
|
|
unique_num = random.randint(0, 99)
|
|
|
if unique_num not in self.fat_unique_set:
|
|
|
return unique_num
|
|
|
if len(self.fat_unique_set) >= 100:
|
|
|
return None
|
|
|
|
|
|
def generate_fat_array(self, first_block: int, block_num: int): # 生成fat表文件列表
|
|
|
fat_arr = [first_block]
|
|
|
self.fat_unique_set.update(fat_arr)
|
|
|
for i in range(block_num - 1):
|
|
|
while True:
|
|
|
num = random.randint(1, 99)
|
|
|
if len(self.fat_unique_set) >= 101:
|
|
|
num = None
|
|
|
break
|
|
|
if num not in self.fat_unique_set:
|
|
|
self.fat_unique_set.add(num)
|
|
|
break
|
|
|
if num:
|
|
|
fat_arr.append(num)
|
|
|
else:
|
|
|
break
|
|
|
return fat_arr
|
|
|
|
|
|
def save_file(self, file_name=None, f_block=None, blocks=None):
|
|
|
print("保存文件")
|
|
|
if file_name:
|
|
|
file_name = file_name
|
|
|
else:
|
|
|
file_name = self.file_name_label.get()
|
|
|
|
|
|
if blocks:
|
|
|
blocks = blocks
|
|
|
else:
|
|
|
blocks = self.blocks_num_label.get()
|
|
|
|
|
|
if self.creating: # 如果保存时没有创建过,先创建
|
|
|
self.creat_file(file_name, f_block, blocks) # 保存的同时执行创建
|
|
|
|
|
|
if self.check:
|
|
|
if f_block:
|
|
|
f_block = int(f_block)
|
|
|
else:
|
|
|
f_block = self.select_fat_unique()
|
|
|
fat_arr = self.generate_fat_array(f_block, int(blocks)) # 生成fat表
|
|
|
self.FolderItems.append([file_name, f_block, blocks, self.code]) # 添加到文件夹
|
|
|
file_name_set.add(file_name) # 添加唯一性文件名集合
|
|
|
self.fat_unique_set.update(fat_arr) # 将占用的磁盘位置信息添加进唯一集合,防止重复取数
|
|
|
self.load_files_list(fat_arr, self.code) # 根据fat表向磁盘装载文件数据并显示
|
|
|
self.show_path_info() # 保存后显示文件夹
|
|
|
self.creating = True # 上一次保存执行完成后才能开始二次执行
|
|
|
self.sys_info("保存成功")
|
|
|
|
|
|
def restart(self):
|
|
|
global blocks_label_set
|
|
|
global file_name_set
|
|
|
self.modi_fat_save()
|
|
|
self.modi_block_save()
|
|
|
self.save_occupy()
|
|
|
self.canvas.delete("creat_path")
|
|
|
self.canvas.delete("fk3")
|
|
|
self.canvas.delete("fat_tag")
|
|
|
self.canvas.delete("fat_disk")
|
|
|
self.canvas.delete("label_disk")
|
|
|
self.canvas.delete("info")
|
|
|
|
|
|
self.massages = [] # 清空消息
|
|
|
self.FolderItems = [] # 清空文件项
|
|
|
blocks_label_set = set() # 块标签集合清空
|
|
|
file_name_set = set() # 唯一性文件名清空
|
|
|
self.fat_unique_set = {0} # 重置fat唯一位置检查集合
|
|
|
self.SimFAT = initialize_simfat() # 重置fat表
|
|
|
self.SimDisk = initialize_simdisk() # 重置磁盘
|
|
|
self.sim_fat_copy = None # fat表深拷贝初始化
|
|
|
self.ex_disk_oc = True # 交替显示保存占用和添加占用标志
|
|
|
self.ex_disk_la = True # 修改保存标签和清除标签的标志
|
|
|
self.sim_disk_copy = None # 磁盘块深拷贝初始化
|
|
|
self.block_modi_tag = False # 磁盘块修改标志置否
|
|
|
self.block_modi_lb = None # 磁盘块标签值初始化
|
|
|
self.old_key = None # FAT表上一次的记录值
|
|
|
self.fat_modi_num = None # 打开下一个FAT单元格之前的修改数值
|
|
|
self.fat_modi_tag = False # 修改状态标签,为True时进入修改状态
|
|
|
self.clear_tag = True # 清除标签,让标签清理和fat清理操作互斥
|
|
|
self.check = None # 检查磁盘条件
|
|
|
self.code = None # 当前磁盘块标签字母
|
|
|
self.creating = True # 正在创建的状态
|
|
|
self.file_modi_tag = False # 文件修改状态
|
|
|
self.sim_file_copy = None # 仿真文件复制临时列表,用于校验
|
|
|
|
|
|
self.file_save_button.config(state="normal") # 禁用一部分按键
|
|
|
self.fat_check_button.config(state="normal")
|
|
|
self.disk_check_button.config(state="normal")
|
|
|
self.creat_path_button.config(state="normal")
|
|
|
self.add_occupy_button.config(state="normal")
|
|
|
self.clear_file_button.config(state="normal")
|
|
|
self.file_check_button.config(state="normal")
|
|
|
|
|
|
try:
|
|
|
self.last_step.destroy()
|
|
|
self.next_step.destroy()
|
|
|
except:
|
|
|
pass
|
|
|
self.sys_info("重置成功!")
|
|
|
self.special_info("重置成功!")
|
|
|
|
|
|
|
|
|
def file_check(self):
|
|
|
global file_name_set
|
|
|
if self.file_modi_tag:
|
|
|
sum = 0
|
|
|
for i in range(len(self.FolderItems)):
|
|
|
if self.FolderItems[i][1:] == self.sim_file_copy[i][1:]:
|
|
|
sum+=1
|
|
|
file_name_set.add(self.FolderItems[i][0]) # 将新文件名添加到唯一结构
|
|
|
if sum == len(self.FolderItems):
|
|
|
self.sys_info("校验正确")
|
|
|
self.special_info("恭喜!\n文件校验成功!")
|
|
|
self.sim_file_copy = None # 校验正确才值无
|
|
|
else:
|
|
|
self.sys_info("校验错误。")
|
|
|
self.special_info("文件校验失败。")
|
|
|
|
|
|
self.file_modi_tag = False
|
|
|
self.clear_tag = True
|
|
|
else:
|
|
|
self.sys_info("没有开启文件校验流程,无法校验。")
|
|
|
|
|
|
|
|
|
def clear_file_label(self):
|
|
|
"""清除FAT表"""
|
|
|
global file_name_set
|
|
|
print("清除文件标签")
|
|
|
if len(self.FolderItems)>0:
|
|
|
if self.clear_tag:
|
|
|
self.special_info("正在进行文件校验!\n请点击目录项的铅笔图标。\n修改目录项。")
|
|
|
self.file_modi_tag = True
|
|
|
self.canvas.delete("creat_path")
|
|
|
self.clear_tag = False # 锁定文件校验状态
|
|
|
if not self.sim_file_copy:
|
|
|
self.sim_file_copy = copy.deepcopy(self.FolderItems) # 深拷贝复制一份原正确列表并保存为复制对象
|
|
|
file_name_set = set()
|
|
|
t0 = list()
|
|
|
for i in range(len(self.FolderItems)):
|
|
|
item = ["-","-","-","-"]
|
|
|
t0.append(item)
|
|
|
self.FolderItems = t0
|
|
|
self.show_path_info()
|
|
|
self.sys_info("文件清除成功!")
|
|
|
else:
|
|
|
self.sys_info("正在执行校验任务,无法清除目录项!")
|
|
|
else:
|
|
|
self.sys_info("文件夹无文件无法清除目录!")
|
|
|
|
|
|
|
|
|
|
|
|
def manual_save(self):
|
|
|
print("手动保存")
|
|
|
self.restart()
|
|
|
if self.current_step:
|
|
|
self.last_step.destroy()
|
|
|
self.next_step.destroy()
|
|
|
|
|
|
self.last_step = tk.Button(self.canvas_child, text="上一步", command=self.last_step_func)
|
|
|
self.canvas_child.create_window([80, 180], anchor="nw", window=self.last_step)
|
|
|
self.last_step.config(state="disabled")
|
|
|
|
|
|
self.next_step = tk.Button(self.canvas_child, text="下一步", command=self.next_step_func)
|
|
|
self.canvas_child.create_window([160, 180], anchor="nw", window=self.next_step)
|
|
|
|
|
|
self.current_step = 1
|
|
|
self.file_info_edit() # 开启构造文件夹操作
|
|
|
self.file_save_button.config(state="disabled") # 禁用一部分按键
|
|
|
self.fat_check_button.config(state="disabled")
|
|
|
self.disk_check_button.config(state="disabled")
|
|
|
self.creat_path_button.config(state="disabled")
|
|
|
self.add_occupy_button.config(state="disabled")
|
|
|
self.clear_file_button.config(state="disabled")
|
|
|
self.file_check_button.config(state="disabled")
|
|
|
|
|
|
def last_step_func(self):
|
|
|
print("上一步")
|
|
|
if self.current_step == 2:
|
|
|
print(1)
|
|
|
self.current_step = 1
|
|
|
# 开启文件夹修改
|
|
|
self.last_step.config(state="disabled")
|
|
|
self.file_info_edit() # 开启文件夹构造操作
|
|
|
self.modi_fat_save()
|
|
|
|
|
|
elif self.current_step == 3:
|
|
|
print(2)
|
|
|
self.current_step = 2
|
|
|
# 开启FAT修改
|
|
|
self.modi_block_save()
|
|
|
self.clear_fat_label()
|
|
|
self.next_step.config(state="normal")
|
|
|
self.next_step.config(text="下一步")
|
|
|
|
|
|
elif self.current_step == 4:
|
|
|
self.current_step =3
|
|
|
print(3)
|
|
|
# 开启磁盘修改
|
|
|
self.clear_disk_label()
|
|
|
self.next_step.config(text="完 成")
|
|
|
|
|
|
def next_step_func(self):
|
|
|
print("下一步")
|
|
|
if self.current_step == 1:
|
|
|
print("2")
|
|
|
self.current_step = 2
|
|
|
self.last_step.config(state="normal")
|
|
|
# 开启FAT修改
|
|
|
self.file_info_save() # 保存文件夹构造,并将文件信息添加到类属性self.FolderItems
|
|
|
self.clear_fat_label() # 清除FAT表
|
|
|
# self.modi_fat()
|
|
|
|
|
|
elif self.current_step == 2:
|
|
|
print("3")
|
|
|
self.current_step = 3
|
|
|
self.modi_fat_save()
|
|
|
self.clear_disk_label()
|
|
|
# 开启磁盘修改
|
|
|
# self.next_step.config(state="disabled")
|
|
|
self.next_step.config(text="完 成")
|
|
|
|
|
|
elif self.current_step == 3:
|
|
|
print("4")
|
|
|
self.current_step = 4
|
|
|
self.modi_block_save()
|
|
|
# 完成
|
|
|
# self.next_step.config(text="完 成")
|
|
|
self.next_step.config(text="校 验")
|
|
|
|
|
|
elif self.current_step == 4:
|
|
|
# 校验
|
|
|
# self.next_step.config(text="校 验")
|
|
|
self.save_check()
|
|
|
|
|
|
def save_check(self):
|
|
|
folder_item = self.FolderItems
|
|
|
fat_table = self.SimFAT
|
|
|
block_table = self.SimDisk
|
|
|
f_num = 0
|
|
|
for folders in folder_item:
|
|
|
num = 0
|
|
|
name = folders[0]
|
|
|
first = folders[1]
|
|
|
if first.isdigit():
|
|
|
blocks = int(folders[2])
|
|
|
label = folders[3]
|
|
|
fat = read_sim_fat(first, fat_table)
|
|
|
if len(fat) == int(blocks):
|
|
|
num += 1
|
|
|
for i, loca in enumerate(fat):
|
|
|
row = loca // 10
|
|
|
col = loca % 10
|
|
|
if block_table[row][col] == f"{label}{i+1}":
|
|
|
num += 1
|
|
|
if i < len(fat)-1:
|
|
|
if fat_table[row][col] == fat[i+1]:
|
|
|
num += 1
|
|
|
elif i == len(fat)-1:
|
|
|
if fat_table[row][col] == "FF":
|
|
|
num += 1
|
|
|
if num == 2*len(fat)+1:
|
|
|
self.sys_info(f"{name}校验正确!")
|
|
|
else:
|
|
|
self.sys_info(f"{name}校验错误!")
|
|
|
f_num += 1
|
|
|
else:
|
|
|
self.sys_info(f"{name}校验错误!")
|
|
|
if f_num == len(self.FolderItems):
|
|
|
self.special_info("校验成功")
|
|
|
try:
|
|
|
self.last_step.destroy()
|
|
|
self.next_step.destroy()
|
|
|
except:
|
|
|
pass
|
|
|
else:
|
|
|
self.special_info("校验失败")
|
|
|
|
|
|
def file_info_edit(self):
|
|
|
print("手动保存文件夹文件")
|
|
|
if self.current_step ==1:
|
|
|
self.special_info("手动保存模式。\n请先在初始区创建文件\n然后再完善文件信息。\n最后点击下一步。")
|
|
|
tags = "creat_path" # 删除标签
|
|
|
self.canvas.delete(tags)
|
|
|
x = 580
|
|
|
y = 96
|
|
|
self.file_name = self.set_canvas_entry(x, y, 6, "", tags) # 显示entry组件,输入字符
|
|
|
self.first_block = self.set_canvas_entry(x + 80, y, 6, "", tags)
|
|
|
self.blocks = self.set_canvas_entry(x + 160, y, 6, "", tags)
|
|
|
self.mark_char = self.set_canvas_entry(x + 240, y, 6, " ", tags)
|
|
|
|
|
|
def file_info_save(self):
|
|
|
self.special_info("文件保存成功\n现在开始添加文件分配表。")
|
|
|
if self.FolderItems != []:
|
|
|
self.FolderItems.pop()
|
|
|
file_name = self.file_name.get() # 文件名
|
|
|
first_block = self.first_block.get() # 磁盘首块
|
|
|
if first_block.isdigit():
|
|
|
first_block = int(first_block)
|
|
|
block_num = self.blocks.get() # 磁盘块数
|
|
|
mark_char = self.mark_char.get() # 磁盘标签
|
|
|
self.FolderItems.append([file_name, first_block, block_num, mark_char])
|
|
|
file_name_set.add(file_name) # 添加唯一文件名
|
|
|
blocks_label_set.add(mark_char) # 添加磁盘唯一块标志
|
|
|
|
|
|
tags = "creat_path" # 删除标签
|
|
|
self.canvas.delete(tags)
|
|
|
for i, item in enumerate(self.FolderItems):
|
|
|
item = [str(n) for n in item]
|
|
|
text = "\t".join(item) # 制表符加工
|
|
|
self.canvas.create_text(580, 96, anchor=tk.NW, text=text, font=("Arial", 14),
|
|
|
fill="white", tags=tags)
|
|
|
self.sys_info("修改成功!")
|
|
|
|
|
|
def clear_fat_label(self):
|
|
|
print("清除表单项")
|
|
|
self.special_info("正在进行FAT校验!\n请点击修改表单项。\n修改FAT表。")
|
|
|
self.fat_modi_tag = True # 开启FAT修改标签
|
|
|
if self.clear_tag:
|
|
|
self.canvas.delete("fat_tag")
|
|
|
self.clear_tag = False
|
|
|
if not self.sim_fat_copy:
|
|
|
self.sim_fat_copy = copy.deepcopy(self.SimFAT) # 深拷贝复制一份原正确列表并保存为复制对象
|
|
|
self.SimFAT = initialize_simfat() # 同时清空原FAT表
|
|
|
self.sys_info("清除成功!")
|
|
|
|
|
|
else:
|
|
|
self.sys_info("正在执行校验任务,无法清除表单项!")
|
|
|
|
|
|
def modi_fat(self):
|
|
|
if self.fat_modi_tag:
|
|
|
self.special_info("正在修改FAT表。\n点击FAT表对应区域修改值。\n完成后保存表单项。")
|
|
|
if not self.sim_fat_copy and self.fat_modi_tag:
|
|
|
self.sim_fat_copy = copy.deepcopy(self.SimFAT) # 深拷贝复制一份原正确列表并保存为复制对象
|
|
|
else:
|
|
|
self.sys_info("未开启FAT校验流程。")
|
|
|
|
|
|
def modi_fat_entry(self, row, column, lt_top):
|
|
|
default = self.SimFAT[row][column]
|
|
|
if self.fat_modi_num and self.old_key:
|
|
|
if self.fat_modi_num.get().isdigit() or self.fat_modi_num.get().upper() == "FF":
|
|
|
if self.fat_modi_num.get().isdigit():
|
|
|
self.SimFAT[self.old_key[0]][self.old_key[1]] = int(self.fat_modi_num.get())
|
|
|
else:
|
|
|
self.SimFAT[self.old_key[0]][self.old_key[1]] = "FF"
|
|
|
self.sys_info(f"{self.old_key} -> {self.fat_modi_num.get()}添加成功!")
|
|
|
else:
|
|
|
self.sys_info("请输入正整数,或FF!")
|
|
|
|
|
|
self.canvas.delete("fat_entry")
|
|
|
self.fat_modi_num = self.set_canvas_entry(lt_top[0] + 8, lt_top[1] + 8, 2, default, "fat_entry")
|
|
|
self.old_key = [row, column]
|
|
|
self.show_all_fat()
|
|
|
|
|
|
def modi_fat_save(self):
|
|
|
print("保存表单项")
|
|
|
if self.fat_modi_tag:
|
|
|
self.canvas.delete("fat_entry")
|
|
|
self.fat_modi_tag = False # 修改标志置否保存后就不再能修改
|
|
|
self.clear_tag = True # 保存后清除项就置真
|
|
|
if self.fat_modi_num and self.old_key:
|
|
|
if self.fat_modi_num.get().isdigit() or self.fat_modi_num.get().upper() == "FF":
|
|
|
if self.fat_modi_num.get().isdigit():
|
|
|
self.SimFAT[self.old_key[0]][self.old_key[1]] = int(self.fat_modi_num.get())
|
|
|
else:
|
|
|
self.SimFAT[self.old_key[0]][self.old_key[1]] = "FF"
|
|
|
else:
|
|
|
self.sys_info("请输入正整数,或FF!")
|
|
|
self.show_all_fat()
|
|
|
self.old_key = None
|
|
|
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
if self.SimFAT[i][n] != 0:
|
|
|
num = i * 10 + n
|
|
|
self.fat_unique_set.add(num)
|
|
|
self.sys_info("保存表单成功!")
|
|
|
self.special_info("FAT 保存成功!\n可以开始校验。")
|
|
|
self.fat_modi_tag = False # 修改标志置否保存后就不再能修改
|
|
|
else:
|
|
|
self.sys_info("未开启FAT校验流程。")
|
|
|
|
|
|
def fat_checkout(self):
|
|
|
print("FAT校验")
|
|
|
if self.sim_fat_copy and not self.fat_modi_tag:
|
|
|
num = 0
|
|
|
tag = False
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
num += 1
|
|
|
if self.SimFAT[i][n] != self.sim_fat_copy[i][n]:
|
|
|
self.sys_info(f"校验失败\n{i}行{n}列错误")
|
|
|
tag = True
|
|
|
break
|
|
|
if tag:
|
|
|
break
|
|
|
|
|
|
if num == 100:
|
|
|
self.sys_info("校验正确")
|
|
|
self.special_info("恭喜!\nFAT校验正确!")
|
|
|
|
|
|
self.sim_fat_copy = None
|
|
|
|
|
|
else:
|
|
|
self.sys_info("未完成修改操作,不可校验")
|
|
|
|
|
|
def clear_disk_label(self):
|
|
|
print("清除标签")
|
|
|
if self.clear_tag:
|
|
|
self.block_modi_tag = True
|
|
|
self.special_info("正在进行磁盘块校验。\n请点击修改标签,\n补充清除的磁盘块标签。")
|
|
|
self.canvas.delete("block_entry")
|
|
|
self.canvas.delete("label_disk")
|
|
|
# self.canvas.delete("")
|
|
|
self.clear_tag = False # 将清除标志置否,防止其他模块改动
|
|
|
if not self.sim_disk_copy:
|
|
|
self.sim_disk_copy = copy.deepcopy(self.SimDisk) # 复制一份原正确列表并保存为复制对象
|
|
|
|
|
|
for i in range(10):
|
|
|
for j in range(10):
|
|
|
if self.SimDisk[i][j] != 0:
|
|
|
self.SimDisk[i][j] = 0
|
|
|
self.sys_info("清除成功!")
|
|
|
self.show_all_disk()
|
|
|
else:
|
|
|
self.sys_info("正在执行校验任务,无法清除磁盘模块标签。")
|
|
|
|
|
|
|
|
|
def modi_block_lb(self): # 修改标签
|
|
|
print("修改标签")
|
|
|
if self.block_modi_tag:
|
|
|
self.special_info("正在修改磁盘块。\n点击磁盘模块区域修改值。\n完成后保存标签。")
|
|
|
self.clear_tag = False # 修改磁盘标签时冻结文件分配表的按钮
|
|
|
if not self.sim_disk_copy:
|
|
|
self.sim_disk_copy = copy.deepcopy(self.SimDisk) # 深度拷贝数组
|
|
|
|
|
|
self.ex_disk_la = False
|
|
|
self.canvas.delete("prl")
|
|
|
self.exchange_button_disk_label()
|
|
|
else:
|
|
|
self.sys_info("未开启磁盘块校验流程。")
|
|
|
|
|
|
def modi_block_entry(self, row, column, lt_top):
|
|
|
default = self.SimDisk[row][column]
|
|
|
|
|
|
if self.block_modi_lb:
|
|
|
label = self.block_modi_lb.get().upper()
|
|
|
if label != "0":
|
|
|
if re.match(r'^[A-Za-z]\d+$', label): # 正则表达式将匹配如 "A1"、"b2"、"Z9" 等形式的字符串
|
|
|
self.SimDisk[self.old_key[0]][self.old_key[1]] = label
|
|
|
self.sys_info(f"{self.old_key} -> {label}添加成功!")
|
|
|
else:
|
|
|
self.sys_info("请输入正确格式,如:A1!")
|
|
|
|
|
|
self.canvas.delete("block_entry")
|
|
|
self.block_modi_lb = self.set_canvas_entry(lt_top[0] + 2, lt_top[1] + 10, 3, default, "block_entry", 12)
|
|
|
self.block_modi_lb.select_range(0, tk.END) # 使Entry组件获得焦点(选中),以便可以直接修改值
|
|
|
self.old_key = [row, column]
|
|
|
self.show_all_disk()
|
|
|
|
|
|
def modi_block_save(self):
|
|
|
print("保存标签")
|
|
|
if self.block_modi_tag:
|
|
|
self.canvas.delete("block_entry")
|
|
|
self.ex_disk_la = True
|
|
|
self.canvas.delete("psl")
|
|
|
self.exchange_button_disk_label()
|
|
|
if self.block_modi_lb:
|
|
|
label = self.block_modi_lb.get().upper()
|
|
|
if label != "0":
|
|
|
if re.match(r'^[A-Za-z]\d+$', label): # 正则表达式将匹配如 "A1"、"b2"、"Z9" 等形式的字符串
|
|
|
self.SimDisk[self.old_key[0]][self.old_key[1]] = label
|
|
|
self.sys_info(f"{self.old_key} -> {label}添加成功!")
|
|
|
else:
|
|
|
self.sys_info("请输入正确格式,如:A1!")
|
|
|
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
if self.SimDisk[i][n] != 0 and self.SimDisk[i][n] != "":
|
|
|
num = i * 10 + n
|
|
|
code = self.SimDisk[i][n][0] # 取第一个字母
|
|
|
blocks_label_set.add(code) # 添加字母到字母唯一集合
|
|
|
self.fat_unique_set.add(num) # 将被占用的位置添加到唯一FAT表中防止被选中
|
|
|
|
|
|
self.block_modi_lb = False # 修改标签置否。
|
|
|
self.show_all_disk()
|
|
|
self.block_modi_tag = False # 磁盘修改标签置否
|
|
|
self.clear_tag = True
|
|
|
self.special_info("磁盘块已保存。\n可以开始校验。")
|
|
|
self.sys_info("磁盘块保存成功!")
|
|
|
else:
|
|
|
self.sys_info("未开启磁盘校验流程")
|
|
|
|
|
|
def add_occupy(self):
|
|
|
print("添加占用")
|
|
|
self.ex_disk_oc = False
|
|
|
self.canvas.delete("pao")
|
|
|
self.exchange_button_disk_occupy()
|
|
|
self.sys_info("正在添加占用...")
|
|
|
self.special_info("正在添加占用。")
|
|
|
|
|
|
def add_occupy_click(self, x, y):
|
|
|
if not self.ex_disk_oc:
|
|
|
for key, block_lt in self.blocks_position_mapping.items():
|
|
|
if block_lt[0] < x < block_lt[0] + 43 and block_lt[1] < y < block_lt[1] + 43:
|
|
|
self.SimDisk[key[0]][key[1]] = ""
|
|
|
self.SimFAT[key[0]][key[1]] = "X"
|
|
|
print(key[0], key[1])
|
|
|
self.show_all_disk()
|
|
|
self.show_all_fat()
|
|
|
self.sys_info(f"{key}添加成功")
|
|
|
|
|
|
def disk_checkout(self):
|
|
|
print("Disk校验")
|
|
|
if self.sim_disk_copy and not self.block_modi_tag:
|
|
|
num = 0
|
|
|
tag = False
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
num += 1
|
|
|
if self.SimDisk[i][n] != self.sim_disk_copy[i][n]:
|
|
|
if self.SimDisk[i][n] != "":
|
|
|
self.sys_info(f"校验失败\n{i}行{n}列错误")
|
|
|
tag = True
|
|
|
break
|
|
|
if tag:
|
|
|
break
|
|
|
if num == 100:
|
|
|
self.special_info("恭喜!\n磁盘校验正确!")
|
|
|
self.sys_info("校验正确")
|
|
|
self.sim_disk_copy = None
|
|
|
else:
|
|
|
self.sys_info("未进行修改操作,不可校验")
|
|
|
|
|
|
def save_occupy(self):
|
|
|
print("保存占用")
|
|
|
self.ex_disk_oc = True
|
|
|
self.canvas.delete("pso")
|
|
|
self.exchange_button_disk_occupy()
|
|
|
|
|
|
for i in range(10):
|
|
|
for n in range(10):
|
|
|
if self.SimDisk[i][n] != 0:
|
|
|
num = i * 10 + n
|
|
|
self.fat_unique_set.add(num)
|
|
|
self.sys_info("保存占用成功!")
|
|
|
self.special_info("保存占用成功!")
|
|
|
|
|
|
def on_left_click(self, event, ):
|
|
|
x = event.x
|
|
|
y = event.y
|
|
|
print(x, y)
|
|
|
if self.fat_modi_tag:
|
|
|
for key, fat_lt in self.fat_table_position_mapping.items():
|
|
|
if fat_lt[0] < x < fat_lt[0] + 43 and fat_lt[1] < y < fat_lt[1] + 43:
|
|
|
self.modi_fat_entry(key[0], key[1], fat_lt)
|
|
|
|
|
|
if self.block_modi_tag:
|
|
|
for key, block_lt in self.blocks_position_mapping.items():
|
|
|
if block_lt[0] < x < block_lt[0] + 43 and block_lt[1] < y < block_lt[1] + 43:
|
|
|
self.modi_block_entry(key[0], key[1], block_lt)
|
|
|
|
|
|
self.add_occupy_click(x, y)
|
|
|
|
|
|
# pprint(self.SimFAT)
|
|
|
|
|
|
def show_real_disk(self, title, sector):
|
|
|
child_window = tk.Toplevel(self.root)
|
|
|
child_window.title(title)
|
|
|
|
|
|
child_window1 = tk.Toplevel(self.root)
|
|
|
child_window1.title(f"{title}_字节解析")
|
|
|
|
|
|
sector_num, Bytes = sector
|
|
|
canvas = tk.Canvas(child_window, width=750, height=830, bg="white", )
|
|
|
canvas1 = tk.Canvas(child_window1, width=750, height=830, bg="white", )
|
|
|
BYTES_PER_LINE = 16 # 每行字节数
|
|
|
n = 0
|
|
|
s = 0
|
|
|
for byte in range(16):
|
|
|
if s % 9 == 0:
|
|
|
s = s + 1
|
|
|
canvas.create_text(100 + s * 35, 20 + n * 24, text=f"{byte:02X}", anchor="nw", fill="red",
|
|
|
font=("Arial", 14))
|
|
|
canvas1.create_text(100 + s * 35, 20 + n * 24, text=f"{byte:02X}", anchor="nw", fill="red",
|
|
|
font=("Arial", 14))
|
|
|
s += 1
|
|
|
n += 1
|
|
|
for i in range(0, len(Bytes), BYTES_PER_LINE):
|
|
|
line_data = Bytes[i:i + BYTES_PER_LINE]
|
|
|
print(f"{sector_num * 32 + i:08X}:", end=" ")
|
|
|
canvas.create_text(20, 20 + n * 24, text=f"{sector_num * 32 + i:08X}:", anchor="nw", fill="red",font=("Arial", 14))
|
|
|
canvas1.create_text(20, 20 + n * 24, text=f"{sector_num * 32 + i:08X}:", anchor="nw", fill="red",font=("Arial", 14))
|
|
|
s = 0
|
|
|
for byte in line_data:
|
|
|
print(f"{byte:02X}", end=" ")
|
|
|
print(chr(byte), end=" ")
|
|
|
if s % 9 == 0:
|
|
|
s = s + 1
|
|
|
canvas.create_text(100 + s * 35, 20 + n * 24, text=f"{byte:02X}", anchor="nw", fill="black",font=("Arial", 14))
|
|
|
canvas1.create_text(100 + s * 35, 20 + n * 24, text=f"{chr(byte)}", anchor="nw", fill="black",font=("Arial", 14))
|
|
|
s += 1
|
|
|
print()
|
|
|
n += 1
|
|
|
canvas.pack(fill=tk.BOTH, expand=True)
|
|
|
canvas1.pack(fill=tk.BOTH, expand=True)
|
|
|
self.sys_info(f"正在查看{title}")
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
root = tk.Tk()
|
|
|
root.resizable(False, False) # 禁止用户调整窗口大小
|
|
|
main = InterfaceFile(root)
|
|
|
# root.after(60000, close_window)
|
|
|
root.mainloop()
|
|
|
|