Skip to content

Commit a99705e

Browse files
[Refact] inicio da organização do projeto
1 parent 7274d8b commit a99705e

39 files changed

+2183
-32
lines changed

MarkViewDesktop/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Development ignored file
2+
*.md

MarkViewDesktop/___init__.py

Whitespace-only changes.

MarkViewDesktop/config/___init__.py

Whitespace-only changes.

MarkViewDesktop/config/settings.ini

Whitespace-only changes.

MarkViewDesktop/editor/___init__.py

Whitespace-only changes.

MarkViewDesktop/editor/actions/___init__.py

Whitespace-only changes.

MarkViewDesktop/editor/actions/edit_actions.py

Whitespace-only changes.
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
"""Módulo para ações relacionadas a arquivos no editor"""
2+
class FileActions:
3+
def __init__(self, ui):
4+
self.ui = ui
5+
self.ui.new_file_count = 0 # Contador para novos arquivos
6+
7+
def new_file(self):
8+
"""Cria uma nova aba de arquivo com um nome único"""
9+
file_name = generate_new_file_name(self.ui.tab_widget)
10+
new_tab = self.ui.create_new_tab(file_name)
11+
self.ui.tab_widget.addTab(new_tab, file_name)
12+
self.ui.tab_widget.setCurrentWidget(new_tab)
13+
14+
def generate_new_file_name(self):
15+
"""Gera um nome de arquivo novo único com base no número de arquivos novos"""
16+
self.ui.new_file_count += 1
17+
base_name = "Novo Arquivo"
18+
file_name = f"{base_name} ({self.ui.new_file_count})"
19+
20+
# Garante que o nome é único entre as abas
21+
existing_tabs = [self.ui.tab_widget.tabText(i) for i in range(self.ui.tab_widget.count())]
22+
while file_name in existing_tabs:
23+
self.ui.new_file_count += 1
24+
file_name = f"{base_name} ({self.ui.new_file_count})"
25+
26+
return file_name
27+
28+
def check_unsaved_changes(self, tab_index):
29+
"""Verifica se a aba atual tem alterações não salvas e oferece para salvar"""
30+
widget = self.ui.tab_widget.widget(tab_index)
31+
if not widget:
32+
return False
33+
34+
text_edit = widget.findChild(QTextEdit)
35+
36+
if text_edit and text_edit.document().isModified():
37+
# Pergunta ao usuário se ele quer salvar as alterações
38+
reply = QMessageBox.question(self, "Arquivo Modificado",
39+
"O arquivo foi modificado. Deseja salvar as alterações?",
40+
QMessageBox.Yes | QMessageBox.No |QMessageBox.Cancel)
41+
42+
if reply == QMessageBox.Yes:
43+
return self.save_file(tab_index)
44+
elif reply == QMessageBox.Cancel:
45+
return True # Cancela a ação
46+
return False
47+
48+
def saveFileDialog(self):
49+
# Define o filtro para apenas arquivos .md
50+
filter = "Markdown Files (*.md);;All Files (*)"
51+
fname, _ = QFileDialog.getSaveFileName(self, 'Save file', '', filter)
52+
current_index = self.ui.tab_widget.currentIndex()
53+
current_tab = self.ui.tab_widget.widget(current_index)
54+
if fname:
55+
# Adiciona a extensão .md se não estiver presente
56+
if not fname.endswith('.md'):
57+
fname += '.md'
58+
with open(fname, 'w', encoding='utf-8') as file:
59+
file.write(self.ui.editArea.toPlainText())
60+
# Atualiza o nome da aba atual para o nome do arquivo salvo
61+
self.ui.open_files[current_tab][1] = False
62+
self.ui.open_files[current_tab][2] = False
63+
file_name = fname.split('/')[-1] # Extrai o nome do arquivo do caminho
64+
self.ui.tab_widget.setTabText(current_index, file_name)
65+
self.ui.tab_widget.setTabToolTip(current_index, fname)
66+
67+
def saveFile(self):
68+
"""Salva as mudanças no arquivo atual"""
69+
# Obtém a aba atual e o caminho do arquivo associado a ela
70+
current_index = self.ui.tab_widget.currentIndex()
71+
current_tab = self.ui.tab_widget.widget(current_index)
72+
73+
file_info = self.ui.open_files[current_tab]
74+
file_path = file_info[0]
75+
isNewFile = file_info[2]
76+
77+
if not isNewFile:
78+
79+
if file_path:
80+
# Sobrescreve o arquivo atual com o conteúdo do QTextEdit
81+
text_edit = current_tab.layout().itemAt(0).widget()
82+
if isinstance(text_edit, QTextEdit):
83+
with open(file_path, 'w', encoding='utf-8') as file:
84+
file.write(text_edit.toPlainText())
85+
self.ui.open_files[current_tab][1] = False
86+
87+
# Remove o '*' do nome da aba
88+
clean_file_name = os.path.basename(file_path) # Apenas o nome do arquivo sem o caminho
89+
self.ui.tab_widget.setTabText(current_index, clean_file_name)
90+
#print(f"Arquivo {file_path} salvo com sucesso.")
91+
else:
92+
# Caso não haja um caminho, abre um diálogo para salvar como um novo arquivo
93+
self.saveFileDialog()
94+
#============== Abertura de um arquivo/Novo Arquivo
95+
def open_here(self, tab_index):
96+
"""Abre um arquivo na aba selecionada, substituindo o conteúdo atual"""
97+
# Abre um diálogo para selecionar o arquivo
98+
options = QFileDialog.Options()
99+
file_path, _ = QFileDialog.getOpenFileName(self, "Abrir Arquivo", "", "Todos os Arquivos (*);;Arquivos de Texto (*.txt);;Markdown Files (*.md)", options=options)
100+
101+
if file_path:
102+
try:
103+
# Carrega o conteúdo do arquivo selecionado
104+
with open(file_path, 'r', encoding='utf-8') as file:
105+
content = file.read()
106+
107+
# Obtém o widget da aba selecionada
108+
current_tab = self.ui.tab_widget.widget(tab_index)
109+
if current_tab:
110+
# Procura pelo QTextEdit dentro do layout da aba
111+
layout = current_tab.layout()
112+
if layout is not None and layout.count() > 0:
113+
# Assume que o QTextEdit é o primeiro widget no layout
114+
text_edit = layout.itemAt(0).widget()
115+
if isinstance(text_edit, QTextEdit):
116+
# Substitui o conteúdo do QTextEdit pelo conteúdo do arquivo
117+
text_edit.setPlainText(content)
118+
119+
# Atualiza o nome da aba com o nome do arquivo aberto
120+
file_name = os.path.basename(file_path)
121+
self.ui.tab_widget.setTabText(tab_index, file_name)
122+
self.ui.tab_widget.setTabToolTip(tab_index, file_path)
123+
124+
# Atualiza o dicionário de arquivos abertos
125+
self.ui.open_files[current_tab] = [file_name, False, False]
126+
127+
print(f"Arquivo {file_name} aberto na aba {tab_index} com sucesso.")
128+
except Exception as e:
129+
print(f"Erro ao abrir o arquivo: {e}")
130+
131+
def showDialogAndOpenFile(self):
132+
options = QFileDialog.Options()
133+
options |= QFileDialog.ReadOnly # Abre o arquivo em modo somente leitura
134+
filter = "Markdown Files (*.md);;All Files (*)"
135+
file_path, _ = QFileDialog.getOpenFileName(self, "Abrir Arquivo", "",filter,options=options)
136+
137+
file_name = ""
138+
if file_path:
139+
file_name = os.path.basename(file_path)
140+
# Carregar o conteúdo do arquivo ou realizar alguma ação com ele
141+
with open(file_path, 'r',encoding='utf-8') as file:
142+
# content = file.read()
143+
# self.ui.previewArea.setPlainText(content)
144+
self.open_file(file, file_name, file_path)
145+
146+
def open_file(self, file_, file_name, file_path=None):
147+
"""Cria uma nova aba com um QTextEdit para abrir arquivo selecionado"""
148+
new_tab = QWidget()
149+
layout = QVBoxLayout()
150+
151+
# Criando uma área de texto
152+
text_edit = QTextEdit() # TextEditWithLineNumbers()
153+
text_edit.setStyleSheet("background-color: #DCDCDC; color:black")
154+
text_edit.setTabStopDistance(32)
155+
layout.addWidget(text_edit)
156+
layout.setContentsMargins(4, 4, 4, 4)
157+
new_tab.setLayout(layout)
158+
text_edit.textChanged.connect(lambda: self.updatePreview(text_edit))
159+
text_edit.setPlainText(file_.read())
160+
161+
# Adiciona uma nova aba com o editor de texto e o nome do arquivo como título da aba
162+
tab_index = self.ui.tab_widget.addTab(new_tab, file_name)
163+
self.ui.tab_widget.setCurrentIndex(tab_index)
164+
if(file_path):
165+
self.ui.tab_widget.setTabToolTip(tab_index,file_path)
166+
text_edit.setFocus()
167+
168+
# Armazena o caminho do arquivo no widget da aba como chave
169+
self.ui.open_files[new_tab] = [file_.name, False, False]
170+
self.checkIfAnyItemHidden()
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
2+
class EditorCore:
3+
def __init__(self, ui):
4+
self.ui = ui
5+
self._init_editor()
6+
7+
def verifyChangesAndSetTabName(self):
8+
current_index = self.ui.tab_widget.currentIndex()
9+
current_tab = self.ui.tab_widget.widget(current_index)
10+
if current_tab in self.ui.open_files:
11+
# Atualiza o estado de isModified para True
12+
file_name = self.ui.open_files[current_tab][0]
13+
isModified = self.ui.open_files[current_tab][1]
14+
if not file_name.endswith('*') and not isModified:
15+
self.ui.tab_widget.setTabText(current_index, f"{os.path.basename(file_name)}*")
16+
self.ui.open_files[current_tab][1] = True
17+
18+
def getCurrentTextEdit(self, current_index):
19+
"""Recupera o QTextEdit da aba atualmente selecionada"""
20+
# Obtém o índice da aba atualmente selecionada
21+
#current_index = self.ui.tab_widget.currentIndex()
22+
23+
if current_index == -1:
24+
# Nenhuma aba selecionada
25+
return None
26+
27+
# Obtém o widget da aba selecionada
28+
current_tab = self.ui.tab_widget.widget(current_index)
29+
30+
if current_tab is not None:
31+
# Procura pelo QTextEdit dentro do layout da aba
32+
layout = current_tab.layout()
33+
if layout is not None and layout.count() > 0:
34+
# Assume que o QTextEdit é o primeiro widget no layout
35+
text_edit = layout.itemAt(0).widget()
36+
if isinstance(text_edit, QTextEdit):
37+
return text_edit
38+
39+
return None
40+
41+
def onTabChange(self, index):
42+
self.ui.editArea = self.getCurrentTextEdit(index)
43+
if(self.ui.editArea is not None):
44+
self.updateAfterTabChange(self.ui.editArea)
45+
self.ui.editArea.installEventFilter(self)
46+
#print(f"Aba mudada: {index}")
47+
48+
def onTabRightClick(self, position):
49+
"""Exibe um diálogo para renomear arquivo ao clicar com o botão direito em cima da aba"""
50+
tab_index = self.ui.tab_widget.tabBar().tabAt(position)
51+
tab_widget = self.ui.tab_widget.widget(tab_index)
52+
if tab_index != -1:
53+
# Cria o menu de contexto
54+
menu = QMenu(self)
55+
56+
rename_action = QAction("Renomear arquivo", self)
57+
rename_action.triggered.connect(lambda: self.renameTab(tab_index, tab_widget))
58+
59+
open_action = QAction("Abrir aqui", self)
60+
open_action.triggered.connect(lambda: self.open_here(tab_index))
61+
62+
save_action = QAction("Salvar arquivo", self)
63+
save_action.triggered.connect(lambda: self.saveFile())
64+
65+
# Adiciona as ações ao menu
66+
menu.addAction(rename_action)
67+
menu.addAction(open_action)
68+
menu.addAction(save_action)
69+
#menu.addSeparator() # Adiciona um separador visual
70+
71+
72+
# Exibe o menu de contexto na posição do cursor
73+
menu.exec_(self.ui.tab_widget.tabBar().mapToGlobal(position))
74+
75+
def renameTab(self, tab_index, tab_widget):
76+
"""Renomeia a aba especificada e o arquivo associado"""
77+
# Obtém o nome atual da aba e o caminho completo do arquivo
78+
current_name = self.ui.tab_widget.tabText(tab_index)
79+
file_path = self.ui.open_files[tab_widget][0] # Caminho atual do arquivo
80+
current_dir = os.path.dirname(file_path) # Diretório atual do arquivo
81+
82+
# Solicita um novo nome para o arquivo
83+
new_name, ok = QInputDialog.getText(self, "Renomear arquivo",
84+
"Novo nome para o arquivo:",
85+
text=os.path.basename(current_name))
86+
if ok and new_name.strip():
87+
# Gera o novo caminho completo do arquivo
88+
new_file_path = os.path.join(current_dir, new_name.strip())
89+
90+
try:
91+
# Renomeia o arquivo no sistema de arquivos
92+
os.rename(file_path, new_file_path)
93+
94+
# Atualiza o nome da aba
95+
self.ui.tab_widget.setTabText(tab_index, new_name.strip())
96+
97+
# Atualiza o nome no dicionário de arquivos abertos
98+
self.ui.open_files[tab_widget][0] = new_file_path
99+
100+
print(f"Arquivo renomeado com sucesso para: {new_file_path}")
101+
except Exception as e:
102+
print(f"Erro ao renomear o arquivo: {e}")
103+
104+
def getCurrentFileModifiedStatus(self, current_index):
105+
"""Recupera apenas o status de modificação da aba atualmente selecionada"""
106+
if current_index == -1:
107+
# Nenhuma aba selecionada
108+
return None
109+
110+
# Obtém o widget da aba selecionada
111+
current_tab = self.ui.tab_widget.widget(current_index)
112+
113+
if current_tab is not None:
114+
# Verifica se a aba atual está no dicionário de arquivos abertos
115+
if current_tab in self.ui.open_files:
116+
file_info = self.ui.open_files[current_tab]
117+
is_modified = file_info[1] # Status de modificação
118+
return is_modified
119+
120+
return None
121+
122+
def checkIfAnyItemHidden(self):
123+
"""Verifica se algum item no QSplitter tem altura 0 (não está visível) e ajusta sua altura"""
124+
sizes = self.ui.splitter.sizes() # Obtém as alturas dos widgets no QSplitter
125+
updated = False
126+
# Define as alturas específicas para os itens
127+
if len(sizes) >= 2:
128+
sizes[0] = 186 # Define a altura do primeiro widget para 186
129+
sizes[1] = 288 # Define a altura do segundo widget para 288
130+
131+
# Atualiza os tamanhos no QSplitter
132+
self.ui.splitter.setSizes(sizes)
133+
#print("Alturas ajustadas: Item 0 = 186, Item 1 = 288")
134+
else:
135+
#print("O QSplitter não possui widgets suficientes para ajustar as alturas.")
136+
updated = True
137+
138+
if updated:
139+
# Atualiza os tamanhos no QSplitter com os novos valores
140+
self.ui.splitter.setSizes(sizes)
141+
#print("Altura ajustada para itens escondidos.")
142+
143+
def close_tab(self, index):
144+
"""Fecha a aba na posição fornecida, verificando se há alterações não salvas"""
145+
widget = self.ui.tab_widget.widget(index)
146+
147+
if self.check_unsaved_changes(index):
148+
return # Se o usuário cancelar, não fecha a aba
149+
150+
# Remove a aba
151+
self.ui.tab_widget.removeTab(index)
152+
153+
# Remove o widget da lista de arquivos abertos
154+
if widget in self.ui.open_files:
155+
del self.ui.open_files[widget]
156+

MarkViewDesktop/editor/utils/___init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)