Skip to content

Commit 021f6ca

Browse files
[Refact] Organizando e refatorando
1 parent a99705e commit 021f6ca

File tree

7 files changed

+1149
-989
lines changed

7 files changed

+1149
-989
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
from PySide6.QtWidgets import QMessageBox, QMenu, QInputDialog, QTextEdit, QWidget, QVBoxLayout
2+
from PySide6.QtCore import Qt
3+
from PySide6.QtGui import QAction
4+
from PySide6 import QtGui
5+
import markdown
6+
7+
class EditActionsMixin:
8+
9+
def init_ui(self):
10+
self.ui.statusBarMessage()
11+
self.ui.menu = self.create_menu()
12+
self.ui.splitter.setStyleSheet("QSplitter::handle {background-color:#dfe2e5; ...}")
13+
self.ui.editArea.setFocus()
14+
self.ui.previewArea.setZoomFactor(0.8)
15+
self.setGeometry(100, 100, 800, 600)
16+
self.setWindowTitle('DocViewer')
17+
self.ui.file_btn.clicked.connect(self.show_menu)
18+
self.ui.tab_widget.tabCloseRequested.connect(self.close_tab)
19+
self.ui.tab_widget.currentChanged.connect(self.onTabChange)
20+
self.ui.tab_widget.tabBar().setContextMenuPolicy(Qt.CustomContextMenu)
21+
self.ui.tab_widget.tabBar().customContextMenuRequested.connect(self.onTabRightClick)
22+
self.new_file()
23+
24+
def create_menu(self):
25+
menu = QMenu()
26+
new_file_act = QAction("Novo arquivo", self)
27+
new_file_act.setShortcut("Ctrl+N")
28+
new_file_act.triggered.connect(self.new_file)
29+
menu.addAction(new_file_act)
30+
31+
open_file_act = QAction("Abrir Arquivo", self)
32+
open_file_act.setShortcut("Ctrl+O")
33+
open_file_act.triggered.connect(self.showDialogAndOpenFile)
34+
menu.addAction(open_file_act)
35+
36+
save_file_act = QAction("Salvar Arquivo", self)
37+
save_file_act.setShortcut("Ctrl+S")
38+
save_file_act.triggered.connect(self.saveFile)
39+
menu.addAction(save_file_act)
40+
41+
menu.setFixedWidth(210)
42+
return menu
43+
44+
def show_menu(self):
45+
if not self.ui.has_open_menu:
46+
self.ui.menu.exec(self.ui.file_btn.mapToGlobal(self.ui.file_btn.rect().bottomLeft()))
47+
self.ui.has_open_menu = True
48+
else:
49+
self.ui.menu.close()
50+
self.ui.has_open_menu = False
51+
52+
def onTabRightClick(self, position):
53+
"""Exibe um diálogo para renomear arquivo ao clicar com o botão direito em cima da aba"""
54+
tab_index = self.ui.tab_widget.tabBar().tabAt(position)
55+
tab_widget = self.ui.tab_widget.widget(tab_index)
56+
if tab_index != -1:
57+
# Cria o menu de contexto
58+
menu = QMenu(self)
59+
60+
rename_action = QAction("Renomear arquivo", self)
61+
rename_action.triggered.connect(lambda: self.renameTab(tab_index, tab_widget))
62+
63+
open_action = QAction("Abrir aqui", self)
64+
open_action.triggered.connect(lambda: self.open_here(tab_index))
65+
66+
save_action = QAction("Salvar arquivo", self)
67+
save_action.triggered.connect(lambda: self.saveFile())
68+
69+
# Adiciona as ações ao menu
70+
menu.addAction(rename_action)
71+
menu.addAction(open_action)
72+
menu.addAction(save_action)
73+
#menu.addSeparator() # Adiciona um separador visual
74+
75+
76+
# Exibe o menu de contexto na posição do cursor
77+
menu.exec_(self.ui.tab_widget.tabBar().mapToGlobal(position))
78+
# ... incluir updatePreview, inteliComplete, updateCompleteHtml, getMarkdownText, scroll_to_bottom etc
79+
def eventFilter(self, obj, event):
80+
if obj == self.ui.editArea and event.type() == QtCore.QEvent.KeyRelease and event.key() == QtCore.Qt.Key_Return:
81+
self.inteliComplete()
82+
return super().eventFilter(obj, event)
83+
84+
def inteliComplete(self):
85+
cursor = self.ui.editArea.textCursor()
86+
cursor.movePosition(QtGui.QTextCursor.EndOfLine) # Move o cursor para o final da linha atual
87+
88+
actual_line = cursor.block().text().strip()
89+
previous_line = cursor.block().previous().text().strip() # Obtém o texto da linha anterior
90+
#next_line = cursor.block().next().text().strip()
91+
#print("actual line", actual_line)
92+
if previous_line.startswith("-"):
93+
if(len(previous_line) > 2 and previous_line[2] == '['):
94+
cursor.insertText("- [ ] ")
95+
else:
96+
if(actual_line.startswith("-")):
97+
cursor.movePosition(QtGui.QTextCursor.EndOfLine)
98+
else:
99+
cursor.insertText("- ")
100+
elif previous_line.startswith(">"):
101+
cursor.insertText("> ")
102+
elif previous_line.startswith("_"):
103+
cursor.insertText("_ ")
104+
elif previous_line.startswith("*"):
105+
cursor.insertText("* ")
106+
elif previous_line.startswith("1."):
107+
cursor.insertText("1. ")
108+
elif previous_line.startswith("- "):
109+
cursor.insertText("- [ ] ")
110+
111+
##cursor.movePosition(QtGui.QTextCursor.StartOfLine, QtGui.QTextCursor.MoveAnchor)
112+
self.ui.editArea.setTextCursor(cursor)
113+
114+
def getMarkdownText(self, input_text):
115+
mkd_text = markdown.markdown(input_text, extensions=['extra', 'tables','fenced_code', 'codehilite'])
116+
mkd_text = mkd_text.replace('[ ]', '<input type="checkbox" disabled>') # Necessário!
117+
mkd_text = mkd_text.replace('[x]', '<input type="checkbox" disabled checked>') # Necessário!
118+
return mkd_text
119+
120+
def updatePreview(self, text_edit):
121+
"""Atualiza a visualização com base no conteúdo do QTextEdit fornecido"""
122+
markdown_text = text_edit.toPlainText()
123+
self.verifyChangesAndSetTabName()
124+
125+
self.html_text_ = self.getMarkdownText(markdown_text)
126+
self.updateCompleteHtml()
127+
self.ui.previewArea.setHtml(self.complete_html)
128+
### TODO: Permitir ativar e desativar esta funcionalidade
129+
##self.ui.previewArea.loadFinished.connect(self.scroll_to_bottom)
130+
131+
def updateCompleteHtml(self):
132+
"""Atualiza e redefine o conteúdo de complete_html"""
133+
self.complete_html = f"""
134+
<!DOCTYPE html>
135+
<html>
136+
<head>
137+
<meta charset="utf-8">
138+
<style>
139+
body {{
140+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
141+
line-height: 1.6;
142+
padding: 20px;
143+
color: #E6edf3;
144+
background-color: #161b22;
145+
}}
146+
h1, h2, h3, h4, h5, h6 {{
147+
border-bottom: 1px solid #eaecef;
148+
padding-bottom: 0.3em;
149+
}}
150+
h1 {{ font-size: 2em; }}
151+
h2 {{ font-size: 1.5em; }}
152+
h3 {{ font-size: 1.25em; }}
153+
blockquote {{
154+
color: #848d97;
155+
border-left: 0.25em solid #30363d;
156+
padding: 0.5em 1em;
157+
}}
158+
ol {{
159+
padding-left: 20px; /* Recuo inicial da lista */
160+
list-style-type: decimal; /* Números padrão para a lista */
161+
font-family: Arial, sans-serif; /* Fonte padrão */
162+
line-height: 1.6; /* Altura da linha para melhor legibilidade */
163+
}}
164+
ol ol {{
165+
padding-left: 20px; /* Recuo adicional para listas aninhadas */
166+
list-style-type: lower-alpha; /* Letras minúsculas para segundo nível */
167+
168+
}}
169+
170+
ol ol ol {{
171+
padding-left: 20px; /* Recuo adicional para listas de terceiro nível */
172+
list-style-type: lower-roman; /* Números romanos minúsculos para terceiro nível */
173+
174+
}}
175+
code {{
176+
font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, "Liberation Mono", monospace;
177+
padding: .2em .4em;
178+
margin: 0;
179+
font-size: 85%;
180+
white-space: break-spaces;
181+
background-color: #afb8c133;
182+
border-radius: 6px;
183+
}}
184+
pre code {{
185+
background-color: #30363d;
186+
padding: 0;
187+
font-size: 100%;
188+
}}
189+
pre {{
190+
overflow: auto;
191+
overflow-x: auto;
192+
overflow-y: auto;
193+
background-color: #30363d;
194+
padding: 1em;
195+
overflow: auto;
196+
}}
197+
.codehilite .k {{ color: #f92672; }} /* Palavras-chave em rosa */
198+
.codehilite .c {{ color: #75715e; font-style: italic; }} /* Comentários em cinza */
199+
.codehilite .n {{ color: #a6e22e; }} /* Nomes de variáveis em verde */
200+
.codehilite .s {{ color: #e6db74; }}
201+
/* Palavras-chave (e.g., public, final, class) */
202+
.codehilite .kd {{ color: #f92672; font-weight: bold; }} /* Palavras-chave em rosa */
203+
204+
/* Nome de classes (e.g., SaberToothedCat) */
205+
.codehilite .nc {{ color: #a6e22e; font-weight: bold; }} /* Nome de classes em verde claro */
206+
207+
/* Nomes de variáveis ou tipos (e.g., Animal, System) */
208+
.codehilite .n {{ color: #66d9ef; }} /* Nomes de variáveis em azul claro */
209+
210+
/* Anotações (e.g., @Override) */
211+
.codehilite .nd {{ color: #ae81ff; font-style: italic; }} /* Anotações em roxo claro */
212+
213+
/* Tipos de retorno (e.g., void) */
214+
.codehilite .kt {{ color: #fd971f; }} /* Tipos de retorno em laranja */
215+
216+
/* Nomes de métodos ou funções (e.g., makeSound) */
217+
.codehilite .nf {{ color: #a6e22e; font-weight: bold; }} /* Nomes de métodos em verde claro */
218+
219+
/* Comentários */
220+
.codehilite .c1 {{ color: #75715e; font-style: italic; }} /* Comentários em cinza */
221+
222+
/* Atributos ou membros (e.g., out, println) */
223+
.codehilite .na {{ color: #f8f8f2; }} /* Atributos em branco */
224+
225+
.codehilite .p {{ color: #f8f8f2; }} /* Pontuação em branco */
226+
227+
/* Strings */
228+
.codehilite .s {{ color: #e6db74; }} /* Strings em amarelo */
229+
230+
/* Espaçamento (não precisa de estilização, mas está incluído para clareza) */
231+
.codehilite .w {{ color: inherit; }}
232+
table {{
233+
border-collapse: collapse;
234+
border-spacing: 0;
235+
max-width: 100%;
236+
display: block;
237+
overflow: auto;
238+
}}
239+
table th, table td {{
240+
border: 1px solid #dfe2e5;
241+
padding: 6px 13px;
242+
}}
243+
table tr {{
244+
background-color: #161b22;
245+
border-top: 1px solid #c6cbd1;
246+
}}
247+
table tr:nth-child(2n) {{
248+
background-color: #30363d;
249+
}}
250+
input[type="checkbox"] {{
251+
width: 1em;
252+
height: 1em;
253+
margin-right: 0.5em;
254+
vertical-align: middle;
255+
position: relative;
256+
top: -0.1em;
257+
}}
258+
259+
</style>
260+
</head>
261+
<body>
262+
{self.html_text_}
263+
</body>
264+
</html>
265+
"""
266+
267+
def verifyChangesAndSetTabName(self):
268+
current_index = self.ui.tab_widget.currentIndex()
269+
current_tab = self.ui.tab_widget.widget(current_index)
270+
if current_tab in self.ui.open_files:
271+
# Atualiza o estado de isModified para True
272+
file_path = self.ui.open_files[current_tab][0]
273+
isModified = self.ui.open_files[current_tab][1]
274+
if not file_path.endswith('*') and not isModified:
275+
file_name = file_path.split('/')[-1] # Pega o último componente do caminho
276+
self.ui.tab_widget.setTabText(current_index, f"{file_name}*")
277+
self.ui.open_files[current_tab][1] = True

0 commit comments

Comments
 (0)