diff --git a/README.md b/README.md index e72d2ae..4f7816b 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -### librer +# LIBRER A file cataloging program with extensive customization options to suit user preferences. **The software and this document are under development and in a pre-release state.** ## Features: -The primary purpose of this software is to enable users to catalog their files, particularly on removable media like memory cards and portable drives. It allows users to add metadata, referred to here as **custom data**, and facilitates future searching through the created records. **Custom data** consists of textual information acquired through the execution of user-chosen commands or scripts. **Custom data** may include any text data customized to meet the user's requirements, restricted only by the available memory and the software accessible for data retrieval. The retrieved data is stored in a newly created database record and can be utilized for search or verification purposes. +The primary purpose of this software is to enable users to catalog their files, particularly on removable media like memory cards and portable drives. It allows user to add metadata, referred to here as **custom data**, and facilitates future searching through the created records. **Custom data** consists of textual information acquired through the execution of user-chosen commands or scripts. **Custom data** may include any text data customized to meet the user's requirements, restricted only by the available memory and the software accessible for data retrieval. The retrieved data is stored in a newly created database record and can be utilized for search or verification purposes. ## Screenshots: @@ -88,7 +88,7 @@ pip install -r requirements.txt ./scripts/icons.convert.sh ./scripts/version.gen.sh -python ./src/dude.py +python3 ./src/librer.py ``` ## Licensing diff --git a/src/core.py b/src/core.py index db50a10..19aee68 100644 --- a/src/core.py +++ b/src/core.py @@ -33,6 +33,11 @@ from os.path import join as path_join from os.path import abspath from os.path import normpath + +from platform import system as platform_system +from platform import release as platform_release +from platform import node as platform_node + from os import remove as os_remove from fnmatch import fnmatch @@ -133,23 +138,14 @@ def test_regexp(expr): #print(i, temp_tuple) ####################################################################### -data_format_version='1.0002' +data_format_version='1.0003' class LibrerCoreData : - label = "" - creation_time = None - rid = None #data record id - scan_path = None - data = None - quant_files = 0 - quant_folders = 0 - data_format_version='' - - def __init__(self,label,path): + def __init__(self,label='',path=''): self.label=label self.scan_path = path self.creation_time = int(1000*time()) - self.rid = self.creation_time + self.rid = self.creation_time #data record id self.data = () self.quant_files = 0 @@ -165,6 +161,8 @@ def __init__(self,label,path): self.files_cde_size_extracted = 0 self.files_cde_errors_quant = 0 + self.creation_os,self.creation_host = f'{platform_system()} {platform_release()}',platform_node() + def get_time(self): return self.creation_time/1000 @@ -183,13 +181,17 @@ def __init__(self,label,path,log): self.files_search_progress = 0 self.crc_progress_info=0 + self.FILE_NAME = '' - def file_name(self): + def new_file_name(self): return f'{self.db.rid}.dat' def abort(self): self.abort_action = True + def get_info(self): + return f'name: {self.db.label}\nscan path: {self.db.scan_path}\nsize: {bytes_to_str(self.db.sum_size)}\nhost: {self.db.creation_host}\nOS: {self.db.creation_os}\ncreation time: {self.db.creation_time}\nfile: {self.FILE_NAME}' + def calc_crc(self,fullpath,size): CRC_BUFFER_SIZE=4*1024*1024 buf = bytearray(CRC_BUFFER_SIZE) @@ -690,7 +692,7 @@ def find_items(self, self.find_results_list = list(find_results) def save(self) : - file_name=self.file_name() + file_name=self.new_file_name() self.info_line = f'saving {file_name}' file_path=sep.join([self.db_dir,file_name]) self.log.info('saving %s' % file_path) @@ -702,6 +704,8 @@ def save(self) : def load(self,db_dir,file_name): self.log.info('loading %s' % file_name) + self.FILE_NAME = file_name + try: full_file_path = sep.join([db_dir,file_name]) with gzip_open(full_file_path, "rb") as gzip_file: @@ -937,9 +941,7 @@ def find_items_in_all_records(self, def delete_record_by_id(self,rid): for record in self.records: if record.db.rid == rid: - print('found record to delete:',rid) - - file_path = sep.join([self.db_dir,record.file_name()]) + file_path = sep.join([self.db_dir,record.FILE_NAME]) self.log.info('deleting file:%s',file_path) try: os_remove(file_path) diff --git a/src/dialogs.py b/src/dialogs.py index 9af550a..9b3b657 100644 --- a/src/dialogs.py +++ b/src/dialogs.py @@ -28,9 +28,20 @@ from os import name as os_name -import tkinter as tk -from tkinter import ttk +from tkinter import Frame +from tkinter import Label +from tkinter import BooleanVar +from tkinter import DoubleVar +from tkinter import StringVar from tkinter import scrolledtext +from tkinter import Toplevel +from tkinter import Canvas + +from tkinter.ttk import Button +from tkinter.ttk import Scrollbar +from tkinter.ttk import Progressbar +from tkinter.ttk import Checkbutton +from tkinter.ttk import Entry def set_geometry_by_parent(widget,parent): x_offset = int(parent.winfo_rootx()+0.5*(parent.winfo_width()-widget.winfo_width())) @@ -45,7 +56,7 @@ def __init__(self,parent,icon,bg_color,title,pre_show=None,post_close=None,min_w self.bg_color=bg_color self.icon = icon - self.widget = tk.Toplevel(parent,bg=self.bg_color,bd=0, relief='flat') + self.widget = Toplevel(parent,bg=self.bg_color,bd=0, relief='flat') self.widget.withdraw() self.widget.update() self.widget.protocol("WM_DELETE_WINDOW", lambda : self.hide()) @@ -57,7 +68,7 @@ def __init__(self,parent,icon,bg_color,title,pre_show=None,post_close=None,min_w self.focus=None - self.widget.iconphoto(False, self.icon) + self.widget.iconphoto(False, *icon) self.widget.title(title) self.widget.bind('', lambda event : self.hide() ) @@ -70,16 +81,16 @@ def __init__(self,parent,icon,bg_color,title,pre_show=None,post_close=None,min_w self.pre_show=pre_show self.post_close=post_close - self.area_main = tk.Frame(self.widget,bg=self.bg_color) + self.area_main = Frame(self.widget,bg=self.bg_color) self.area_main.pack(side='top',expand=1,fill='both') #only grid here self.area_main.grid_columnconfigure(0, weight=1) - self.area_buttons = tk.Frame(self.widget,bg=self.bg_color) + self.area_buttons = Frame(self.widget,bg=self.bg_color) self.area_buttons.pack(side='bottom',expand=0,fill='x') - self.wait_var=tk.BooleanVar() + self.wait_var=BooleanVar() self.wait_var.set(False) self.do_command_after_show=None @@ -145,7 +156,7 @@ def show(self,wait=True): #windows re-show workaround try: - self.widget.iconphoto(False, self.icon) + self.widget.iconphoto(False, *self.icon) except Exception as e: print(e) @@ -188,10 +199,10 @@ class LabelDialog(GenericDialog): def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=300,min_height=120): super().__init__(parent,icon,bg_color,'',pre_show,post_close,min_width,min_height) - self.label = tk.Label(self.area_main, text='',justify='center',bg=self.bg_color) + self.label = Label(self.area_main, text='',justify='center',bg=self.bg_color) self.label.grid(row=0,column=0,padx=5,pady=5) - self.cancel_button=ttk.Button(self.area_buttons, text='OK', width=14, command=super().hide ) + self.cancel_button=Button(self.area_buttons, text='OK', width=14, command=super().hide ) self.cancel_button.pack(side='bottom', anchor='n',padx=5,pady=5) self.focus=self.cancel_button @@ -202,6 +213,28 @@ def show(self,title='',message=''): super().show() +class LabelDialogQuestion(LabelDialog): + def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=300,min_height=200,image=''): + super().__init__(parent,icon,bg_color,pre_show,post_close,min_width,min_height) + + self.cancel_button.configure(text='Cancel') + self.cancel_button.pack(side='left', anchor='n',padx=5,pady=5) + + self.ok_button=Button(self.area_buttons, text='OK', width=13, command=self.ok,image=image, compound='right' ) + self.ok_button.pack(side='right', anchor='n',padx=5,pady=5) + + self.focus=self.cancel_button + + def ok (self): + self.res_bool=True + self.wait_var.set(True) + super().hide() + + def show(self,title='',message=''): + self.res_bool=False + super().show(title,message) + + class ProgressDialog(GenericDialog): def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=550,min_height=120): super().__init__(parent,icon,bg_color,'',pre_show,post_close,min_width,min_height) @@ -210,37 +243,37 @@ def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=5 self.prev_text={} self.prev_image={} for i in range(5): - self.lab[i] = tk.Label(self.area_main, text='',justify='center',bg=self.bg_color) + self.lab[i] = Label(self.area_main, text='',justify='center',bg=self.bg_color) self.lab[i].grid(row=i+1,column=0,padx=5) self.prev_text[i]='' self.prev_image[i]=None - self.abort_button=ttk.Button(self.area_buttons, text='Abort', width=10,command=lambda : self.hide() ) + self.abort_button=Button(self.area_buttons, text='Abort', width=10,command=lambda : self.hide() ) self.abort_button.pack(side='bottom', anchor='n',padx=5,pady=5) - (frame_0:=tk.Frame(self.area_main,bg=self.bg_color)).grid(row=0, column=0, sticky='news') - self.progr1var = tk.DoubleVar() - self.progr1=ttk.Progressbar(frame_0,orient='horizontal',length=100, mode='determinate',variable=self.progr1var) + (frame_0:=Frame(self.area_main,bg=self.bg_color)).grid(row=0, column=0, sticky='news') + self.progr1var = DoubleVar() + self.progr1=Progressbar(frame_0,orient='horizontal',length=100, mode='determinate',variable=self.progr1var) self.progr1.grid(row=0,column=1,padx=1,pady=4,sticky='news') - self.lab_l1=tk.Label(frame_0,width=22,bg=self.bg_color) + self.lab_l1=Label(frame_0,width=22,bg=self.bg_color) self.lab_l1.grid(row=0,column=0,padx=1,pady=4) self.lab_l1.config(text='l1') - self.lab_r1=tk.Label(frame_0,width=22,bg=self.bg_color) + self.lab_r1=Label(frame_0,width=22,bg=self.bg_color) self.lab_r1.grid(row=0,column=2,padx=1,pady=4) self.lab_r1.config(text='r1') - self.progr2var = tk.DoubleVar() - self.progr2=ttk.Progressbar(frame_0,orient='horizontal',length=100, mode='determinate',variable=self.progr2var) + self.progr2var = DoubleVar() + self.progr2=Progressbar(frame_0,orient='horizontal',length=100, mode='determinate',variable=self.progr2var) self.progr2.grid(row=1,column=1,padx=1,pady=4,sticky='news') - self.lab_l2=tk.Label(frame_0,width=22,bg=self.bg_color) + self.lab_l2=Label(frame_0,width=22,bg=self.bg_color) self.lab_l2.grid(row=1,column=0,padx=1,pady=4) self.lab_l2.config(text='l2') - self.lab_r2=tk.Label(frame_0,width=22,bg=self.bg_color) + self.lab_r2=Label(frame_0,width=22,bg=self.bg_color) self.lab_r2.grid(row=1,column=2,padx=1,pady=4) self.lab_r2.config(text='r2') @@ -290,7 +323,7 @@ def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=1 self.area_main.grid_rowconfigure(0, weight=1) - self.cancel_button=ttk.Button(self.area_buttons, text='Close', width=14, command=super().hide ) + self.cancel_button=Button(self.area_buttons, text='Close', width=14, command=super().hide ) self.cancel_button.pack(side='bottom', anchor='n',padx=5,pady=5) self.focus=self.cancel_button @@ -318,7 +351,7 @@ def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=8 self.cancel_button.configure(text='Cancel') self.cancel_button.pack(side='left', anchor='n',padx=5,pady=5) - self.ok_button=ttk.Button(self.area_buttons, text='OK', width=14, command=self.ok,image=image, compound='right' ) + self.ok_button=Button(self.area_buttons, text='OK', width=14, command=self.ok,image=image, compound='right' ) self.ok_button.pack(side='right', anchor='n',padx=5,pady=5) self.focus=self.cancel_button @@ -337,12 +370,12 @@ def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=4 self.cancel_button.configure(text='Cancel') - self.entry_val=tk.StringVar() + self.entry_val=StringVar() - self.entry = ttk.Entry(self.area_main, textvariable=self.entry_val,justify='left') + self.entry = Entry(self.area_main, textvariable=self.entry_val,justify='left') self.entry.grid(row=2,column=0,padx=5,pady=5,sticky="wens") - self.button_ok = ttk.Button(self.area_buttons, text='OK', width=14, command=self.ok ) + self.button_ok = Button(self.area_buttons, text='OK', width=14, command=self.ok ) self.button_ok.pack(side='left', anchor='n',padx=5,pady=5) self.cancel_button.pack(side='right') @@ -371,9 +404,9 @@ class CheckboxEntryDialogQuestion(EntryDialogQuestion): def __init__(self,parent,icon,bg_color,pre_show=None,post_close=None,min_width=400,min_height=120): super().__init__(parent,icon,bg_color,pre_show,post_close,min_width,min_height) - self.check_val=tk.BooleanVar() + self.check_val=BooleanVar() - self.check = ttk.Checkbutton(self.area_main, variable=self.check_val) + self.check = Checkbutton(self.area_main, variable=self.check_val) self.check.grid(row=1,column=0,padx=5,pady=5,sticky="wens") self.result2=None @@ -392,10 +425,10 @@ class FindEntryDialog(CheckboxEntryDialogQuestion): def __init__(self,parent,icon,bg_color,mod_cmd,prev_cmd,next_cmd,pre_show=None,post_close=None,min_width=400,min_height=120): super().__init__(parent,icon,bg_color,pre_show,post_close,min_width,min_height) - self.button_prev = ttk.Button(self.area_buttons, text='prev (Shift+F3)', width=14, command=self.prev ) + self.button_prev = Button(self.area_buttons, text='prev (Shift+F3)', width=14, command=self.prev ) self.button_prev.pack(side='left', anchor='n',padx=5,pady=5) - self.button_next = ttk.Button(self.area_buttons, text='next (F3)', width=14, command=self.next ) + self.button_next = Button(self.area_buttons, text='next (F3)', width=14, command=self.next ) self.button_next.pack(side='right', anchor='n',padx=5,pady=5) self.mod_cmd=mod_cmd @@ -445,15 +478,15 @@ def show(self,title='',message='',initial='',checkbutton_text='',checkbutton_ini except Exception as e: print(e) -class SFrame(tk.Frame): +class SFrame(Frame): def __init__(self, parent,bg,width=200,height=100): super().__init__(parent,bg=bg) self.windows = bool(os_name=='nt') - self.canvas = tk.Canvas(self, bd=0, bg=bg,highlightcolor=bg,width=width,height=height,relief='flat') - self.f = tk.Frame(self.canvas, bg=bg,takefocus=False) - self.vsb = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview) + self.canvas = Canvas(self, bd=0, bg=bg,highlightcolor=bg,width=width,height=height,relief='flat') + self.f = Frame(self.canvas, bg=bg,takefocus=False) + self.vsb = Scrollbar(self, orient="vertical", command=self.canvas.yview) self.canvas.configure(yscrollcommand=self.vsb.set) self.canvas.configure(highlightthickness=0,takefocus=False) diff --git a/src/executor.py b/src/executor.py index c3f6c63..6d21c1d 100644 --- a/src/executor.py +++ b/src/executor.py @@ -33,7 +33,6 @@ from psutil import Process from signal import SIGTERM - class Executor : def __init__(self): self.command_list_to_execute = None diff --git a/src/librer.py b/src/librer.py index 5658271..446baf8 100644 --- a/src/librer.py +++ b/src/librer.py @@ -384,6 +384,35 @@ def post_close(self,on_main_window_dialog=True): self.menu_enable() self.menubar_config(cursor="") + text_info_dialog_created = False + @restore_status_line + @block_actions_processing + @gui_block + def get_text_info_dialog(self): + if not self.text_info_dialog_created: + self.status("Opening dialog ...") + + self.text_info_dialog = dialogs.TextDialogInfo(self.main,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + + self.text_info_dialog_created = True + + return self.text_info_dialog + + + ask_dialog_on_main_created = False + @restore_status_line + @block_actions_processing + @gui_block + def get_ask_dialog_on_main(self): + if not self.ask_dialog_on_main_created: + self.status("Opening dialog ...") + + self.ask_dialog_on_main = dialogs.LabelDialogQuestion(self.main,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close,image=self.ico['warning']) + + self.ask_dialog_on_main_created = True + + return self.ask_dialog_on_main + scan_dialog_created = False @restore_status_line @block_actions_processing @@ -394,7 +423,7 @@ def get_scan_dialog(self): self_ico_librer = self.ico_librer - self.scan_dialog=dialogs.GenericDialog(self.main,self.ico_librer,self.bg_color,'Create new data record',pre_show=self.pre_show,post_close=self.post_close,min_width=800,min_height=520) + self.scan_dialog=dialogs.GenericDialog(self.main,(self.ico_librer,self.ico_record),self.bg_color,'Create new data record',pre_show=self.pre_show,post_close=self.post_close,min_width=800,min_height=520) self_ico = self.ico @@ -428,7 +457,7 @@ def get_scan_dialog(self): self.widget_tooltip(scan_label_entry,"Label of record to be created\nCannot be changed later.") - lab1=Label(temp_frame,text="Path To scan:",bg=self.bg_color,anchor='w') + lab1=Label(temp_frame,text="Path to scan:",bg=self.bg_color,anchor='w') lab1.grid(row=0, column=2, sticky='news',padx=4,pady=4) self.path_to_scan_entry_var=StringVar(value=self.last_dir) @@ -453,7 +482,9 @@ def get_scan_dialog(self): self.exclude_regexp_scan=BooleanVar() temp_frame2 = LabelFrame(self.scan_dialog.area_main,text='Exclude from scan:',borderwidth=2,bg=self.bg_color,takefocus=False) - temp_frame2.grid(row=2,column=0,sticky='news',padx=4,pady=4,columnspan=4) + + #TODO + #temp_frame2.grid(row=2,column=0,sticky='news',padx=4,pady=4,columnspan=4) self.exclude_scroll_frame=dialogs.SFrame(temp_frame2,bg=self.bg_color) self.exclude_scroll_frame.pack(fill='both',expand=True,side='top') @@ -482,7 +513,8 @@ def get_scan_dialog(self): ############## skip_button = Checkbutton(self.scan_dialog.area_main,text='log skipped files',variable=self.log_skipped_var) - skip_button.grid(row=4,column=0,sticky='news',padx=8,pady=3,columnspan=3) + #TODO + #skip_button.grid(row=4,column=0,sticky='news',padx=8,pady=3,columnspan=3) self.widget_tooltip(skip_button,"log every skipped file (softlinks, hardlinks, excluded, no permissions etc.)") @@ -514,10 +546,10 @@ def get_scan_dialog(self): use_tooltip = "Mark to use CD Extractor" mask_tooltip = "glob expresions separated by comma ','\ne.g. '*.7z, *.zip, *.gz'" - min_tooltip = "Minimum size of file to aplly CD expresion or crc\nmay be empty e.g. 0" - max_tooltip = "Maximum size of file aplly CD expresion or crc\nmay be empty e.g. '100MB'" + min_tooltip = "Minimum size of file\nto aplly CD extraction or crc\nmay be empty e.g. 0" + max_tooltip = "Maximum size of file\nto aplly CD extraction or crc\nmay be empty e.g. '100MB'" exec_tooltip = "executable or batch script that will be run\nwith file for extraction\nmay have parameters\nWill be executed with scanned file full path\ne.g. '7z l', 'cat', '~/my_extraction.sh', 'c:\\my_extraction.bat'" - open_tooltip = "set executable file af Custom Data Extractor..." + open_tooltip = "set executable file as Custom Data Extractor..." timeout_tooltip = "Time limit in seconds for single CD extraction.\nAfter timeout executed process will be terminated" test_tooltip = "Test Custom Data Extractor\non single selected file ..." crc_tooltip = "Calculate CRC (SHA1) for ALL\nfiles matching glob and size cryteria\nIt may take a long time." @@ -595,12 +627,12 @@ def get_scan_dialog(self): ########################################### - self.info_dialog_on_scan = dialogs.LabelDialog(self.scan_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) - self.text_dialog_on_scan = dialogs.TextDialogInfo(self.scan_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) - self.text_ask_dialog_on_scan = dialogs.TextDialogQuestion(self.scan_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close,image=self_ico['warning']) - self.exclude_dialog_on_scan = dialogs.EntryDialogQuestion(self.scan_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.info_dialog_on_scan = dialogs.LabelDialog(self.scan_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.text_dialog_on_scan = dialogs.TextDialogInfo(self.scan_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.text_ask_dialog_on_scan = dialogs.TextDialogQuestion(self.scan_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close,image=self_ico['warning']) + self.exclude_dialog_on_scan = dialogs.EntryDialogQuestion(self.scan_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) - self.progress_dialog_on_scan = dialogs.ProgressDialog(self.scan_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.progress_dialog_on_scan = dialogs.ProgressDialog(self.scan_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) self.progress_dialog_on_scan.command_on_close = self.progress_dialog_abort self.widget_tooltip(self.progress_dialog_on_scan.abort_button,'') @@ -620,9 +652,9 @@ def get_find_dialog(self): self_ico_librer = self.ico_librer ################################### - self.find_dialog=dialogs.GenericDialog(self.main,self_ico_librer,self.bg_color,'Search database',pre_show=self.pre_show,post_close=self.post_close) + self.find_dialog=dialogs.GenericDialog(self.main,(self.ico_librer,self.ico_record),self.bg_color,'Search database',pre_show=self.pre_show,post_close=self.post_close) - self.progress_dialog_on_find = dialogs.ProgressDialog(self.find_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.progress_dialog_on_find = dialogs.ProgressDialog(self.find_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) self.progress_dialog_on_find.command_on_close = self.progress_dialog_find_abort self.widget_tooltip(self.progress_dialog_on_find.abort_button,'') @@ -797,8 +829,8 @@ def validate_size_str(val): sfdma.grid_rowconfigure(4, weight=1) sfdma.grid_columnconfigure(0, weight=1) - self.info_dialog_on_find = dialogs.LabelDialog(self.find_dialog.widget,self_ico_librer,self.bg_color,pre_show=lambda new_widget : self.pre_show(on_main_window_dialog=False,new_widget=new_widget),post_close=lambda : self.post_close(on_main_window_dialog=False)) - self.text_dialog_on_find = dialogs.TextDialogInfo(self.find_dialog.widget,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.info_dialog_on_find = dialogs.LabelDialog(self.find_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=lambda new_widget : self.pre_show(on_main_window_dialog=False,new_widget=new_widget),post_close=lambda : self.post_close(on_main_window_dialog=False)) + self.text_dialog_on_find = dialogs.TextDialogInfo(self.find_dialog.widget,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) self.find_dialog_created = True @@ -812,7 +844,7 @@ def get_about_dialog(self): if not self.about_dialog_created: self.status("Opening dialog ...") - self.aboout_dialog=dialogs.GenericDialog(self.main,self.ico_librer,self.bg_color,'',pre_show=self.pre_show,post_close=self.post_close) + self.aboout_dialog=dialogs.GenericDialog(self.main,(self.ico_librer,self.ico_record),self.bg_color,'',pre_show=self.pre_show,post_close=self.post_close) frame1 = LabelFrame(self.aboout_dialog.area_main,text='',bd=2,bg=self.bg_color,takefocus=False) frame1.grid(row=0,column=0,sticky='news',padx=4,pady=(4,2)) @@ -863,7 +895,7 @@ def get_license_dialog(self): l_error(exception_2) self.exit() - self.license_dialog=dialogs.GenericDialog(self.main,self.ico['license'],self.bg_color,'',pre_show=self.pre_show,post_close=self.post_close,min_width=800,min_height=520) + self.license_dialog=dialogs.GenericDialog(self.main,(self.ico['license'],self.ico['license']),self.bg_color,'',pre_show=self.pre_show,post_close=self.post_close,min_width=800,min_height=520) frame1 = LabelFrame(self.license_dialog.area_main,text='',bd=2,bg=self.bg_color,takefocus=False) frame1.grid(row=0,column=0,sticky='news',padx=4,pady=4) @@ -1113,11 +1145,11 @@ def __init__(self,cwd): ####################################################################### - self.info_dialog_on_main = dialogs.LabelDialog(self_main,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) - self.text_ask_dialog = dialogs.TextDialogQuestion(self_main,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close,image=self_ico['warning']) - self.text_info_dialog = dialogs.TextDialogInfo(self_main,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.info_dialog_on_main = dialogs.LabelDialog(self_main,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + + #self.text_ask_dialog_on_main = dialogs.TextDialogQuestion(self_main,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close,image=self_ico['warning']) - self.progress_dialog_on_load = dialogs.ProgressDialog(self_main,self_ico_librer,self.bg_color,pre_show=self.pre_show,post_close=self.post_close) + self.progress_dialog_on_load = dialogs.ProgressDialog(self_main,(self.ico_librer,self.ico_record),self.bg_color,pre_show=self.pre_show,post_close=self.post_close) self.progress_dialog_on_load.command_on_close = self.progress_dialog_load_abort self.widget_tooltip(self.progress_dialog_on_load.abort_button,'') @@ -1432,7 +1464,8 @@ def show_tooltips_tree(self,event): record_path = record.db.scan_path size = core_bytes_to_str(record.db.sum_size) - self.tooltip_lab_configure(text=f'record:{record_name}\npath:{record_path}\nsize:{size}' + (f'\n\n{node_cd}' if node_cd else '')) + time_info = strftime('%Y/%m/%d %H:%M:%S',localtime(record.db.get_time())) + self.tooltip_lab_configure(text=record.get_info() + (f'\n\n================================================================\n{node_cd}' if node_cd else '') ) self.tooltip_deiconify() @@ -2681,9 +2714,11 @@ def delete_data_record(self): path = self.current_record.db.scan_path creation_time = self.current_record.db.creation_time - self.text_ask_dialog.show('Delete selected data record ?','Data record: ' + label + '\n\n' + path) + dialog = self.get_ask_dialog_on_main() + + dialog.show('Delete selected data record ?',f'Data record label: {label}\n\nscan path:{path}\n\ndata file:{self.current_record.FILE_NAME}' ) - if self.text_ask_dialog.res_bool: + if dialog.res_bool: librer_core.delete_record_by_id(self.current_record.db.rid) record_item = self.record_to_item[self.current_record] self.tree.delete(record_item) @@ -2876,15 +2911,22 @@ def open_item(self,event=None,item=None): #print('data_tuple:',data_tuple) - len_data_tuple = len(data_tuple) - if len_data_tuple==4: - (entry_name,code,size,mtime) = data_tuple - elif len_data_tuple==5: - (entry_name,code,size,mtime,fifth_field) = data_tuple - else: - l_error(f'data format incompatible:{data_tuple}') - print(f'data format incompatible:{data_tuple}') - continue + (entry_name,code,size,mtime) = data_tuple[0:4] + + #len_data_tuple = len(data_tuple) + #if len_data_tuple==4: + #elif len_data_tuple==5: + try: + fifth_field = data_tuple[4] + #(entry_name,code,size,mtime,fifth_field) = data_tuple + except: + pass + + #else: + # fifth_field = None + # l_error(f'data format incompatible:{data_tuple}') + # print(f'data format incompatible:{data_tuple}') + # continue #sub_dictionary,cd @@ -3067,8 +3109,8 @@ def tree_action(self,item): #if not opened: # self.open_item(None,item) elif kind == self.RECORD : - info_list=[f'name:{record_name}',f'scan path:{record.db.scan_path}',f'size:{core.bytes_to_str(record.db.sum_size)}'] - self.text_info_dialog.show('Record Info.','\n'.join(info_list)) + time_info = strftime('%Y/%m/%d %H:%M:%S',localtime(record.db.get_time())) + self.get_text_info_dialog().show('Record Info.',record.get_info()) #if opened: # self.open_item(None,item) @@ -3085,7 +3127,7 @@ def tree_action(self,item): if cd_data := fifth_field: cd_txt = record.get_cd_text(cd_data,is_compressed) - self.text_info_dialog.show('Custom Data',cd_txt) + self.get_text_info_dialog().show('Custom Data',cd_txt) return self.info_dialog_on_main.show('Information','No Custom data.')