ktongue's picture
download
raw
11.3 kB
import sys
import requests
import json
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from canvas import DrawingCanvas
API_URL = "http://localhost:5000/api"
class RichTextEditor(QWidget):
def __init__(self):
super().__init__()
self.layout = QVBoxLayout(self)
# Barre d'outils de formatage
self.toolbar = QHBoxLayout()
# Police
self.font_combo = QFontComboBox()
self.font_combo.currentFontChanged.connect(self.change_font)
self.toolbar.addWidget(self.font_combo)
# Taille
self.size_spin = QSpinBox()
self.size_spin.setRange(8, 72)
self.size_spin.setValue(11)
self.size_spin.valueChanged.connect(self.change_size)
self.toolbar.addWidget(self.size_spin)
# Séparateur
line = QFrame()
line.setFrameShape(QFrame.Shape.VLine)
line.setFrameShadow(QFrame.Shadow.Sunken)
self.toolbar.addWidget(line)
# Boutons de style
self.bold_btn = QPushButton("B")
self.bold_btn.setCheckable(True)
self.bold_btn.clicked.connect(self.toggle_bold)
self.toolbar.addWidget(self.bold_btn)
self.italic_btn = QPushButton("I")
self.italic_btn.setCheckable(True)
self.italic_btn.clicked.connect(self.toggle_italic)
self.toolbar.addWidget(self.italic_btn)
self.underline_btn = QPushButton("U")
self.underline_btn.setCheckable(True)
self.underline_btn.clicked.connect(self.toggle_underline)
self.toolbar.addWidget(self.underline_btn)
self.toolbar.addStretch()
self.layout.addLayout(self.toolbar)
# Éditeur HTML
self.editor = QTextEdit()
self.editor.setAcceptRichText(True)
self.layout.addWidget(self.editor)
self.current_page_id = None
def change_font(self, font):
self.editor.setCurrentFont(font)
def change_size(self, size):
self.editor.setFontPointSize(size)
def toggle_bold(self):
self.editor.setFontWeight(
QFont.Weight.Bold if self.bold_btn.isChecked() else QFont.Weight.Normal
)
def toggle_italic(self):
self.editor.setFontItalic(self.italic_btn.isChecked())
def toggle_underline(self):
self.editor.setFontUnderline(self.underline_btn.isChecked())
def set_content(self, html_content):
self.editor.setHtml(html_content if html_content else "")
def get_content(self):
return self.editor.toHtml()
def clear(self):
self.editor.clear()
class OneNoteClone(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("OneNote Clone")
self.setGeometry(100, 100, 1400, 900)
# Widget central
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QHBoxLayout(self.central_widget)
# Panneau de navigation
self.nav_panel = QSplitter(Qt.Orientation.Horizontal)
self.notebook_list = QListWidget()
self.notebook_list.setMaximumWidth(200)
self.notebook_list.itemClicked.connect(self.load_sections)
self.nav_panel.addWidget(self.create_panel("📒 Notebooks", self.notebook_list, self.add_notebook))
self.section_list = QListWidget()
self.section_list.setMaximumWidth(200)
self.section_list.itemClicked.connect(self.load_pages)
self.nav_panel.addWidget(self.create_panel("📑 Sections", self.section_list, self.add_section))
self.page_list = QListWidget()
self.page_list.setMaximumWidth(250)
self.page_list.itemClicked.connect(self.load_page_content)
self.nav_panel.addWidget(self.create_panel("📄 Pages", self.page_list, self.add_page))
self.layout.addWidget(self.nav_panel, 1)
# Zone d'édition avec onglets
self.editor_container = QWidget()
self.editor_layout = QVBoxLayout(self.editor_container)
self.page_title = QLineEdit()
self.page_title.setPlaceholderText("Titre de la page")
self.page_title.setStyleSheet("font-size: 24px; border: none; padding: 10px; background: transparent;")
self.editor_layout.addWidget(self.page_title)
self.tabs = QTabWidget()
self.text_editor = RichTextEditor()
self.canvas = DrawingCanvas()
self.tabs.addTab(self.text_editor, "Texte")
self.tabs.addTab(self.canvas, "Dessin")
self.editor_layout.addWidget(self.tabs)
self.save_btn = QPushButton("💾 Sauvegarder")
self.save_btn.clicked.connect(self.save_page)
self.editor_layout.addWidget(self.save_btn)
self.layout.addWidget(self.editor_container, 3)
self.status_bar = QStatusBar()
self.setStatusBar(self.status_bar)
self.current_notebook_id = None
self.current_section_id = None
self.current_page_id = None
self.load_notebooks()
self.auto_save_timer = QTimer()
self.auto_save_timer.timeout.connect(self.auto_save)
self.auto_save_timer.start(30000)
def create_panel(self, title, list_widget, add_callback):
panel = QWidget()
layout = QVBoxLayout(panel)
header = QLabel(title)
header.setStyleSheet("font-weight: bold; font-size: 14px; padding: 5px;")
layout.addWidget(header)
layout.addWidget(list_widget)
add_btn = QPushButton("+ Ajouter")
add_btn.clicked.connect(add_callback)
layout.addWidget(add_btn)
return panel
def load_notebooks(self):
self.notebook_list.clear()
try:
response = requests.get(f"{API_URL}/notebooks")
for nb in response.json():
item = QListWidgetItem(nb['name'])
item.setData(Qt.ItemDataRole.UserRole, nb['id'])
item.setBackground(QColor(nb['color']))
self.notebook_list.addItem(item)
except Exception as e:
self.status_bar.showMessage(f"Erreur: {str(e)}")
def add_notebook(self):
name, ok = QInputDialog.getText(self, "Nouveau Notebook", "Nom:")
if ok and name:
color = QColorDialog.getColor()
try:
requests.post(f"{API_URL}/notebooks", json={
'name': name,
'color': color.name() if color.isValid() else '#7719AA'
})
self.load_notebooks()
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def load_sections(self, item):
self.current_notebook_id = item.data(Qt.ItemDataRole.UserRole)
self.section_list.clear()
self.page_list.clear()
self.current_page_id = None
try:
response = requests.get(f"{API_URL}/notebooks/{self.current_notebook_id}/sections")
for sec in response.json():
item = QListWidgetItem(sec['name'])
item.setData(Qt.ItemDataRole.UserRole, sec['id'])
self.section_list.addItem(item)
except Exception as e:
self.status_bar.showMessage(f"Erreur: {str(e)}")
def add_section(self):
if not self.current_notebook_id:
QMessageBox.warning(self, "Attention", "Sélectionnez d'abord un notebook")
return
name, ok = QInputDialog.getText(self, "Nouvelle Section", "Nom:")
if ok and name:
try:
requests.post(f"{API_URL}/notebooks/{self.current_notebook_id}/sections", json={'name': name})
self.load_sections(self.notebook_list.currentItem())
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def load_pages(self, item):
self.current_section_id = item.data(Qt.ItemDataRole.UserRole)
self.page_list.clear()
try:
response = requests.get(f"{API_URL}/sections/{self.current_section_id}/pages")
for page in response.json():
item = QListWidgetItem(f"{page['title']}\n{page['updated_at'][:10]}")
item.setData(Qt.ItemDataRole.UserRole, page['id'])
self.page_list.addItem(item)
except Exception as e:
self.status_bar.showMessage(f"Erreur: {str(e)}")
def add_page(self):
if not self.current_section_id:
QMessageBox.warning(self, "Attention", "Sélectionnez d'abord une section")
return
title, ok = QInputDialog.getText(self, "Nouvelle Page", "Titre:")
if ok:
try:
requests.post(f"{API_URL}/sections/{self.current_section_id}/pages", json={'title': title})
self.load_pages(self.section_list.currentItem())
except Exception as e:
QMessageBox.critical(self, "Erreur", str(e))
def load_page_content(self, item):
self.current_page_id = item.data(Qt.ItemDataRole.UserRole)
try:
response = requests.get(f"{API_URL}/pages/{self.current_page_id}")
page = response.json()
self.page_title.setText(page['title'])
self.text_editor.set_content(page['content'])
self.canvas.set_data(page.get('drawing_data', '[]'))
except Exception as e:
self.status_bar.showMessage(f"Erreur: {str(e)}")
def save_page(self):
if not self.current_page_id:
return
try:
requests.put(f"{API_URL}/pages/{self.current_page_id}", json={
'title': self.page_title.text(),
'content': self.text_editor.get_content(),
'drawing_data': self.canvas.get_data()
})
self.status_bar.showMessage("Sauvegardé!", 2000)
if self.section_list.currentItem():
self.load_pages(self.section_list.currentItem())
except Exception as e:
self.status_bar.showMessage(f"Erreur: {str(e)}")
def auto_save(self):
if self.current_page_id and self.page_title.text():
self.save_page()
def main():
app = QApplication(sys.argv)
app.setStyle('Fusion')
app.setStyleSheet("""
QMainWindow { background-color: #1e1e1e; }
QWidget { background-color: #2d2d2d; color: #ffffff; }
QListWidget { background-color: #252526; border: none; padding: 5px; }
QListWidget::item { padding: 8px; border-radius: 4px; }
QListWidget::item:selected { background-color: #094771; }
QPushButton { background-color: #0e639c; border: none; padding: 8px; border-radius: 4px; color: white; }
QPushButton:hover { background-color: #1177bb; }
QTextEdit { background-color: #1e1e1e; border: 1px solid #3c3c3c; }
QLineEdit { background-color: transparent; border-bottom: 1px solid #3c3c3c; color: white; }
""")
window = OneNoteClone()
window.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()

Xet Storage Details

Size:
11.3 kB
·
Xet hash:
f45122fc60268fdafe33209150db0926c902f00a64dcaeaf1a044732aada63aa

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.