Y:iXdZddlZddlmZmZmZmZmZmZm Z m Z m Z m Z m Z mZmZmZmZddlmZmZddlmZddlmZmZej4eZGddeZy) z`Main Window for ChefSystem. The primary application window with recipe list and details panel. N) QMainWindowQWidget QVBoxLayout QHBoxLayoutQToolBar QLineEdit QListWidget QSplitterQLabel QTextEdit QPushButtonQListWidgetItem QMessageBox QApplication QComboBox)Qt QSettings)QAction)RecipeOutputc,eZdZdZdeffd Zd$dZd$dZdefdZ defd Z d$d Z d%d e d e ddfd Z d$dZd$dZdedzddfdZdeddfdZdeddfdZdeddfdZde ddfdZdeddfdZd$dZd$dZd$dZd$dZd$dZd eddfd!Zd$d"Z d$d#Z!xZ"S)& MainWindowz}Main application window for ChefSystem. Displays recipe list, search bar, action buttons, and recipe details panel. configc2t|||_||_d|_|j d|j dd|j|j|j|j|jy)zInitialize the main window. Args: db: DatabaseManager instance. config: Application configuration dictionary. NzChefSystem - AI Prompt ManageriiX) super__init__dbrcurrent_recipesetWindowTitlesetMinimumSize _setup_ui_connect_signals_restore_geometrypopulate_tag_filter load_recipes)selfrr __class__s 9/mnt/ssd/data/python-lab/ChefSystem/src/ui/main_window.pyrzMainWindow.__init__s  " <= D#&       " returnNc|jttjj}|j }|j ||j}|j ||jddgt}t}|j ||jdddd|j||j|y)z%Set up the user interface components.,irN)_create_toolbarr r Orientation Horizontal_create_left_panel addWidget_create_right_panelsetSizesrrsetContentsMargins setLayoutsetCentralWidget)r&splitter left_panel right_panelcentral_widgetlayouts r(r!zMainWindow._setup_ui2s R^^667,,. :&..0 ;' 3*%!"!!!Q1-  ( n-r)ctd}|jd|j|td|}|j d|j d|j d|jj|j|j|td||_ |jj d|jj d |jj d |jjd|jjj|j|j|jtd ||_|jj d |jj d |jj d |jjd|jjj|j|j|j|j!td||_|j"j d|j"j d|j"j d|j"jd|j"jj|j$|j|j"|j!td||_|j&j d|j&j d|j&j d|j&jd|j&jj|j(|j|j&y)z'Create the toolbar with action buttons.z Main ToolbarFz New RecipezCreate a new recipezCtrl+NzCreate a new recipe (Ctrl+N)EditzEdit selected recipezCtrl+EzEdit selected recipe (Ctrl+E)DeletezDelete selected recipez#Delete selected recipe (Delete key)z Copy PromptzCopy prompt to clipboardzCtrl+Cz!Copy prompt to clipboard (Ctrl+C)zManage Outputsz"Add, view, and manage output fileszCtrl+Oz,Manage output files for this recipe (Ctrl+O)N)r setMovable addToolBarr setStatusTip setShortcut setToolTip triggeredconnect on_new_recipe addAction edit_action setEnabledon_edit_recipe delete_actionon_delete_recipe addSeparator copy_actionon_copy_promptmanage_outputs_actionon_manage_outputs)r&toolbar new_actions r(r-zMainWindow._create_toolbarMs>*5!  \40  56x(<=$$T%7%78*%#640 %%&<= $$X. ##$CD ##E* ""**4+>+>?$**+%Xt4 ''(@A &&x0 %%&KL %%e, $$,,T-B-BC$,,-#=$7 %%&@A $$X. ##$GH ##E* ""**4+>+>?$**+&--=t%D" ""//0TU ""..x8 ""--.\] ""--e4 "",,44T5K5KL$445r)cbt}t}td}t|_|jj d|j ||j |jtd}t|_|jjdd|j ||j |jtd}t|_ |j ||j |j|j||S)zuCreate the left panel with recipe list and search. Returns: QWidget: Left panel widget. zSearch Recipes:zType to search...zFilter by Tag:All TagsNzRecipes:) rrr r search_boxsetPlaceholderTextr1r tag_filteraddItemr recipe_listr5)r&panelr; search_label tag_label list_labels r(r0zMainWindow._create_left_panels  /0 #+ **+>?&)+, #+  D1#)J' &=$))*  r)c\t}t}td}|j|td|_|j|jtd|_|j|j td}t |_|jjd|jjd|j||j|jtd}t |_ |jjd|jjd|j||j|jtd }|j|t|_ |jjd|j|jtd |_ |j|j|j|j||S) zoCreate the right panel with recipe details. Returns: QWidget: Right panel widget. z

Recipe Details

Name: No recipe selectedTags: -zDescription:PTzPrompt Preview:z

Recent Outputs

%Created: - | Updated: -)rrr r1 name_label tags_labelr description_textsetMaximumHeight setReadOnlyprompt_previewr outputs_list dates_label addStretchr5)r&r[r; details_labeldescription_label prompt_label outputs_labels r(r2zMainWindow._create_right_panels  89 '!!BC)!!12)##89 )  ..r2 ))$/*+../67 'k ,,S1 ''-&,,-89 ''M **3/**+""IJ))*  r)c||jjj|j|jj j|j |jjj|j|jjj|jy)zConnect signals to slots.N) rZitemSelectionChangedrEon_recipe_selectedrV textChangedon_search_changedrXcurrentIndexChangedon_tag_filter_changedrkitemDoubleClickedon_output_double_clicked)r&s r(r"zMainWindow._connect_signalss~ --55d6M6MN ##++D,B,BC ++33D4N4NO ++33D4Q4QRr) search_queryrXc  |r|gnd}|s|rJtj|j||}tj d|d|dt |nAtj |j}tj dt |d|jj|D]f}t|j}|jtjj|j|jj!|hy#t"$r>}tj%d|d t'j(|d d |Yd}~yd}~wwxYw) zLoad recipes from database and populate list. Args: search_query: Optional search query to filter recipes. tag_filter: Optional tag to filter recipes by. N)querytagszSearched recipes with query 'z ' and tags z, found zLoaded z recipeszError loading recipes: Texc_infoErrorzFailed to load recipes: )rsearchrloggerinfolenget_allrZclearrnamesetDatar ItemDataRoleUserRoleidrY Exceptionerrorrwarning)r&r{rX tags_listrecipesrecipeitemes r(r%zMainWindow.load_recipess0 O(2 Iy --|)T ;L>U^T__ghklshtguvw ..1 gc'l^8<=    " " $! /&v{{3 R__55vyyA  ((. /  O LL21#6L F   g1I!/M N N OsDD E%'4E  E%cP tj|j}t}|D]g}|js|jj dDcgc]#}|j s|j %}}|j|i|jj}|jj|jjddt|D]}|jj|| |r;|jj|}|dk\r|jj|tj!dt#|dycc}w#t$$r$}tj'd|d Yd}~yd}~wwxYw) z?Populate tag filter dropdown with unique tags from all recipes.,rUNrzPopulated tag filter with z unique tagszError populating tag filter: Tr)rrrsetr~splitstripupdaterX currentDatarrYsortedfindDatasetCurrentIndexrdebugrrr) r& all_recipestags_setrtag recipe_tags current_tagindexrs r(r$zMainWindow.populate_tag_filters^ M ..1KuH% 1;;:@++:K:KC:P"`3TWT]T]T_399;"`K"`OOK0  1//557K OO ! ! # OO # #J 5h' 2''S1 200=A:OO33E: LL5c(m_LQ R)#a, M LL8?   N LL0 2aSADL Q   g1H/L M M Ns6A-C%% D/.7D**D/rc||jjd|jjd|jj |j j |j j |jjdy|jjd|j|jjd|jr |jnd|jj|jr |jnd|jdd }t|jd kDr|d z }|j j||jr|jjd nd}|j r|j jd nd}|jjd |d ||j#|j$y)zUpdate the details panel with recipe information. Args: recipe: Recipe to display, or None to clear. Nr`rardz Name: z Tags: -zNo descriptionr,z...%Y-%m-%d %H:%MzCreated: z | Updated: )resetTextrfrgrrjrkrlrr~ setPlainText description prompt_textr created_atstrftime updated_at_load_recent_outputsr)r&r preview_textcreatedupdateds r(rzMainWindow.update_details_panel>s > OO # #$E F OO # #$4 5  ! ! ' ' )    % % '    # # %    $ $%L M  - } => -v{{ PS/T UV **ASAS6+=+=Yij))$3/ v!! "S ( E !L ((6CIBSBS&##,,-=>Y\BHBSBS&##,,-=>Y\   #3G9G    # # %""1+ 0NTNaNaF//889IJgj %/r)A> &y1 R__55vyyA!!))$/  0&'78 bkk556!!))$/  ^ LL}tjd |d tj|d d |Yd}~yd}~wwxYw)zHandle new recipe action.r RecipeEditorNrparentzNew recipe created successfullyzRecipe created successfully zNew recipe creation canceledz!Error opening new recipe dialog: TrrFailed to open recipe editor: )src.ui.recipe_editorrrexecrrr$r% get_recipe_idr statusBar showMessagerrrcritical)r&reditor new_recipe_idrs r(rFzMainWindow.on_new_recipes5 V!$''T$GF{{} =>((*!!#!' 4 4 6  --m< ,,-JDQ :; V LL>Dcddlm}|jstj|ddy ||j |jj |}|jrtjd|jj|j|j|j|jj |jjdd ytjd |jjy#t $r>}tj#d |d tj$|dd|Yd}~yd}~wwxYw)zHandle edit recipe action.rr No SelectionzPlease select a recipe to edit.NrzRecipe updated: zRecipe updated successfullyrzEdit recipe canceled: z"Error opening edit recipe dialog: Trrr)rrrrrrrrrrrr$r%rrrrrr)r&rrrs r(rJzMainWindow.on_edit_recipes/5""   n6W X  V!$''T5H5H5K5KTXYF{{} .t/B/B/G/G.HIJ((*!!#))$*=*=*@*@A ,,-JDQ 4T5H5H5M5M4NOP V LL=aSADL Q  w2PQRPS0T U U VsC D$7,D$$ E+-4E&&E+cX|jsytj|dd|jjdtjj tjj ztjj }|tjj k(r tj|j|jj}|rktjd|jjtj|ddd|_|j|jytj |dd yy#t"$r>}tj%d |d tj&|dd |Yd}~yd}~wwxYw)zHandle delete recipe action.NzConfirm Deletez(Are you sure you want to delete recipe 'z1'? This will also delete all associated outputs.zDeleted recipe: SuccesszRecipe deleted successfullyrzFailed to delete recipezError deleting recipe: TrzFailed to delete recipe: )rrquestionrStandardButtonYesNordeleterrrr informationr$r%rrrr)r&replysuccessrs r(rLzMainWindow.on_delete_recipesi"" $$  6t7J7J7O7O6PQ< <  & & * *[-G-G-J-J J  & & ) )   K..22 2 U --1D1D1G1GHKK"243F3F3K3K2L MN++D)=Z[*.D',,.%%'''g7PQ 3 U 6qc:T J$$T76OPQs4STT Us(B E" E"" F)+4F$$F)c(|jsytj}|j|jjt j d|jj|jjddy)z'Handle copy prompt to clipboard action.NzCopied prompt to clipboard: zPrompt copied to clipboardi) rr clipboardrrrrrrr)r&rs r(rOzMainWindow.on_copy_promptsq""  **, $--99: 243F3F3K3K2LMN $$%A4Hr)cddlm}|jstj|ddy ||j |j|}|j |j|jjtjd|jjy#t$r>}tjd|d tj|d d |Yd}~yd}~wwxYw) zHandle manage outputs action.r) OutputManagerrz)Please select a recipe to manage outputs.N)rzOutput manager closed for: zError opening output manager: TrrzFailed to open output manager: )src.ui.output_managerrrrrrrrrrrrrrr)r&rmanagerrs r(rQzMainWindow.on_manage_outputss7""   n6a b  W#DGGT-@-@NG LLN  % %d&9&9&<&< = KK5d6I6I6N6N5OP Q W LL9!=L M  w2QRSQT0U V V WsBB-- C464C//C4rcddlm}|jtjj }|rV ||j }|j|}|stj|ddtjd|y y #t$r>}tjd|dtj|dd |Yd }~y d }~wwxYw) zqHandle double-click on output item (opens file). Args: item: The clicked list item. r) OutputServicerzkFailed to open output file. The file may not exist or no application is configured to open this file type.z"Output double-clicked and opened: zError opening output: TrzFailed to open output: N)src.services.output_servicerrrrrr open_outputrrrrrrr)r&rr output_idoutput_servicerrs r(rzz#MainWindow.on_output_double_clicked*s >IIboo667  S!.tww!7(44Y?''i @ LM  S 5aS9D I$$T76MaS4QRR SsAB C4C  Cct}|jd}|r'|j|tj dyy)z&Restore window geometry from settings.window_geometryzWindow geometry restoredN)rvaluerestoreGeometryrr)r&settingsgeometrys r(r#zMainWindow._restore_geometryFs;;>>"34    * LL3 4 r)c^t}|jd|jtj d |j j tjd|jy#t$r"}tjd|Yd}~7d}~wwxYw)zRHandle window close event. Args: event: Close event. rzWindow geometry savedzDatabase connection closedzError closing database: N) rsetValue saveGeometryrrrcloserrraccept)r&eventrrs r( closeEventzMainWindow.closeEventNs;+T->->-@A ,- 9 GGMMO KK4 5   9 LL3A37 8 8 9s/B B, B''B,)r*N)N)#__name__ __module__ __qualname____doc__dictrr!r-rr0r2r"strr%r$rtrrintrboolrrrvrxrFrJrLrOrQrrzr#r  __classcell__)r's@r(rrs) 4..646lG@4W4lSOOsOdO>"MHN6!-6D=!-T!-F^c^d^4 7T 7d 7 c d EcEdE M3 M4 MV>VBU< IW.S_SS85r)r)rloggingPyQt6.QtWidgetsrrrrrrr r r r r rrrr PyQt6.QtCorerr PyQt6.QtGuirsrc.database.modelsrr getLoggerr rrr)r(rsS  '.   8 $K K r)