1212from PySide6 .QtWidgets import (
1313 QMainWindow , QApplication , QWidget , QVBoxLayout , QHBoxLayout ,
1414 QTabWidget , QMenuBar , QMenu , QToolBar , QStatusBar , QSplitter ,
15- QLabel , QPushButton , QMessageBox , QFileDialog , QDockWidget
15+ QLabel , QPushButton , QMessageBox , QFileDialog , QDockWidget , QInputDialog
1616)
1717from PySide6 .QtCore import Qt , QTimer , QSize , Signal
18- from PySide6 .QtGui import QAction , QFont , QKeySequence , QIcon
18+ from PySide6 .QtGui import QAction , QFont , QKeySequence , QIcon , QTextCursor
1919
2020# Lokale Imports
2121sys .path .insert (0 , str (Path (__file__ ).parent .parent ))
@@ -70,6 +70,7 @@ def __init__(self):
7070 # Aktives Projekt
7171 self .current_project : Optional [ProjectConfig ] = None
7272 self .open_files : Dict [str , CodeEditor ] = {}
73+ self ._search_term = ""
7374
7475 # UI Setup
7576 self .setWindowTitle ("DevCenter" )
@@ -546,13 +547,11 @@ def _setup_connections(self):
546547
547548 def _restore_state (self ):
548549 """Stellt den Fensterzustand wieder her"""
549- state = self .settings .get ('window.state' , {})
550-
551- if 'geometry' in state :
552- pass # TODO: Geometrie wiederherstellen
553-
554- if 'maximized' in state and state ['maximized' ]:
555- self .showMaximized ()
550+ geometry , state = self .settings .restore_window_state ()
551+ if geometry :
552+ self .restoreGeometry (geometry )
553+ if state :
554+ self .restoreState (state )
556555
557556 def _show_welcome (self ):
558557 """Zeigt Welcome-Screen oder öffnet letztes Projekt"""
@@ -605,6 +604,7 @@ def _load_project(self, project: ProjectConfig):
605604 def _new_file (self ):
606605 """Erstellt eine neue leere Datei"""
607606 editor = CodeEditor ()
607+ self ._apply_editor_settings (editor )
608608 self .editor_tabs .addTab (editor , "Unbenannt" )
609609 self .editor_tabs .setCurrentWidget (editor )
610610 self ._connect_editor (editor )
@@ -628,6 +628,7 @@ def _open_file_path(self, path: str):
628628
629629 # Neue Datei öffnen
630630 editor = CodeEditor ()
631+ self ._apply_editor_settings (editor )
631632 if editor .load_file (path ):
632633 self .open_files [path ] = editor
633634 name = os .path .basename (path )
@@ -641,6 +642,21 @@ def _connect_editor(self, editor: CodeEditor):
641642 """Verbindet Editor-Signale"""
642643 editor .file_modified .connect (self ._on_file_modified )
643644 editor .cursor_position_changed .connect (self ._on_cursor_changed )
645+
646+ def _apply_editor_settings (self , editor : CodeEditor ):
647+ """Wendet die aktuellen Editor-Einstellungen auf einen Editor an."""
648+ line_numbers = self .settings .get ('editor.line_numbers' , None )
649+ if line_numbers is None :
650+ line_numbers = self .settings .get ('editor.show_line_numbers' , True )
651+
652+ editor .apply_settings (
653+ font_family = self .settings .get ('editor.font_family' , 'Consolas' ),
654+ font_size = self .settings .get ('editor.font_size' , 11 ),
655+ tab_size = self .settings .get ('editor.tab_size' , 4 ),
656+ show_line_numbers = bool (line_numbers ),
657+ auto_complete = self .settings .get ('editor.auto_complete' , True ),
658+ highlight_current_line = self .settings .get ('editor.highlight_current_line' , True ),
659+ )
644660
645661 def _save_file (self ):
646662 """Speichert die aktuelle Datei"""
@@ -760,12 +776,62 @@ def _paste(self):
760776 editor .paste ()
761777
762778 def _find (self ):
763- """TODO: Such-Dialog"""
764- pass
779+ """Öffnet einfachen Suchdialog."""
780+ editor = self ._get_current_editor ()
781+ if not editor :
782+ self .statusbar .showMessage ("Kein aktiver Editor vorhanden" , 2000 )
783+ return
784+
785+ default = editor .textCursor ().selectedText () or self ._search_term
786+ pattern , ok = QInputDialog .getText (
787+ self , "Suchen" , "Suchbegriff:" , text = default
788+ )
789+ if not ok or not pattern :
790+ return
791+
792+ self ._search_term = pattern
793+
794+ if not editor .find (pattern ):
795+ cursor = editor .textCursor ()
796+ cursor .movePosition (QTextCursor .MoveOperation .Start )
797+ editor .setTextCursor (cursor )
798+ if not editor .find (pattern ):
799+ self .statusbar .showMessage (f"\" { pattern } \" nicht gefunden" , 2500 )
800+ return
801+
802+ self .statusbar .showMessage (f"Gefunden: { pattern } " , 2500 )
765803
766804 def _replace (self ):
767- """TODO: Ersetzen-Dialog"""
768- pass
805+ """Öffnet einfachen Ersetzen-Dialog."""
806+ editor = self ._get_current_editor ()
807+ if not editor :
808+ self .statusbar .showMessage ("Kein aktiver Editor vorhanden" , 2000 )
809+ return
810+
811+ search_text , ok = QInputDialog .getText (
812+ self , "Ersetzen" , "Zu ersetzen:" , text = editor .textCursor ().selectedText ()
813+ )
814+ if not ok or not search_text :
815+ return
816+
817+ replace_text , ok = QInputDialog .getText (
818+ self , "Ersetzen" , "Durch diesen Text ersetzen:"
819+ )
820+ if not ok :
821+ return
822+
823+ text = editor .toPlainText ()
824+ matches = text .count (search_text )
825+ if matches == 0 :
826+ self .statusbar .showMessage (f'"{ search_text } " nicht gefunden' , 2500 )
827+ return
828+
829+ cursor_pos = editor .textCursor ().position ()
830+ editor .setPlainText (text .replace (search_text , replace_text ))
831+ cursor = editor .textCursor ()
832+ cursor .setPosition (min (cursor_pos , len (editor .toPlainText ())))
833+ editor .setTextCursor (cursor )
834+ self .statusbar .showMessage (f"{ matches } Ersetzung(en) durchgeführt" , 2500 )
769835
770836 # === Ansicht-Operationen ===
771837
@@ -920,7 +986,10 @@ def _apply_settings(self):
920986 self .ai_service .set_api_key (self .settings .get ('ai.api_key' , '' ))
921987
922988 # Editor-Einstellungen auf alle offenen Editoren anwenden
923- # TODO: Implementieren
989+ for index in range (self .editor_tabs .count ()):
990+ widget = self .editor_tabs .widget (index )
991+ if isinstance (widget , CodeEditor ):
992+ self ._apply_editor_settings (widget )
924993
925994 def _show_about (self ):
926995 """Zeigt den Über-Dialog"""
0 commit comments