Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue 42 fixes #43

Merged
merged 4 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 167 additions & 48 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import extension_mainclass
import requirements
import git_integration
import settings

class TextEditor(wx.Frame):
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -92,6 +93,7 @@ def InitUI(self):

self.file_list = wx.ListBox(self.sidebar)
self.PopulateFileList()
self.file_list.Bind(wx.EVT_RIGHT_DOWN, self.OnFileListRightClick)

self.matching_brackets = {
'(': ')',
Expand Down Expand Up @@ -171,6 +173,7 @@ def CreateMenuBar(self):
fileMenu = wx.Menu()
save_item = fileMenu.Append(wx.ID_SAVE, '&Save\tCtrl+S', 'Save the file')
run_item = fileMenu.Append(wx.ID_ANY, '&Run Code\tCtrl+R', 'Run the code')
folder_item = fileMenu.Append(wx.ID_ANY, '&Open Folder\tCtrl+Shift+O', 'Open Folder')
fileMenu.AppendSeparator()
pylint_item = fileMenu.Append(wx.ID_ANY, '&Run pylint\tCtrl+P', 'Run pylint on code')
exit_item = fileMenu.Append(wx.ID_EXIT, '&Exit\tCtrl+Q', 'Exit application')
Expand All @@ -195,9 +198,6 @@ def CreateMenuBar(self):
req_item = deployment_submenu.Append(wx.ID_ANY, 'Generate requirements.txt')
toolsMenu.AppendSubMenu(deployment_submenu, 'Deployment Tools')

# Create the Customize menu item
customize_item = toolsMenu.Append(wx.ID_ANY, '&Customize\tCtrl+Shift+C', 'Customize the UI')

# Create the Git submenu
git_submenu = wx.Menu() # This is a Menu, not a MenuItem
commit_item = git_submenu.Append(wx.ID_ANY, 'Git Commit', 'Commit the code') # Append to the git submenu
Expand All @@ -210,10 +210,14 @@ def CreateMenuBar(self):
about_item = helpMenu.Append(wx.ID_ABOUT, '&About', 'About')
docs_item = helpMenu.Append(wx.ID_ANY, "&Docs", "Open Documentation")

configMenu = wx.Menu()
customize_item = configMenu.Append(wx.ID_ANY, '&Customize manually\tCtrl+Shift+C', 'Customize the UI')
settings_item = configMenu.Append(wx.ID_ANY, '&Settings', 'Open Settings')

menubar.Append(fileMenu, '&File')
menubar.Append(editMenu, '&Edit')
menubar.Append(toolsMenu,'&Tools')
menubar.Append(configMenu, '&Config')
menubar.Append(helpMenu, '&Help')
# minsize
self.SetMenuBar(menubar)
Expand All @@ -229,6 +233,8 @@ def CreateMenuBar(self):
self.Bind(wx.EVT_MENU, self.OnExit, exit_item)
self.Bind(wx.EVT_MENU, self.OnCut, cut_item)
self.Bind(wx.EVT_MENU, self.OnCopy, copy_item)
self.Bind(wx.EVT_MENU, self.OnOpenFolder, folder_item)
self.Bind(wx.EVT_MENU, self.OnConfig, settings_item)
self.Bind(wx.EVT_MENU, self.OnPaste, paste_item)
self.Bind(wx.EVT_MENU, self.OnRunPylint, pylint_item)
self.Bind(wx.EVT_MENU, self.OnFindReplace, find_replace_item)
Expand Down Expand Up @@ -261,6 +267,35 @@ def Homepage(self, event):
webbrowser.open("https://xedix.w3spaces.com")
self.SetStatusText(" Webpage opened", 2)

def OnConfig(self, event):
settings.main()

def OnOpenFolder(self, event):
# Create and show the directory dialog
dlg = wx.DirDialog(self, "Choose a directory:",
style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST)

if dlg.ShowModal() == wx.ID_OK:
# Get the selected path
path = dlg.GetPath()

# Change directory using os.system
os.system(f'cd "{path}"')

# Also change the Python script's working directory
os.chdir(path)

# Show confirmation message
self.SetStatusText(f" Changed directory to: {path}")

# Clear the current file list
self.file_list.Clear()

# Populate the file list with files from the new directory
self.PopulateFileList()

dlg.Destroy()

def RequirementsGeneration(self, event):
current_tab = self.notebook.GetCurrentPage()
if current_tab:
Expand All @@ -272,6 +307,91 @@ def RequirementsGeneration(self, event):
else:
self.SetStatusText("Error saving requirements")

# Add these methods to the TextEditor class

def OnFileListRightClick(self, event):
"""Handle right-click events on file list items."""
# Get the item that was clicked
index = self.file_list.HitTest(event.GetPosition())
if index != wx.NOT_FOUND:
self.file_list.SetSelection(index)

# Create and show the context menu
menu = wx.Menu()
rename_item = menu.Append(wx.ID_ANY, "Rename")
delete_item = menu.Append(wx.ID_ANY, "Delete")

# Bind menu events
self.Bind(wx.EVT_MENU, self.OnRenameFile, rename_item)
self.Bind(wx.EVT_MENU, self.OnDeleteFile, delete_item)

# Show the popup menu
self.PopupMenu(menu)
menu.Destroy()

def OnRenameFile(self, event):
"""Handle file rename operation."""
selected_index = self.file_list.GetSelection()
if selected_index != wx.NOT_FOUND:
old_name = self.file_list.GetString(selected_index)

# Show dialog to get new name
dialog = wx.TextEntryDialog(self, "Enter new filename:", "Rename File", old_name)
if dialog.ShowModal() == wx.ID_OK:
new_name = dialog.GetValue()

try:
# Rename the file
os.rename(old_name, new_name)

# Update the file list
self.file_list.SetString(selected_index, new_name)

# Update the notebook tab if the file is open
for i in range(self.notebook.GetPageCount()):
if self.notebook.GetPageText(i) == old_name:
self.notebook.SetPageText(i, new_name)

self.SetStatusText(f" Renamed {old_name} to {new_name}")
except OSError as e:
wx.MessageBox(f"Error renaming file: {str(e)}", "Error",
wx.OK | wx.ICON_ERROR)

dialog.Destroy()

def OnDeleteFile(self, event):
"""Handle file delete operation."""
selected_index = self.file_list.GetSelection()
if selected_index != wx.NOT_FOUND:
filename = self.file_list.GetString(selected_index)

# Show confirmation dialog
dialog = wx.MessageDialog(self,
f"Are you sure you want to delete '{filename}'?",
"Confirm Delete",
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)

if dialog.ShowModal() == wx.ID_YES:
try:
# Close the file if it's open in the editor
for i in range(self.notebook.GetPageCount()):
if self.notebook.GetPageText(i) == filename:
self.notebook.DeletePage(i)
break

# Delete the file
os.remove(filename)

# Remove from file list
self.file_list.Delete(selected_index)

self.SetStatusText(f" Deleted {filename}")
except OSError as e:
wx.MessageBox(f"Error deleting file: {str(e)}", "Error",
wx.OK | wx.ICON_ERROR)

dialog.Destroy()

def OnJumpToLine(self, event):
current_tab = self.notebook.GetCurrentPage()
if current_tab:
Expand Down Expand Up @@ -462,50 +582,6 @@ def PopulateFileList(self):
## add padding between 2 child items
list
# self.file_list.SetWindowStyleFlag(wx.NO_BORDER)



def OnChar(self, event):
self.SetStatusText(" Character pressed",2)
self.SetStatusText(" Showing recomendations")
current_tab = self.notebook.GetCurrentPage()
if current_tab:
text_area = current_tab.GetChildren()[0]
key_code = event.GetKeyCode()

# Auto-close brackets
if chr(key_code) in self.matching_brackets:
pos = text_area.GetCurrentPos()
text_area.InsertText(pos, self.matching_brackets[chr(key_code)])
text_area.SetCurrentPos(pos)
text_area.SetSelection(pos, pos)

key_code = event.GetKeyCode()
if chr(key_code).isalpha() or key_code == ord('.'):
pos = text_area.GetCurrentPos()
word_start_pos = text_area.WordStartPosition(pos, True)
length = pos - word_start_pos

# Show autocomplete after 3 characters or when a dot is typed
if length >= 0 or key_code == ord('.'):
# List of completions
completions_list = [
"abs", "all", "any", "bin", "bool", "bytearray", "bytes", "chr", "classmethod",
"compile", "complex", "delattr", "dict", "dir", "divmod", "enumerate", "eval",
"exec", "filter", "float", "format", "frozenset", "getattr", "globals",
"hasattr", "hash", "help", "hex", "id", "input", "int", "isinstance", "issubclass",
"iter", "len", "list", "locals", "map", "max", "memoryview", "min", "next",
"object", "oct", "open", "ord", "pow", "print", "property", "range", "repr",
"reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str",
"sum", "super", "tuple", "type", "vars", "zip", "__name__"
]

# Convert the list of completions into a space-separated string
completions = " ".join(completions_list)

text_area.AutoCompShow(0, completions) # Show the autocomplete list

event.Skip() # Continue processing other key events

def OnFileOpen(self, event):
file_name = self.file_list.GetStringSelection()
Expand Down Expand Up @@ -919,6 +995,50 @@ def OnSave(self, event):
with open(file_name, 'w') as file:
file.write(content)

def OnChar(self, event):
self.SetStatusText(" Character pressed",2)
self.SetStatusText(" Showing recomendations")
current_tab = self.notebook.GetCurrentPage()
if current_tab:
text_area = current_tab.GetChildren()[0]
key_code = event.GetKeyCode()

# Auto-close brackets
if chr(key_code) in self.matching_brackets:
pos = text_area.GetCurrentPos()
text_area.InsertText(pos, self.matching_brackets[chr(key_code)])
text_area.SetCurrentPos(pos)
text_area.SetSelection(pos, pos)

key_code = event.GetKeyCode()
if chr(key_code).isalpha() or key_code == ord('.'):
pos = text_area.GetCurrentPos()
word_start_pos = text_area.WordStartPosition(pos, True)
length = pos - word_start_pos

# Show autocomplete after 3 characters or when a dot is typed
if length >= 0 or key_code == ord('.'):
# List of completions
completions_list = [
"abs", "all", "any", "bin", "bool", "bytearray", "bytes", "chr", "classmethod",
"compile", "complex", "delattr", "dict", "dir", "divmod", "enumerate", "eval",
"exec", "filter", "float", "format", "frozenset", "getattr", "globals",
"hasattr", "hash", "help", "hex", "id", "input", "int", "isinstance", "issubclass",
"iter", "len", "list", "locals", "map", "max", "memoryview", "min", "next",
"object", "oct", "open", "ord", "pow", "print", "property", "range", "repr",
"reversed", "round", "set", "setattr", "slice", "sorted", "staticmethod", "str",
"sum", "super", "tuple", "type", "vars", "zip", "__name__"
]

# Convert the list of completions into a space-separated string
completions = " ".join(completions_list)

text_area.AutoCompShow(0, completions) # Show the autocomplete list
self.OnSave(wx.EVT_CHAR)
self.SetStatusText(" Autosaved", 2)

event.Skip() # Continue processing other key events

def OnExit(self, event):
self.SetStatusText(" Exiting XediX...")
time.sleep(1)
Expand All @@ -944,7 +1064,6 @@ def OnPaste(self, event):

extension_mainclass.main()


def main():
app = wx.App(False)
frame = TextEditor(None)
Expand Down
94 changes: 94 additions & 0 deletions src/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import wx

class SettingsApp(wx.Frame):
def __init__(self, *args, **kw):
super(SettingsApp, self).__init__(*args, **kw)

self.initUI()

def initUI(self):
panel = wx.Panel(self)

vbox = wx.BoxSizer(wx.VERTICAL)

# Theme setting
hbox1 = wx.BoxSizer(wx.HORIZONTAL)
st1 = wx.StaticText(panel, label='Theme Value:')
hbox1.Add(st1, flag=wx.RIGHT, border=8)
self.theme_text = wx.TextCtrl(panel)
hbox1.Add(self.theme_text, proportion=1)
vbox.Add(hbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)

# Header Active setting
hbox2 = wx.BoxSizer(wx.HORIZONTAL)
st2 = wx.StaticText(panel, label='Header Active Color:')
hbox2.Add(st2, flag=wx.RIGHT, border=8)
self.header_active_text = wx.TextCtrl(panel)
hbox2.Add(self.header_active_text, proportion=1)
vbox.Add(hbox2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)

# Header Inactive setting
hbox3 = wx.BoxSizer(wx.HORIZONTAL)
st3 = wx.StaticText(panel, label='Header Inactive Color:')
hbox3.Add(st3, flag=wx.RIGHT, border=8)
self.header_inactive_text = wx.TextCtrl(panel)
hbox3.Add(self.header_inactive_text, proportion=1)
vbox.Add(hbox3, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, border=10)

# Save button
hbox4 = wx.BoxSizer(wx.HORIZONTAL)
btn_save = wx.Button(panel, label='Save', size=(70, 30))
hbox4.Add(btn_save)
vbox.Add(hbox4, flag=wx.ALIGN_RIGHT|wx.RIGHT|wx.BOTTOM, border=10)

panel.SetSizer(vbox)

# Load initial values
self.load_settings()

# Bind the save button to the save function
btn_save.Bind(wx.EVT_BUTTON, self.on_save)

self.SetSize((400, 250))
self.SetTitle('Settings App')
self.Centre()

def load_settings(self):
try:
with open('theme.xcfg', 'r') as file:
theme_value = file.read().strip()
self.theme_text.SetValue(theme_value)
except FileNotFoundError:
self.theme_text.SetValue('')

try:
with open('xedix.xcfg', 'r') as file:
lines = file.readlines()
for line in lines:
if line.startswith('headerActive:'):
self.header_active_text.SetValue(line.split(':')[1].strip())
elif line.startswith('headerInactive:'):
self.header_inactive_text.SetValue(line.split(':')[1].strip())
except FileNotFoundError:
self.header_active_text.SetValue('')
self.header_inactive_text.SetValue('')

def on_save(self, event):
theme_value = self.theme_text.GetValue().strip()
header_active_color = self.header_active_text.GetValue().strip()
header_inactive_color = self.header_inactive_text.GetValue().strip()

with open('theme.xcfg', 'w') as file:
file.write(theme_value)

with open('xedix.xcfg', 'w') as file:
file.write(f'headerActive:{header_active_color};\n')
file.write(f'headerInactive:{header_inactive_color};\n')

wx.MessageBox('Settings saved successfully', 'Info', wx.OK | wx.ICON_INFORMATION)

def main():
app = wx.App()
frame = SettingsApp(None)
frame.Show()
app.MainLoop()
Loading