From be6aac620f2db5857632864a76936bfe48cd4a44 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Wed, 11 Oct 2023 20:20:34 -0500 Subject: [PATCH 01/14] Update BuildUI.py --- Modules/BuildUI.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index 6b105a4..fec2cff 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -16,7 +16,7 @@ def build_ui(editor): #editor.statusBar = editor.statusBar() build_window(editor) build_menubar(editor) - #build_toolbar(editor) + build_toolbar(editor) # Application's main layout (grid) gridLayout = QGridLayout() @@ -67,11 +67,11 @@ def build_menubar(editor): file = editor.menuBar().addMenu('&File') plugins = editor.menuBar().addMenu('&Plugins') - new_file = build_action(editor, 'assets/icons/svg_file_open', 'New Notebook...', 'New Notebook', False) + new_file = build_action(editor, 'assets/icons/svg_file_open', 'New Notebook', 'New Notebook', False) new_file.setShortcut(QKeySequence.StandardKey.New) new_file.triggered.connect(lambda: new(editor)) - open_file = build_action(editor, 'assets/icons/svg_file_open', 'Open Notebook...', 'Open Notebook', False) + open_file = build_action(editor, 'assets/icons/svg_file_open', 'Open Notebook', 'Open Notebook', False) open_file.setShortcut(QKeySequence.StandardKey.Open) open_file.triggered.connect(lambda: load(editor)) From 54c595e311d1e344d19eb9173bc30e00515cabe7 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Mon, 16 Oct 2023 21:35:53 -0500 Subject: [PATCH 02/14] Bug Fix Moving mouse away from draggable container no longer exits typing --- Models/DraggableContainer.py | 29 +++++++++++++------------- Modules/BuildUI.py | 30 +++++++++++++++++++++------ Views/EditorFrameView.py | 40 +++++++++++++++++++++--------------- Widgets/Textbox.py | 8 ++++---- 4 files changed, 66 insertions(+), 41 deletions(-) diff --git a/Models/DraggableContainer.py b/Models/DraggableContainer.py index 57b248d..978fa84 100644 --- a/Models/DraggableContainer.py +++ b/Models/DraggableContainer.py @@ -64,10 +64,10 @@ def setChildWidget(self, childWidget): self.vLayout.addWidget(childWidget) self.vLayout.setContentsMargins(0,0,0,0) - def eventFilter(self, obj, event): + def eventFilter(self, obj, e): # If child widget resized itsself, resize this drag container, not ideal bc child resizes on hover - if isinstance(event, QResizeEvent): + if isinstance(e, QResizeEvent): self.resize(self.childWidget.size()) return False @@ -80,7 +80,7 @@ def popupShow(self, pt: QPoint): def mousePressEvent(self, e: QMouseEvent): self.position = QPoint(e.globalX() - self.geometry().x(), e.globalY() - self.geometry().y()) - print("DC MOUSE PRESS") + print("Draggable Container MOUSE PRESS") # Undo related # self.old_x = e.globalX() @@ -93,7 +93,7 @@ def mousePressEvent(self, e: QMouseEvent): print("NOT EDIT") return if not e.buttons() and Qt.LeftButton: - print("DC GOT MOUSE PRESS") + print("Draggable Container GOT MOUSE PRESS") self.setCursorShape(e.pos()) return True if e.button() == Qt.RightButton: @@ -117,14 +117,15 @@ def leaveEvent(self, e: QMouseEvent): self.childWidget.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.setStyleSheet("border: none;") - # Delete this DC if childWidget says it's empty - if hasattr(self.childWidget, "checkEmpty"): - if self.childWidget.checkEmpty(): - editorSignalsInstance.widgetRemoved.emit(self) - - # ??? - if self.childWidget.hasFocus(): - self.setFocus() + # Delete this Draggable Container if childWidget says it's empty + if not self.childWidget.hasFocus(): + if hasattr(self.childWidget, "checkEmpty"): + if self.childWidget.checkEmpty(): + editorSignalsInstance.widgetRemoved.emit(self) + + # If mouse leaves draggable container, set focus to the editor + #if self.childWidget.hasFocus(): + # self.setFocus()''' def buildDragContainerMenu(self): @@ -217,7 +218,7 @@ def setCursorShape(self, e_pos: QPoint): self.setCursor(QCursor(Qt.SizeVerCursor)) self.mode = Mode.RESIZEB else: - self.setCursor(QCursor(Qt. ArrowCursor)) + self.setCursor(QCursor(Qt.ArrowCursor)) self.mode = Mode.MOVE # Determine how to handle the mouse being moved inside the box @@ -281,7 +282,7 @@ def mouseMoveEvent(self, e: QMouseEvent): self.parentWidget().repaint() self.newGeometry.emit(self.geometry()) - # Pass the event to the child widget if this container is focuesd, and childwidget implements the method to receive it + # Pass the e to the child widget if this container is focuesd, and childwidget implements the method to receive it def widgetAttributeChanged(self, changedWidgetAttribute, value): cw = self.childWidget diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index fec2cff..8919244 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -85,9 +85,23 @@ def build_menubar(editor): file.addActions([new_file, open_file, save_file, save_fileAs]) +''' +def build_toolbar(editor): + toolbar = QToolBar("Main toolbar") + editor.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar) + + button_action = QAction("Your button", editor) + button_action.setStatusTip("This is your button") + button_action.triggered.connect(action.onMyToolBarButtonClick) + button_action.setCheckable(True) + toolbar.addAction(button_action) +''' + + + def build_toolbar(editor): toolbar = QToolBar() - toolbar.setIconSize(QSize(15, 15)) + toolbar.setIconSize(QSize(16, 16)) toolbar.setMovable(False) editor.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar) @@ -98,25 +112,28 @@ def build_toolbar(editor): size.addItems([str(fs) for fs in FONT_SIZES]) size.currentIndexChanged.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontSize, int(size.currentText()))) - fontColor = build_action(toolbar, 'assets/icons/svg_font_color', "Font Color", "Font Color", False) - fontColor.triggered.connect(lambda x: openGetColorDialog(purpose = "font")) - bgColor = build_action(toolbar, 'assets/icons/svg_font_bucket', "Text Box Color", "Text Box Color", False) bgColor.triggered.connect(lambda x: openGetColorDialog(purpose = "background")) + + fontColor = build_action(toolbar, 'assets/icons/svg_font_color', "Font Color", "Font Color", False) + fontColor.triggered.connect(lambda x: openGetColorDialog(purpose = "font")) bold = build_action(toolbar, 'assets/icons/bold', "Bold", "Bold", True) bold.triggered.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) + italic = build_action(toolbar, 'assets/icons/italic.svg', "Italic", "Italic", True) italic.triggered.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontItalic, None)) underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) - underline.triggered.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontUnderline, None)) - + #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) + toolbar.addWidget(font) toolbar.addWidget(size) + toolbar.addActions([bgColor, fontColor, bold, italic, underline]) + def openGetColorDialog(purpose): color = QColorDialog.getColor() if color.isValid(): @@ -128,4 +145,5 @@ def openGetColorDialog(purpose): def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): action = QAction(QIcon(icon_path), action_name, parent) action.setStatusTip(set_status_tip) + action.setCheckable(set_checkable) return action diff --git a/Views/EditorFrameView.py b/Views/EditorFrameView.py index 5232ead..38b5f63 100644 --- a/Views/EditorFrameView.py +++ b/Views/EditorFrameView.py @@ -18,6 +18,7 @@ # Handles all widget display (could be called widget view, but so could draggablecontainer) class EditorFrameView(QWidget): + def __init__(self, editor): super(EditorFrameView, self).__init__() @@ -151,37 +152,43 @@ def mouseReleaseEvent(self, event): else: self.newWidgetOnSection(TextboxWidget, event.pos()) - def mousePressEvent(self, event): + def mousePressEvent(self, e): print("EDITORFRAME MOUSEPRESS") editor = self.editor # Open context menu on right click - if event.buttons() == Qt.RightButton: + if e.buttons() == Qt.RightButton: frame_menu = QMenu(self) + cut_action = QAction("Cut", self) + #add cut functionality + frame_menu.addAction(cut_action) + + paste = QAction("Paste", editor) + paste.triggered.connect(lambda: self.pasteWidget(e.pos())) + frame_menu.addAction(paste) + add_image = QAction("Add Image", self) - add_image.triggered.connect(lambda: self.newWidgetOnSection(ImageWidget, event.pos())) + add_image.triggered.connect(lambda: self.newWidgetOnSection(ImageWidget, e.pos())) frame_menu.addAction(add_image) add_table = QAction("Add Table", editor) - add_table.triggered.connect(lambda: self.newWidgetOnSection(TableWidget, event.pos())) + add_table.triggered.connect(lambda: self.newWidgetOnSection(TableWidget, e.pos())) frame_menu.addAction(add_table) - paste = QAction("Paste", editor) - paste.triggered.connect(lambda: self.pasteWidget(event.pos())) - frame_menu.addAction(paste) + take_screensnip = QAction("Snip Screen", editor) - take_screensnip.triggered.connect(lambda: self.snipScreen(event.pos())) + take_screensnip.triggered.connect(lambda: self.snipScreen(e.pos())) frame_menu.addAction(take_screensnip) add_custom_widget = QAction("Add Custom Widget", editor) - add_custom_widget.triggered.connect(lambda: self.addCustomWidget(event)) + add_custom_widget.triggered.connect(lambda: self.addCustomWidget(e)) frame_menu.addAction(add_custom_widget) - frame_menu.exec(event.globalPos()) + frame_menu.exec(e.globalPos()) - def addCustomWidget(self, event): + def addCustomWidget(self, e): def getCustomWidgets(): customWidgets = {} # dict where entries are {name: class} @@ -206,17 +213,16 @@ def getCustomWidgets(): item_action = QAction(customWidget[0], self) def tmp(c, pos): return lambda: self.newWidgetOnSection(c, pos) - item_action.triggered.connect(tmp(customWidget[1], event.pos())) + item_action.triggered.connect(tmp(customWidget[1], e.pos())) pluginMenu.addAction(item_action) - pluginMenu.exec(event.globalPos()) - - def mouseMoveEvent(self, event): # This event is only called after clicking down on the frame and dragging + pluginMenu.exec(e.globalPos()) + def mouseMoveEvent(self, e): # This event is only called after clicking down on the frame and dragging # Set up multi-select on first move of mouse drag if self.multiselector.mode != MultiselectMode.IS_DRAWING_AREA: - self.multiselector.beginDrawingArea(event) + self.multiselector.beginDrawingArea(e) # Resize multi-select widget on mouse every proceeding mouse movement (dragging) else: - self.multiselector.continueDrawingArea(event) + self.multiselector.continueDrawingArea(e) diff --git a/Widgets/Textbox.py b/Widgets/Textbox.py index 998d2fe..2c6c170 100644 --- a/Widgets/Textbox.py +++ b/Widgets/Textbox.py @@ -49,11 +49,11 @@ def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): return action toolbarTop = QToolBar() - toolbarTop.setIconSize(QSize(25, 25)) + toolbarTop.setIconSize(QSize(16, 16)) toolbarTop.setMovable(False) toolbarBottom = QToolBar() - toolbarBottom.setIconSize(QSize(25, 25)) + toolbarBottom.setIconSize(QSize(16, 16)) toolbarBottom.setMovable(False) font = QFontComboBox() @@ -73,10 +73,10 @@ def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): underline.toggled.connect(lambda x: self.setFontUnderlineCustom(True if x else False)) fontColor = build_action(toolbarBottom, 'assets/icons/svg_font_color', "Font Color", "Font Color", False) - fontColor.triggered.connect(lambda x: self.setTextColorCustom(QColorDialog.getColor())) + fontColor.triggered.connect(lambda: self.setTextColorCustom(QColorDialog.getColor())) bgColor = build_action(toolbarBottom, 'assets/icons/svg_font_bucket', "Text Box Color", "Text Box Color", False) - bgColor.triggered.connect(lambda x: self.setBackgroundColor(QColorDialog.getColor())) + bgColor.triggered.connect(lambda: self.setBackgroundColor(QColorDialog.getColor())) toolbarTop.addWidget(font) toolbarTop.addWidget(size) From c726c6ae8bf7d76466cc563548363c0756a06bb5 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Wed, 18 Oct 2023 23:38:53 -0500 Subject: [PATCH 03/14] Added icons to toolbar Included hyperlink, table, undo, and redo buttons --- Assets/icons/svg_hyperlink.svg | 11 ++++++++ Assets/icons/svg_redo.svg | 7 +++++ Assets/icons/svg_table.svg | 4 +++ Assets/icons/svg_undo.svg | 4 +++ Models/DraggableContainer.py | 2 ++ Modules/BuildUI.py | 49 ++++++++++++++++++++-------------- 6 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 Assets/icons/svg_hyperlink.svg create mode 100644 Assets/icons/svg_redo.svg create mode 100644 Assets/icons/svg_table.svg create mode 100644 Assets/icons/svg_undo.svg diff --git a/Assets/icons/svg_hyperlink.svg b/Assets/icons/svg_hyperlink.svg new file mode 100644 index 0000000..930588a --- /dev/null +++ b/Assets/icons/svg_hyperlink.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/icons/svg_redo.svg b/Assets/icons/svg_redo.svg new file mode 100644 index 0000000..a96d7e5 --- /dev/null +++ b/Assets/icons/svg_redo.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Assets/icons/svg_table.svg b/Assets/icons/svg_table.svg new file mode 100644 index 0000000..9c21ff1 --- /dev/null +++ b/Assets/icons/svg_table.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Assets/icons/svg_undo.svg b/Assets/icons/svg_undo.svg new file mode 100644 index 0000000..aced362 --- /dev/null +++ b/Assets/icons/svg_undo.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Models/DraggableContainer.py b/Models/DraggableContainer.py index 978fa84..e57bec6 100644 --- a/Models/DraggableContainer.py +++ b/Models/DraggableContainer.py @@ -118,6 +118,8 @@ def leaveEvent(self, e: QMouseEvent): self.setStyleSheet("border: none;") # Delete this Draggable Container if childWidget says it's empty + # current bug: draggable containers will still exist after creating a + # new textbox but after creating an additional textbox, the dc will remove itself. if not self.childWidget.hasFocus(): if hasattr(self.childWidget, "checkEmpty"): if self.childWidget.checkEmpty(): diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index 8919244..df94611 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -37,6 +37,9 @@ def build_ui(editor): leftSideLayout.setContentsMargins(0, 0, 0, 0) leftSideLayout.setSpacing(0) + + + # Right side of the app's layout rightSideLayout = QVBoxLayout() rightSideContainerWidget = QWidget() @@ -56,6 +59,10 @@ def build_ui(editor): gridLayout.addWidget(leftSideContainerWidget, 0, 0) gridLayout.addWidget(rightSideContainerWidget, 0, 1) + addSectionButton = QPushButton("Add Section") + #add functionality e.g. addSectionButton.clcicked.connect(editor.add_section_function) + leftSideLayout.addWidget(addSectionButton) + def build_window(editor): editor.setWindowTitle("OpenNote") editor.setWindowIcon(QIcon('./Assets/OpenNoteLogo.png')) @@ -85,26 +92,20 @@ def build_menubar(editor): file.addActions([new_file, open_file, save_file, save_fileAs]) -''' -def build_toolbar(editor): - toolbar = QToolBar("Main toolbar") - editor.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar) - - button_action = QAction("Your button", editor) - button_action.setStatusTip("This is your button") - button_action.triggered.connect(action.onMyToolBarButtonClick) - button_action.setCheckable(True) - toolbar.addAction(button_action) -''' - - - def build_toolbar(editor): toolbar = QToolBar() toolbar.setIconSize(QSize(16, 16)) toolbar.setMovable(False) editor.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar) + spacer = QWidget() + spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + + undo = build_action(toolbar, 'assets/icons/svg_undo', "undo", "undo", False) + redo = build_action(toolbar, 'assets/icons/svg_redo', "redo", "redo", False) + + + font = QFontComboBox() font.currentFontChanged.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.Font, font.currentFont())) @@ -113,25 +114,33 @@ def build_toolbar(editor): size.currentIndexChanged.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontSize, int(size.currentText()))) bgColor = build_action(toolbar, 'assets/icons/svg_font_bucket', "Text Box Color", "Text Box Color", False) - bgColor.triggered.connect(lambda x: openGetColorDialog(purpose = "background")) + bgColor.triggered.connect(lambda: openGetColorDialog(purpose = "background")) + + fontColor = build_action(toolbar, 'assets/icons/svg_font_color', "Font Color", "Font Color", False) - fontColor.triggered.connect(lambda x: openGetColorDialog(purpose = "font")) + fontColor.triggered.connect(lambda: openGetColorDialog(purpose = "font")) bold = build_action(toolbar, 'assets/icons/bold', "Bold", "Bold", True) - bold.triggered.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) + bold.triggered.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) italic = build_action(toolbar, 'assets/icons/italic.svg', "Italic", "Italic", True) - italic.triggered.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontItalic, None)) + #italic.triggered.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(setFontItalicCustom), None) underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) - + table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", True) + hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", True) + + toolbar.addActions([undo, redo]) + toolbar.addSeparator() toolbar.addWidget(font) toolbar.addWidget(size) - + toolbar.addSeparator() toolbar.addActions([bgColor, fontColor, bold, italic, underline]) + toolbar.addSeparator() + toolbar.addActions([table, hyperlink]) def openGetColorDialog(purpose): From 436b4453d26915f8e04b467bce6d6b8570936dbf Mon Sep 17 00:00:00 2001 From: sillypenguin77 <67487654+sillypenguin77@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:39:26 -0500 Subject: [PATCH 04/14] Set default text to black --- Widgets/Textbox.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Widgets/Textbox.py b/Widgets/Textbox.py index 998d2fe..107702f 100644 --- a/Widgets/Textbox.py +++ b/Widgets/Textbox.py @@ -15,6 +15,7 @@ def __init__(self, x, y, w = 15, h = 30, t = ''): self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.textChanged.connect(self.textChangedEvent) self.setStyleSheet('background-color: rgba(0, 0, 0, 0);') + self.setTextColor('black') def textChangedEvent(self): if len(self.toPlainText()) < 2: From 148e5d727ff3bd7a8e053db20b38c8f8b89b9702 Mon Sep 17 00:00:00 2001 From: sillypenguin77 <67487654+sillypenguin77@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:39:56 -0500 Subject: [PATCH 05/14] Added Link Widget Functionality --- Views/EditorFrameView.py | 8 +++++ Widgets/Link.py | 76 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 Widgets/Link.py diff --git a/Views/EditorFrameView.py b/Views/EditorFrameView.py index 5232ead..e316db2 100644 --- a/Views/EditorFrameView.py +++ b/Views/EditorFrameView.py @@ -15,6 +15,10 @@ from Widgets.Table import TableWidget from Modules.Clipboard import Clipboard from Modules.Undo import UndoHandler +from Widgets.Link import LinkWidget +from Widgets.Link import LinkDialog + + # Handles all widget display (could be called widget view, but so could draggablecontainer) class EditorFrameView(QWidget): @@ -179,6 +183,10 @@ def mousePressEvent(self, event): add_custom_widget.triggered.connect(lambda: self.addCustomWidget(event)) frame_menu.addAction(add_custom_widget) + insert_Link = QAction("Insert Link", editor) + insert_Link.triggered.connect(lambda: self.newWidgetOnSection(LinkWidget,event.pos())) + frame_menu.addAction(insert_Link) + frame_menu.exec(event.globalPos()) def addCustomWidget(self, event): diff --git a/Widgets/Link.py b/Widgets/Link.py new file mode 100644 index 0000000..a6c41b1 --- /dev/null +++ b/Widgets/Link.py @@ -0,0 +1,76 @@ +from PySide6.QtCore import * +from PySide6.QtGui import * +from PySide6.QtWidgets import * + + +FONT_SIZES = [7, 8, 9, 10, 11, 12, 13, 14, 18, 24, 36, 48, 64, 72, 96, 144, 288] + + +class LinkWidget(QLabel): + def __init__(self, x, y, l, d, w = 15, h = 30): + super().__init__() + + self.setGeometry(x, y, w, h) + self.setStyleSheet('font-size: 20px') + self.setOpenExternalLinks(True) + + + self.setText(f'{d}') + #self.setParent(parent) + + @staticmethod + def new(clickPos: QPoint): + dialog = LinkDialog() + + if dialog.exec_() == QDialog.Accepted: + link_address, display_text = dialog.get_link_data() + + print(link_address) + + return LinkWidget(clickPos.x(), clickPos.y(), link_address, display_text) + + def __getstate__(self): + data = {} + + data['geometry'] = self.parentWidget().geometry() + #data['content'] = self.toHtml() + data['stylesheet'] = self.styleSheet() + return data + + def __setstate__(self, data): + self.__init__(data['geometry'].x(), data['geometry'].y(), data['geometry'].width(), data['geometry'].height(), data['content']) + self.setStyleSheet(data['stylesheet']) + +class LinkDialog(QDialog): + def __init__(self): + super().__init__() + self.setWindowTitle("Insert Link") + layout = QVBoxLayout() + + self.link_label = QLabel("Link Address:") + self.link_textbox = QLineEdit() + self.display_label = QLabel("Display Text:") + self.display_textbox = QLineEdit() + + layout.addWidget(self.link_label) + layout.addWidget(self.link_textbox) + layout.addWidget(self.display_label) + layout.addWidget(self.display_textbox) + + ok_button = QPushButton("OK") + ok_button.clicked.connect(self.accept) + cancel_button = QPushButton("Cancel") + cancel_button.clicked.connect(self.reject) + + layout.addWidget(ok_button) + layout.addWidget(cancel_button) + + self.setLayout(layout) + + def get_link_data(self): + link_address = self.link_textbox.text() + display_text = self.display_textbox.text() + return link_address, display_text + + + From 8d2eac0551126b93b1098a8a51d9ddbd17502875 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Wed, 1 Nov 2023 16:28:11 -0500 Subject: [PATCH 06/14] Added table edit --- Modules/BuildUI.py | 53 +++++++++++++++++++++++++++++++++++++++- Views/EditorFrameView.py | 9 ++++--- Widgets/Table.py | 48 ++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index df94611..2b456ef 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -5,6 +5,8 @@ from PySide6.QtGui import * from PySide6.QtWidgets import * +from Views.EditorFrameView import * +from Widgets.Table import * from Modules.EditorSignals import editorSignalsInstance, ChangedWidgetAttribute FONT_SIZES = [7, 8, 9, 10, 11, 12, 13, 14, 18, 24, 36, 48, 64, 72, 96, 144, 288] @@ -130,7 +132,9 @@ def build_toolbar(editor): underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) - table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", True) + table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", False) + table.triggered.connect(show_table_popup) + hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", True) toolbar.addActions([undo, redo]) @@ -156,3 +160,50 @@ def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): action.setStatusTip(set_status_tip) action.setCheckable(set_checkable) return action + +def show_table_popup(self): + popup = TablePopupWindow() + popup.exec_() + #def undo_triggered(self): + # Call the EditorFrameView's triggerUndo method + #self.EditorFrameView.triggerUndo() + +class TablePopupWindow(QDialog): + def __init__(self): + super().__init__() + '''self.setWindowTitle("Popup Window") + layout = QVBoxLayout() + label = QLabel("This is a popup window.") + layout.addWidget(label) + self.setLayout(layout)''' + self.setWindowTitle("Table Configuration") + self.layout = QVBoxLayout() + + self.rows_input = QLineEdit(self) + self.rows_input.setPlaceholderText("Enter number of rows:") + self.layout.addWidget(self.rows_input) + + self.cols_input = QLineEdit(self) + colNum = self.cols_input.setPlaceholderText("Enter number of columns:") + self.layout.addWidget(self.cols_input) + + create_table_button = QPushButton("Create Table") + self.layout.addWidget(create_table_button) + create_table_button.clicked.connect(self.accept) + #create error message if no data is entered or if number of rows or columns are < 1 + + cancel_button = QPushButton("Cancel") + cancel_button.clicked.connect(self.reject) + self.setLayout(self.layout) + + def get_table_data(self): + rows_input = self.rows_input.text() + cols_input = self.cols_input.text() + return rows_input, cols_input + + def create_table(self): + print("table") + #row_num = int(self.rows_input.text()) + #col_num = int(self.cols_input.text()) + #self.EditorFrameView.add_table_action(row_num, col_num) + diff --git a/Views/EditorFrameView.py b/Views/EditorFrameView.py index 38b5f63..13d1846 100644 --- a/Views/EditorFrameView.py +++ b/Views/EditorFrameView.py @@ -160,10 +160,6 @@ def mousePressEvent(self, e): if e.buttons() == Qt.RightButton: frame_menu = QMenu(self) - cut_action = QAction("Cut", self) - #add cut functionality - frame_menu.addAction(cut_action) - paste = QAction("Paste", editor) paste.triggered.connect(lambda: self.pasteWidget(e.pos())) frame_menu.addAction(paste) @@ -226,3 +222,8 @@ def mouseMoveEvent(self, e): # This event is only called after clicking down on # Resize multi-select widget on mouse every proceeding mouse movement (dragging) else: self.multiselector.continueDrawingArea(e) + def add_table_action(self): + print("Add table action") + + self.newWidgetOnSection(TableWidget, 0) + \ No newline at end of file diff --git a/Widgets/Table.py b/Widgets/Table.py index 7f615ff..4b3fe13 100644 --- a/Widgets/Table.py +++ b/Widgets/Table.py @@ -2,6 +2,7 @@ from PySide6.QtGui import * from PySide6.QtWidgets import * + class TableWidget(QWidget): def __init__(self, x, y, w, h, rows, cols): super(TableWidget, self).__init__() @@ -42,6 +43,8 @@ def addCol(self): @staticmethod def new(clickPos: QPoint): + #dialog = table + #if return TableWidget(clickPos.x(), clickPos.y(), 200, 200, 2, 2) def customMenuItems(self): @@ -79,3 +82,48 @@ def __setstate__(self, state): for i in range(colCnt): for j in range(rowCnt): self.table.setItem(j, i, QTableWidgetItem(state['tableData'][i][j])) + +def show_table_popup(self): + popup = TablePopupWindow() + popup.exec_() + #def undo_triggered(self): + # Call the EditorFrameView's triggerUndo method + #self.EditorFrameView.triggerUndo() + +class TablePopupWindow(QDialog): + def __init__(self): + super().__init__() + '''self.setWindowTitle("Popup Window") + layout = QVBoxLayout() + label = QLabel("This is a popup window.") + layout.addWidget(label) + self.setLayout(layout)''' + self.setWindowTitle("Table Configuration") + self.layout = QVBoxLayout() + + self.rows_input = QLineEdit(self) + self.rows_input.setPlaceholderText("Enter number of rows:") + self.layout.addWidget(self.rows_input) + + self.cols_input = QLineEdit(self) + colNum = self.cols_input.setPlaceholderText("Enter number of columns:") + self.layout.addWidget(self.cols_input) + + create_table_button = QPushButton("Create Table", self) + self.layout.addWidget(self.create_button) + #create error message if no data is entered or if number of rows or columns are < 1 + create_table_button.clicked.connect(self.accept) + cancel_button = QPushButton("Cancel") + cancel_button.clicked.connect(self.reject) + self.setLayout(self.layout) + + def get_table_data(self): + rows_input = self.rows_input.text() + cols_input = self.cols_input.text() + return rows_input, cols_input + + def create_table(self): + print("table") + #row_num = int(self.rows_input.text()) + #col_num = int(self.cols_input.text()) + #self.EditorFrameView.add_table_action(row_num, col_num) \ No newline at end of file From 86d412f84986f84c5b37e62449a27b3affaf77cb Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:24:02 -0500 Subject: [PATCH 07/14] added table functionality --- Modules/BuildUI.py | 87 +++++++++++++++++++++++++++++++++++----- Views/EditorFrameView.py | 52 +++++++++++++++++++----- Widgets/Textbox.py | 82 +++++++++++++++++++++---------------- 3 files changed, 168 insertions(+), 53 deletions(-) diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index 2b456ef..99d1d93 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -5,9 +5,14 @@ from PySide6.QtGui import * from PySide6.QtWidgets import * -from Views.EditorFrameView import * -from Widgets.Table import * +from Models.DraggableContainer import DraggableContainer +from Widgets.Textbox import * + from Modules.EditorSignals import editorSignalsInstance, ChangedWidgetAttribute +from Modules.Undo import UndoHandler +from Widgets.Table import * + +from Views.EditorFrameView import * FONT_SIZES = [7, 8, 9, 10, 11, 12, 13, 14, 18, 24, 36, 48, 64, 72, 96, 144, 288] @@ -15,10 +20,13 @@ def build_ui(editor): print("Building UI...") + + #editor.EditorFrameView = EditorFrameView(editor) #editor.statusBar = editor.statusBar() build_window(editor) build_menubar(editor) build_toolbar(editor) + #build_test_toolbar(editor) # Application's main layout (grid) gridLayout = QGridLayout() @@ -100,16 +108,20 @@ def build_toolbar(editor): toolbar.setMovable(False) editor.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar) + #separates toolbar with a line break spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) - undo = build_action(toolbar, 'assets/icons/svg_undo', "undo", "undo", False) + toolbar_undo = build_action(toolbar, 'assets/icons/svg_undo', "undo", "undo", False) + #toolbar_undo.triggered.connect(editor.frameView.triggerUndo) + + redo = build_action(toolbar, 'assets/icons/svg_redo', "redo", "redo", False) font = QFontComboBox() - font.currentFontChanged.connect(lambda x: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.Font, font.currentFont())) + font.currentFontChanged.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.Font, font.currentFont())) size = QComboBox() size.addItems([str(fs) for fs in FONT_SIZES]) @@ -124,8 +136,11 @@ def build_toolbar(editor): fontColor.triggered.connect(lambda: openGetColorDialog(purpose = "font")) bold = build_action(toolbar, 'assets/icons/bold', "Bold", "Bold", True) - bold.triggered.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) - + #bold.toggled.connect(editor.frameView.toggleBold) + #bold.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) + bold.triggered.connect(editor.frameView.add_table_action) + + #bold.toggled.connect(lambda x: editor.selected.setFontWeight(700 if x else 500)) italic = build_action(toolbar, 'assets/icons/italic.svg', "Italic", "Italic", True) #italic.triggered.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(setFontItalicCustom), None) @@ -133,11 +148,22 @@ def build_toolbar(editor): underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", False) - table.triggered.connect(show_table_popup) - + #table.triggered.connect(show_table_popup) + table.triggered.connect(EditorFrameView.add_table_action) hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", True) - toolbar.addActions([undo, redo]) + editor.action1 = QAction('Action 1', editor) + #editor.action1.triggered.connect(EditorFrameView.slot_action1) + toolbar.addAction(editor.action1) + editor.action2 = QAction('Action 2', editor) + #editor.action2.triggered.connect(TextboxWidget.slot_action2) + #editor.action2.triggered.connect(show_popup) + toolbar.addAction(editor.action2) + #editor.button = QPushButton("Click Me", editor) + #editor.button.clicked.connect(editor.slot_button_click) + + + #toolbar.addActions([undo, redo]) toolbar.addSeparator() toolbar.addWidget(font) toolbar.addWidget(size) @@ -146,6 +172,10 @@ def build_toolbar(editor): toolbar.addSeparator() toolbar.addActions([table, hyperlink]) +def toggle_bold(self): + self.is_bold = not self.is_bold + + font =self.text_edit def openGetColorDialog(purpose): color = QColorDialog.getColor() @@ -161,6 +191,45 @@ def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): action.setCheckable(set_checkable) return action +def build_test_toolbar(self): + editorFrameViewInstance = EditorFrameView(self) + + toolbar = QToolBar(self) + self.addToolBar(toolbar) + + exitAct = QAction(QIcon('assets/icons/underline.svg'), 'Exit', self) + exitAct.setShortcut('Ctrl+Q') + exitAct.triggered.connect(QApplication.instance().quit) + + self.toolbar = self.addToolBar('Exit') + self.toolbar.addAction(exitAct) + + #font_change + font_combo = QFontComboBox(self) + toolbar.addWidget(font_combo) + + bold = build_action(toolbar, 'assets/icons/bold', "Bold", "Bold", True) + bold.setShortcut('Ctrl+B') + bold.triggered.connect(lambda: editorSignalsInstance.widgetAttributeChanged.connect(self.widgetAttributeChangedEvent)) + + + toolbar.addAction(bold) + + undo_action = QAction("Undo", self) + undo_action.triggered.connect(self.frameView.triggerUndo) + + toolbar.addAction(undo_action) + + + +def change_font(self): + selected_font = self.sender().parent().widgetForAction(self.sender()).currentFont() + + self.text_edit.setFont(selected_font) + +def widgetAttributeChangedEvent(self, draggableContainer): + editorSignalsInstance.widgetAttributeChanged.emit(draggableContainer) + def show_table_popup(self): popup = TablePopupWindow() popup.exec_() diff --git a/Views/EditorFrameView.py b/Views/EditorFrameView.py index 13d1846..e1434fe 100644 --- a/Views/EditorFrameView.py +++ b/Views/EditorFrameView.py @@ -12,7 +12,7 @@ from Modules.EditorSignals import editorSignalsInstance from Widgets.Image import ImageWidget from Modules.Screensnip import SnippingWidget -from Widgets.Table import TableWidget +from Widgets.Table import * from Modules.Clipboard import Clipboard from Modules.Undo import UndoHandler @@ -46,10 +46,14 @@ def __init__(self, editor): # Undo setup self.shortcut = QShortcut(QKeySequence("Ctrl+Z"), self) self.shortcut.setContext(Qt.ApplicationShortcut) - self.shortcut.activated.connect(self.undoHandler.undo) - self.undoHandler.undoWidgetDelete.connect(self.undoWidgetDeleteEvent) + self.shortcut.activated.connect(self.triggerUndo) print("BUILT FRAMEVIEW") + + def triggerUndo(self): + print("triggerUndo Called") + self.undoHandler.undo + self.undoHandler.undoWidgetDelete.connect(self.undoWidgetDeleteEvent) def pasteWidget(self, clickPos): widgetOnClipboard = self.clipboard.getWidgetToPaste() @@ -150,6 +154,7 @@ def mouseReleaseEvent(self, event): # Releasing the mouse after clicking to add text else: + print("CREATE DRAGGABLE CONTAINER") self.newWidgetOnSection(TextboxWidget, event.pos()) def mousePressEvent(self, e): @@ -170,10 +175,9 @@ def mousePressEvent(self, e): add_table = QAction("Add Table", editor) add_table.triggered.connect(lambda: self.newWidgetOnSection(TableWidget, e.pos())) + #add_table.triggered.connect(self.show_table_popup) frame_menu.addAction(add_table) - - take_screensnip = QAction("Snip Screen", editor) take_screensnip.triggered.connect(lambda: self.snipScreen(e.pos())) frame_menu.addAction(take_screensnip) @@ -184,6 +188,11 @@ def mousePressEvent(self, e): frame_menu.exec(e.globalPos()) + def add_table_action(self): + print("add_table_action pressed") + clickPos = QPoint(0, 0) + self.newWidgetOnSection(TableWidget, clickPos) + def addCustomWidget(self, e): def getCustomWidgets(): customWidgets = {} # dict where entries are {name: class} @@ -222,8 +231,31 @@ def mouseMoveEvent(self, e): # This event is only called after clicking down on # Resize multi-select widget on mouse every proceeding mouse movement (dragging) else: self.multiselector.continueDrawingArea(e) - def add_table_action(self): - print("Add table action") - - self.newWidgetOnSection(TableWidget, 0) - \ No newline at end of file + + def toggleBold(self): + print ("TOGGLE BOLD") + dc = DraggableContainer() + cw = dc.childWidget + if(dc.hasFocus()): + cw.changeFontBoldEvent() + #editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, ) + + def slot_action1(self, item): + print("Action 1 triggered") + + +'''class PopupDialog(QDialog): + def __init__(self, name, parent): + super().__init__(parent) + self.resize(600, 300) + self.setWindowTitle("pop") + self.label = QLabel(name, self) + layout = QVBoxLayout() + layout.addWidget(QLabel("Test")) + ok_button = QPushButton("OK") + layout.addWidget(ok_button) + ok_button.clicked.connect(self.accept) + + self.setLayout(layout) + self.setWindowTitle("Table Creation") ''' + diff --git a/Widgets/Textbox.py b/Widgets/Textbox.py index 2c6c170..d0aedf9 100644 --- a/Widgets/Textbox.py +++ b/Widgets/Textbox.py @@ -1,6 +1,7 @@ from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * +from Modules.EditorSignals import editorSignalsInstance FONT_SIZES = [7, 8, 9, 10, 11, 12, 13, 14, 18, 24, 36, 48, 64, 72, 96, 144, 288] @@ -42,54 +43,58 @@ def checkEmpty(self): return False def customMenuItems(self): - def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): - action = QAction(QIcon(icon_path), action_name, parent) - action.setStatusTip(set_status_tip) - action.setCheckable(set_checkable) - return action + def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): + action = QAction(QIcon(icon_path), action_name, parent) + action.setStatusTip(set_status_tip) + action.setCheckable(set_checkable) + return action - toolbarTop = QToolBar() - toolbarTop.setIconSize(QSize(16, 16)) - toolbarTop.setMovable(False) + toolbarTop = QToolBar() + toolbarTop.setIconSize(QSize(25, 25)) + toolbarTop.setMovable(False) - toolbarBottom = QToolBar() - toolbarBottom.setIconSize(QSize(16, 16)) - toolbarBottom.setMovable(False) + toolbarBottom = QToolBar() + toolbarBottom.setIconSize(QSize(25, 25)) + toolbarBottom.setMovable(False) - font = QFontComboBox() - font.currentFontChanged.connect(lambda x: self.setCurrentFontCustom(font.currentFont() if x else self.currentFont())) + font = QFontComboBox() + font.currentFontChanged.connect(lambda x: self.setCurrentFontCustom(font.currentFont() if x else self.currentFont())) - size = QComboBox() - size.addItems([str(fs) for fs in FONT_SIZES]) - size.currentIndexChanged.connect(lambda x: self.setFontPointSizeCustom(FONT_SIZES[x] if x else self.fontPointSize())) + size = QComboBox() + size.addItems([str(fs) for fs in FONT_SIZES]) + size.currentIndexChanged.connect(lambda x: self.setFontPointSizeCustom(FONT_SIZES[x] if x else self.fontPointSize())) - bold = build_action(toolbarBottom, 'assets/icons/svg_font_bold', "Bold", "Bold", True) - bold.toggled.connect(lambda x: self.setFontWeightCustom(700 if x else 500)) + bold = build_action(toolbarBottom, 'assets/icons/svg_font_bold', "Bold", "Bold", True) + bold.toggled.connect(lambda x: self.setFontWeightCustom(700 if x else 500)) - italic = build_action(toolbarBottom, 'assets/icons/svg_font_italic', "Italic", "Italic", True) - italic.toggled.connect(lambda x: self.setFontItalicCustom(True if x else False)) + italic = build_action(toolbarBottom, 'assets/icons/svg_font_italic', "Italic", "Italic", True) + def italicToggled(): + print("Italic Toggled") + italic.toggled.connect(lambda x: self.setFontItalicCustom(True if x else False)) + italicToggled() - underline = build_action(toolbarBottom, 'assets/icons/svg_font_underline', "Underline", "Underline", True) - underline.toggled.connect(lambda x: self.setFontUnderlineCustom(True if x else False)) + underline = build_action(toolbarBottom, 'assets/icons/svg_font_underline', "Underline", "Underline", True) + underline.toggled.connect(lambda x: self.setFontUnderlineCustom(True if x else False)) - fontColor = build_action(toolbarBottom, 'assets/icons/svg_font_color', "Font Color", "Font Color", False) - fontColor.triggered.connect(lambda: self.setTextColorCustom(QColorDialog.getColor())) + fontColor = build_action(toolbarBottom, 'assets/icons/svg_font_color', "Font Color", "Font Color", False) + fontColor.triggered.connect(lambda: self.setTextColorCustom(QColorDialog.getColor())) - bgColor = build_action(toolbarBottom, 'assets/icons/svg_font_bucket', "Text Box Color", "Text Box Color", False) - bgColor.triggered.connect(lambda: self.setBackgroundColor(QColorDialog.getColor())) + bgColor = build_action(toolbarBottom, 'assets/icons/svg_font_bucket', "Text Box Color", "Text Box Color", False) + bgColor.triggered.connect(lambda: self.setBackgroundColor(QColorDialog.getColor())) - toolbarTop.addWidget(font) - toolbarTop.addWidget(size) - toolbarBottom.addActions([bold, italic, underline, fontColor, bgColor]) - qwaTop = QWidgetAction(self) - qwaTop.setDefaultWidget(toolbarTop) - qwaBottom = QWidgetAction(self) - qwaBottom.setDefaultWidget(toolbarBottom) + toolbarTop.addWidget(font) + toolbarTop.addWidget(size) + toolbarBottom.addActions([bold, italic, underline, fontColor, bgColor]) + qwaTop = QWidgetAction(self) + qwaTop.setDefaultWidget(toolbarTop) + qwaBottom = QWidgetAction(self) + qwaBottom.setDefaultWidget(toolbarBottom) - return [qwaTop, qwaBottom] + return [qwaTop, qwaBottom] def setFontItalicCustom(self, italic: bool): if not self.applyToAllIfNoSelection(lambda: self.setFontItalic(italic)): + print("setFontItalicCustom Called") self.setFontItalic(italic) def setFontWeightCustom(self, weight: int): @@ -137,3 +142,12 @@ def applyToAllIfNoSelection(self, func): cursor.clearSelection() self.setTextCursor(cursor) return True + + def attributeChangedSlot(attribute, value): + if attribute == editorSignalsInstance.ChangedWidgetAttribute.FontBold: + print("Font Bold Signal") + def slot_action2(self): + print("Action 2 Triggered") + font = QFont() + font.setItalic(True) + self.setFont(font) From a9d70c4d46aad8902a88fe787449fb5790e0108c Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Thu, 2 Nov 2023 18:50:47 -0500 Subject: [PATCH 08/14] Allow custom table sizes --- Modules/BuildUI.py | 53 ++++------------------------------------------ Widgets/Table.py | 21 +++++++++++------- 2 files changed, 17 insertions(+), 57 deletions(-) diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index 99d1d93..d2152e1 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -148,9 +148,9 @@ def build_toolbar(editor): underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", False) - #table.triggered.connect(show_table_popup) table.triggered.connect(EditorFrameView.add_table_action) - hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", True) + #table.triggered.connect(EditorFrameView.add_table_action) + hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", False) editor.action1 = QAction('Action 1', editor) #editor.action1.triggered.connect(EditorFrameView.slot_action1) @@ -228,51 +228,6 @@ def change_font(self): self.text_edit.setFont(selected_font) def widgetAttributeChangedEvent(self, draggableContainer): - editorSignalsInstance.widgetAttributeChanged.emit(draggableContainer) - -def show_table_popup(self): - popup = TablePopupWindow() - popup.exec_() - #def undo_triggered(self): - # Call the EditorFrameView's triggerUndo method - #self.EditorFrameView.triggerUndo() - -class TablePopupWindow(QDialog): - def __init__(self): - super().__init__() - '''self.setWindowTitle("Popup Window") - layout = QVBoxLayout() - label = QLabel("This is a popup window.") - layout.addWidget(label) - self.setLayout(layout)''' - self.setWindowTitle("Table Configuration") - self.layout = QVBoxLayout() - - self.rows_input = QLineEdit(self) - self.rows_input.setPlaceholderText("Enter number of rows:") - self.layout.addWidget(self.rows_input) - - self.cols_input = QLineEdit(self) - colNum = self.cols_input.setPlaceholderText("Enter number of columns:") - self.layout.addWidget(self.cols_input) - - create_table_button = QPushButton("Create Table") - self.layout.addWidget(create_table_button) - create_table_button.clicked.connect(self.accept) - #create error message if no data is entered or if number of rows or columns are < 1 - - cancel_button = QPushButton("Cancel") - cancel_button.clicked.connect(self.reject) - self.setLayout(self.layout) - - def get_table_data(self): - rows_input = self.rows_input.text() - cols_input = self.cols_input.text() - return rows_input, cols_input - - def create_table(self): - print("table") - #row_num = int(self.rows_input.text()) - #col_num = int(self.cols_input.text()) - #self.EditorFrameView.add_table_action(row_num, col_num) + editorSignalsInstance.widgetAttributeChanged.emit(draggableContainer) + diff --git a/Widgets/Table.py b/Widgets/Table.py index 4b3fe13..4d7768f 100644 --- a/Widgets/Table.py +++ b/Widgets/Table.py @@ -2,7 +2,6 @@ from PySide6.QtGui import * from PySide6.QtWidgets import * - class TableWidget(QWidget): def __init__(self, x, y, w, h, rows, cols): super(TableWidget, self).__init__() @@ -43,9 +42,11 @@ def addCol(self): @staticmethod def new(clickPos: QPoint): - #dialog = table - #if - return TableWidget(clickPos.x(), clickPos.y(), 200, 200, 2, 2) + dialog = TablePopupWindow() + if dialog.exec_() == QDialog.Accepted: + rows_input, cols_input = dialog.get_table_data() + print(f"rows input is {rows_input} cols_input is {cols_input}") + return TableWidget(clickPos.x(), clickPos.y(), 200, 200, int(rows_input), int(cols_input)) def customMenuItems(self): addRow = QAction("Add Row", self) @@ -109,12 +110,16 @@ def __init__(self): colNum = self.cols_input.setPlaceholderText("Enter number of columns:") self.layout.addWidget(self.cols_input) - create_table_button = QPushButton("Create Table", self) - self.layout.addWidget(self.create_button) - #create error message if no data is entered or if number of rows or columns are < 1 + create_table_button = QPushButton("Create Table") + self.layout.addWidget(create_table_button) create_table_button.clicked.connect(self.accept) + #create error message if no data is entered or if number of rows or columns are < 1 + cancel_button = QPushButton("Cancel") + self.layout.addWidget(cancel_button) cancel_button.clicked.connect(self.reject) + + self.setLayout(self.layout) def get_table_data(self): @@ -126,4 +131,4 @@ def create_table(self): print("table") #row_num = int(self.rows_input.text()) #col_num = int(self.cols_input.text()) - #self.EditorFrameView.add_table_action(row_num, col_num) \ No newline at end of file + #self.EditorFrameView.add_table_action(row_num, col_num) From dcd5de27054d1eeb91c0eff27a90475010e611e4 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Fri, 3 Nov 2023 12:45:01 -0500 Subject: [PATCH 09/14] Toolbar table functionality added Now you can create a table with a custom size. No error handling done yet --- Modules/BuildUI.py | 3 +-- Views/EditorFrameView.py | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index d2152e1..a463195 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -148,8 +148,7 @@ def build_toolbar(editor): underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", False) - table.triggered.connect(EditorFrameView.add_table_action) - #table.triggered.connect(EditorFrameView.add_table_action) + table.triggered.connect(editor.frameView.add_table_action) hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", False) editor.action1 = QAction('Action 1', editor) diff --git a/Views/EditorFrameView.py b/Views/EditorFrameView.py index e1434fe..0ef5c4d 100644 --- a/Views/EditorFrameView.py +++ b/Views/EditorFrameView.py @@ -44,9 +44,9 @@ def __init__(self, editor): self.installEventFilter(self.multiselector) # Undo setup - self.shortcut = QShortcut(QKeySequence("Ctrl+Z"), self) - self.shortcut.setContext(Qt.ApplicationShortcut) - self.shortcut.activated.connect(self.triggerUndo) + #self.shortcut = QShortcut(QKeySequence("Ctrl+Z"), self) + #self.shortcut.setContext(Qt.ApplicationShortcut) + #self.shortcut.activated.connect(self.triggerUndo) print("BUILT FRAMEVIEW") From c003263df66b40d866eda0a5fc7ea05fe0d7e2a5 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Fri, 3 Nov 2023 14:10:38 -0500 Subject: [PATCH 10/14] Added bullets and italics italics currently selects all containers and italicize --- Assets/icons/svg_bullets.svg | 19 +++++++++++++++++++ Modules/BuildUI.py | 15 ++++++++++----- Views/EditorFrameView.py | 27 ++++++++++++++------------- Widgets/Textbox.py | 16 ++++++++++++---- 4 files changed, 55 insertions(+), 22 deletions(-) create mode 100644 Assets/icons/svg_bullets.svg diff --git a/Assets/icons/svg_bullets.svg b/Assets/icons/svg_bullets.svg new file mode 100644 index 0000000..fb527c0 --- /dev/null +++ b/Assets/icons/svg_bullets.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index a463195..bb12ef0 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -59,6 +59,7 @@ def build_ui(editor): rightSideLayout.setStretch(0, 0) rightSideLayout.setStretch(1, 1) + # Add appropriate widgets (ideally just view controllers) to their layouts leftSideLayout.addWidget(editor.notebookTitleView, 0) leftSideLayout.addWidget(editor.pageView, 1) # Page view has max stretch factor @@ -138,18 +139,22 @@ def build_toolbar(editor): bold = build_action(toolbar, 'assets/icons/bold', "Bold", "Bold", True) #bold.toggled.connect(editor.frameView.toggleBold) #bold.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) - bold.triggered.connect(editor.frameView.add_table_action) + #bold.triggered.connect(editor.frameView.add_table_action) #bold.toggled.connect(lambda x: editor.selected.setFontWeight(700 if x else 500)) italic = build_action(toolbar, 'assets/icons/italic.svg', "Italic", "Italic", True) - #italic.triggered.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(setFontItalicCustom), None) + italic.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontItalic, None)) underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", False) - table.triggered.connect(editor.frameView.add_table_action) + table.triggered.connect(editor.frameView.toolbar_table) hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", False) + hyperlink.triggered.connect(editor.frameView.toolbar_hyperlink) + bullets = build_action(toolbar, 'assets/icons/svg_bullets', "Hyperlink", "Hyperlink", False) + + editor.action1 = QAction('Action 1', editor) #editor.action1.triggered.connect(EditorFrameView.slot_action1) @@ -160,7 +165,7 @@ def build_toolbar(editor): toolbar.addAction(editor.action2) #editor.button = QPushButton("Click Me", editor) #editor.button.clicked.connect(editor.slot_button_click) - + #toolbar.addActions([undo, redo]) toolbar.addSeparator() @@ -169,7 +174,7 @@ def build_toolbar(editor): toolbar.addSeparator() toolbar.addActions([bgColor, fontColor, bold, italic, underline]) toolbar.addSeparator() - toolbar.addActions([table, hyperlink]) + toolbar.addActions([table, hyperlink, bullets]) def toggle_bold(self): self.is_bold = not self.is_bold diff --git a/Views/EditorFrameView.py b/Views/EditorFrameView.py index 747bc13..ba88afe 100644 --- a/Views/EditorFrameView.py +++ b/Views/EditorFrameView.py @@ -161,50 +161,51 @@ def mouseReleaseEvent(self, event): print("CREATE DRAGGABLE CONTAINER") self.newWidgetOnSection(TextboxWidget, event.pos()) - def mousePressEvent(self, e): + def mousePressEvent(self, event): print("EDITORFRAME MOUSEPRESS") editor = self.editor # Open context menu on right click - if e.buttons() == Qt.RightButton: + if event.buttons() == Qt.RightButton: frame_menu = QMenu(self) paste = QAction("Paste", editor) - paste.triggered.connect(lambda: self.pasteWidget(e.pos())) + paste.triggered.connect(lambda: self.pasteWidget(event.pos())) frame_menu.addAction(paste) add_image = QAction("Add Image", self) - add_image.triggered.connect(lambda: self.newWidgetOnSection(ImageWidget, e.pos())) + add_image.triggered.connect(lambda: self.newWidgetOnSection(ImageWidget, event.pos())) frame_menu.addAction(add_image) add_table = QAction("Add Table", editor) - add_table.triggered.connect(lambda: self.newWidgetOnSection(TableWidget, e.pos())) + add_table.triggered.connect(lambda: self.newWidgetOnSection(TableWidget, event.pos())) #add_table.triggered.connect(self.show_table_popup) frame_menu.addAction(add_table) take_screensnip = QAction("Snip Screen", editor) - take_screensnip.triggered.connect(lambda: self.snipScreen(e.pos())) + take_screensnip.triggered.connect(lambda: self.snipScreen(event.pos())) frame_menu.addAction(take_screensnip) add_custom_widget = QAction("Add Custom Widget", editor) - add_custom_widget.triggered.connect(lambda: self.addCustomWidget(e)) + add_custom_widget.triggered.connect(lambda: self.addCustomWidget(event)) frame_menu.addAction(add_custom_widget) -<<<<<<< HEAD - frame_menu.exec(e.globalPos()) -======= insert_Link = QAction("Insert Link", editor) insert_Link.triggered.connect(lambda: self.newWidgetOnSection(LinkWidget,event.pos())) frame_menu.addAction(insert_Link) frame_menu.exec(event.globalPos()) ->>>>>>> main - def add_table_action(self): - print("add_table_action pressed") + def toolbar_table(self): + print("toolbar_table pressed") clickPos = QPoint(0, 0) self.newWidgetOnSection(TableWidget, clickPos) + def toolbar_hyperlink(self): + print("toolbar_hyperlink pressed") + clickPos = QPoint(0, 0) + self.newWidgetOnSection(LinkWidget, clickPos) + def addCustomWidget(self, e): def getCustomWidgets(): customWidgets = {} # dict where entries are {name: class} diff --git a/Widgets/Textbox.py b/Widgets/Textbox.py index 4c8e32e..fa83bf2 100644 --- a/Widgets/Textbox.py +++ b/Widgets/Textbox.py @@ -69,10 +69,9 @@ def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): bold.toggled.connect(lambda x: self.setFontWeightCustom(700 if x else 500)) italic = build_action(toolbarBottom, 'assets/icons/svg_font_italic', "Italic", "Italic", True) - def italicToggled(): - print("Italic Toggled") - italic.toggled.connect(lambda x: self.setFontItalicCustom(True if x else False)) - italicToggled() + print("Italic Toggled from right click context menu") + italic.toggled.connect(lambda x: self.setFontItalicCustom(True if x else False)) + underline = build_action(toolbarBottom, 'assets/icons/svg_font_underline', "Underline", "Underline", True) underline.toggled.connect(lambda x: self.setFontUnderlineCustom(True if x else False)) @@ -152,3 +151,12 @@ def slot_action2(self): font = QFont() font.setItalic(True) self.setFont(font) + + def changeFontSizeEvent(self, weight): + print("changeFontSizeEvent Called") + self.setFontWeightCustom(weight) + + def changeFontItalicEvent(self): + print("changeFontItalicEvent Called") + #somehow highlights all boxes + self.setFontItalicCustom(lambda x: True if x else False) \ No newline at end of file From 6993f2035105eb062e9c4ded972442485cd0a412 Mon Sep 17 00:00:00 2001 From: benjamintran1 <145232360+benjamintran1@users.noreply.github.com> Date: Sat, 4 Nov 2023 13:14:30 -0500 Subject: [PATCH 11/14] Bold, Italics, and Underline for Toolbar Added functionality to: -bold -underline -italics --- Models/DraggableContainer.py | 1 - Modules/BuildUI.py | 6 ++-- Widgets/Textbox.py | 54 ++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/Models/DraggableContainer.py b/Models/DraggableContainer.py index e57bec6..f935762 100644 --- a/Models/DraggableContainer.py +++ b/Models/DraggableContainer.py @@ -309,4 +309,3 @@ def widgetAttributeChanged(self, changedWidgetAttribute, value): if hasattr(cw, "changeBackgroundColorEvent") and (changedWidgetAttribute == ChangedWidgetAttribute.BackgroundColor): cw.changeBackgroundColorEvent(value) - diff --git a/Modules/BuildUI.py b/Modules/BuildUI.py index bb12ef0..692997a 100644 --- a/Modules/BuildUI.py +++ b/Modules/BuildUI.py @@ -137,8 +137,7 @@ def build_toolbar(editor): fontColor.triggered.connect(lambda: openGetColorDialog(purpose = "font")) bold = build_action(toolbar, 'assets/icons/bold', "Bold", "Bold", True) - #bold.toggled.connect(editor.frameView.toggleBold) - #bold.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) + bold.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontBold, None)) #bold.triggered.connect(editor.frameView.add_table_action) #bold.toggled.connect(lambda x: editor.selected.setFontWeight(700 if x else 500)) @@ -147,7 +146,8 @@ def build_toolbar(editor): italic.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontItalic, None)) underline = build_action(toolbar, 'assets/icons/underline.svg', "Underline", "Underline", True) - #underline.toggled.connect(lambda x: editor.childWidget. setFontUnderlineCustom(True if x else False)) + underline.toggled.connect(lambda: editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontUnderline, None)) + table = build_action(toolbar, 'assets/icons/svg_table', "Create Table", "Create Table", False) table.triggered.connect(editor.frameView.toolbar_table) hyperlink = build_action(toolbar, 'assets/icons/svg_hyperlink', "Hyperlink", "Hyperlink", False) diff --git a/Widgets/Textbox.py b/Widgets/Textbox.py index fa83bf2..a961f89 100644 --- a/Widgets/Textbox.py +++ b/Widgets/Textbox.py @@ -69,7 +69,6 @@ def build_action(parent, icon_path, action_name, set_status_tip, set_checkable): bold.toggled.connect(lambda x: self.setFontWeightCustom(700 if x else 500)) italic = build_action(toolbarBottom, 'assets/icons/svg_font_italic', "Italic", "Italic", True) - print("Italic Toggled from right click context menu") italic.toggled.connect(lambda x: self.setFontItalicCustom(True if x else False)) @@ -156,7 +155,56 @@ def changeFontSizeEvent(self, weight): print("changeFontSizeEvent Called") self.setFontWeightCustom(weight) + #for communicating the signal editorSignalsInstance.widgetAttributeChanged.emit(ChangedWidgetAttribute.FontItalic, None) def changeFontItalicEvent(self): - print("changeFontItalicEvent Called") #somehow highlights all boxes - self.setFontItalicCustom(lambda x: True if x else False) \ No newline at end of file + cursor = self.textCursor() + current_format = cursor.charFormat() + + #Checks if currently selected text is italics + is_italic = current_format.fontItalic() + + #toggles the italics + current_format.setFontItalic(not is_italic) + + #Apply modified format to selected text + cursor.setCharFormat(current_format) + + #Update text cursor with modified format + self.setTextCursor(cursor) + + def changeFontBoldEvent(self): + #somehow highlights all boxes + cursor = self.textCursor() + current_format = cursor.charFormat() + + #Checks if currently selected text is bold + is_bold = current_format.fontWeight() == 700 + + #toggles the italics + if is_bold: + current_format.setFontWeight(500) + else: + current_format.setFontWeight(700) + #Apply modified format to selected text + cursor.setCharFormat(current_format) + + #Update text cursor with modified format + self.setTextCursor(cursor) + + def changeFontUnderlineEvent(self): + #somehow highlights all boxes + cursor = self.textCursor() + current_format = cursor.charFormat() + + #Checks if currently selected text is bold + is_underlined = current_format.fontUnderline() + + #toggles the underline + current_format.setFontUnderline(not is_underlined) + + #Apply modified format to selected text + cursor.setCharFormat(current_format) + + #Update text cursor with modified format + self.setTextCursor(cursor) \ No newline at end of file From 31c66821b2e61758319ebefb13ae1846a152e9f2 Mon Sep 17 00:00:00 2001 From: ldeltastreaml <70774713+ldeltastreaml@users.noreply.github.com> Date: Sat, 4 Nov 2023 15:29:47 -0500 Subject: [PATCH 12/14] Update requirements.txt --- requirements.txt | Bin 276 -> 142 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index f573bd8c25c581a2732c014309842490ca55a622..fbba2f85904daaf9ee772d5c1ba077b2b5df161f 100644 GIT binary patch literal 142 zcmaFAdw*VOZb7A;t)ZTgiJmbpSAIciUUHdkL1jrsex9AJiJrNhfu6Y$FIPZjPELNg zovo#wsh$ClTN#|0l4@pWYlgztbxcXg&nw0db}cSW%`3@F%t1&MXJjVjXQ$>N%m4sR CcPZZh literal 276 zcma)%!3x4K5JcZu@KY*Uwc^2p2k!;HK&@a=Qz6yj&sQgN6cHJch0NRC$*T|CxpL#l zN}4btXQq3~kO7UHBY^`CGE*%ly#~{XTj-2kb9a=~T%?B1%u?RmOqy3}&sIdGsfGRG jho7+)S$SXlgWeFOl(*H6ol<=3iuys#UQ^FzKXbeRcKs<; From 6fef18ae01c2fadb593c2ed813970c6bb71db881 Mon Sep 17 00:00:00 2001 From: Keido0208 <50084889+Keido0208@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:05:12 -0600 Subject: [PATCH 13/14] Fix create new notebook Prompt user to enter notebook name and set notebook name on side bar --- Modules/Load.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Load.py b/Modules/Load.py index b618271..3f2c60f 100644 --- a/Modules/Load.py +++ b/Modules/Load.py @@ -2,7 +2,7 @@ import os from Modules.Save import Autosaver - +import pyautogui from PySide6.QtWidgets import * from PySide6.QtCore import * from PySide6.QtGui import * @@ -13,8 +13,8 @@ def new(editor): print("RAN NEW") destroy(editor) - - editor.notebook = NotebookModel('Untitled') + p_name = pyautogui.prompt("Enter Page Name") + editor.notebook = NotebookModel(p_name) editor.notebookTitleView.setText(editor.notebook.title) editor.selected = None editor.autosaver = Autosaver(editor) From fa62c5ed3d8f9e44d9122de5b157211b5371baa5 Mon Sep 17 00:00:00 2001 From: Keido0208 <50084889+Keido0208@users.noreply.github.com> Date: Tue, 7 Nov 2023 11:18:20 -0600 Subject: [PATCH 14/14] Fix create new notebook Just a change from "Page" to "Notebook" --- Modules/Load.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/Load.py b/Modules/Load.py index 3f2c60f..bce98b7 100644 --- a/Modules/Load.py +++ b/Modules/Load.py @@ -13,7 +13,7 @@ def new(editor): print("RAN NEW") destroy(editor) - p_name = pyautogui.prompt("Enter Page Name") + p_name = pyautogui.prompt("Enter Notebook Name") editor.notebook = NotebookModel(p_name) editor.notebookTitleView.setText(editor.notebook.title) editor.selected = None