Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
401 changes: 401 additions & 0 deletions examples/mnist.ipyg

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from qtpy.QtWidgets import QApplication
from opencodeblocks.graphics.window import OCBWindow

sys.path.insert(0, os.path.join( os.path.dirname(__file__), "..", ".." ))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))

if __name__ == '__main__':
app = QApplication(sys.argv)
Expand Down
2 changes: 1 addition & 1 deletion opencodeblocks/core/serializable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def serialize(self) -> OrderedDict:
""" Serialize the object as an ordered dictionary. """
raise NotImplementedError()

def deserialize(self, data:OrderedDict, hashmap:dict=None, restore_id=True) -> None:
def deserialize(self, data: OrderedDict, hashmap: dict = None, restore_id=True) -> None:
""" Deserialize the object from an ordered dictionary.

Args:
Expand Down
47 changes: 25 additions & 22 deletions opencodeblocks/graphics/blocks/codeblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')


class OCBCodeBlock(OCBBlock):

"""
Expand Down Expand Up @@ -43,7 +44,7 @@ def __init__(self, **kwargs):

self.resizing_source_code = False

self.update_all() # Set the geometry of display and source_editor
self.update_all() # Set the geometry of display and source_editor

def init_source_editor(self):
""" Initialize the python source code editor. """
Expand All @@ -56,11 +57,12 @@ def init_source_editor(self):
@property
def _editor_widget_height(self):
return self.height - self.title_height - 2*self.edge_size \
- self.output_panel_height
- self.output_panel_height

@_editor_widget_height.setter
def _editor_widget_height(self, value: int):
self.output_panel_height = self.height - value - self.title_height - 2*self.edge_size
self.output_panel_height = self.height - \
value - self.title_height - 2*self.edge_size

def update_all(self):
""" Update the code block parts. """
Expand Down Expand Up @@ -94,7 +96,7 @@ def source(self) -> str:
return self._source

@source.setter
def source(self, value:str):
def source(self, value: str):
self._source = value
if hasattr(self, 'source_editor'):
editor_widget = self.source_editor.widget()
Expand All @@ -104,8 +106,9 @@ def source(self, value:str):
def stdout(self) -> str:
""" Code output. Be careful, this also includes stderr """
return self._stdout

@stdout.setter
def stdout(self, value:str):
def stdout(self, value: str):
self._stdout = value
if hasattr(self, 'source_editor'):
# If there is a text output, erase the image output and display the text output
Expand All @@ -123,7 +126,7 @@ def image(self) -> str:
return self._image

@image.setter
def image(self, value:str):
def image(self, value: str):
self._image = value
if hasattr(self, 'source_editor') and self.image != "":
# If there is an image output, erase the text output and display the image output
Expand All @@ -136,44 +139,44 @@ def image(self, value:str):
qlabel.setPixmap(pixmap)

@source.setter
def source(self, value:str):
def source(self, value: str):
self._source = value
if hasattr(self, 'source_editor'):
editor_widget = self.source_editor.widget()
editor_widget.setText(self._source)

def paint(self, painter: QPainter,
option: QStyleOptionGraphicsItem, #pylint:disable=unused-argument
widget: Optional[QWidget]=None): #pylint:disable=unused-argument
option: QStyleOptionGraphicsItem, # pylint:disable=unused-argument
widget: Optional[QWidget] = None): # pylint:disable=unused-argument
""" Paint the code output panel """
super().paint(painter, option, widget)
path_title = QPainterPath()
path_title.setFillRule(Qt.FillRule.WindingFill)
path_title.addRoundedRect(0, 0, self.width, self.height,
self.edge_size, self.edge_size)
self.edge_size, self.edge_size)
painter.setPen(Qt.PenStyle.NoPen)
painter.setBrush(self._brush_background)
painter.drawPath(path_title.simplified())

def _is_in_resize_source_code_area(self, pos:QPointF):
def _is_in_resize_source_code_area(self, pos: QPointF):
"""
Return True if the given position is in the area
used to resize the source code widget
"""
source_editor_start = self.height - self.output_panel_height - self.edge_size

return self.width - self.edge_size/2 < pos.x() and \
source_editor_start - self.edge_size < pos.y() < source_editor_start + self.edge_size
source_editor_start - self.edge_size < pos.y() < source_editor_start + \
self.edge_size


def _is_in_resize_area(self, pos:QPointF):
def _is_in_resize_area(self, pos: QPointF):
""" Return True if the given position is in the block resize_area. """

# This block features 2 resizing areas with 2 different behaviors
is_in_bottom_left = super()._is_in_resize_area(pos)
return is_in_bottom_left or self._is_in_resize_source_code_area(pos)

def _start_resize(self,pos:QPointF):
def _start_resize(self, pos: QPointF):
self.resizing = True
self.resize_start = pos
if self._is_in_resize_source_code_area(pos):
Expand All @@ -185,7 +188,7 @@ def _stop_resize(self):
self.resizing_source_code = False
QApplication.restoreOverrideCursor()

def mouseMoveEvent(self, event:QGraphicsSceneMouseEvent):
def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent):
"""
We override the default resizing behavior as the code part and the display part of the block
block can be resized independently.
Expand All @@ -195,12 +198,12 @@ def mouseMoveEvent(self, event:QGraphicsSceneMouseEvent):
self.width = max(self.width + delta.x(), self._min_width)

height_delta = max(delta.y(),
# List of all the quantities that must remain negative.
# Mainly: min_height - height must be negative for all elements
self._min_output_panel_height - self.output_panel_height,
self._min_height - self.height,
self._min_source_editor_height - self._editor_widget_height
)
# List of all the quantities that must remain negative.
# Mainly: min_height - height must be negative for all elements
self._min_output_panel_height - self.output_panel_height,
self._min_height - self.height,
self._min_source_editor_height - self._editor_widget_height
)

self.height += height_delta
if not self.resizing_source_code:
Expand Down
17 changes: 0 additions & 17 deletions opencodeblocks/graphics/function_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,6 @@ def run_cell(cell: str) -> str:
return kernel.execute(cell)


def run_with_variable_output(cell: str) -> None:
"""
This is a proof of concept to show that it is possible
to collect a variable output from a kernel execution

Here the kernel executes the code and prints the output repeatedly
For example: if cell="model.fit(...)", this would print the progress bar progressing

Args:
cell: String containing Python code
"""
kernel.client.execute(cell)
done = False
while not done:
output, done = kernel.update_output()
print(output)

def get_function_name(code: str) -> str:
"""
Parses a string of code and returns the first function name it finds
Expand Down
2 changes: 2 additions & 0 deletions opencodeblocks/graphics/kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

class Kernel():

"""jupyter_client kernel used to execute code and return output"""

def __init__(self):
self.kernel_manager, self.client = start_new_kernel()

Expand Down
5 changes: 3 additions & 2 deletions opencodeblocks/graphics/pyeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
if TYPE_CHECKING:
from opencodeblocks.graphics.view import OCBView


class PythonEditor(QsciScintilla):

""" In-block python editor for OpenCodeBlocks. """

def __init__(self, block: OCBBlock):
""" In-block python editor for OpenCodeBlocks.

Expand Down Expand Up @@ -88,7 +89,7 @@ def views(self) -> List['OCBView']:
""" Get the views in which the python_editor is present. """
return self.graphicsProxyWidget().scene().views()

def set_views_mode(self, mode:str):
def set_views_mode(self, mode: str):
""" Set the views in which the python_editor is present to editing mode. """
for view in self.views():
if mode == "MODE_EDITING" or view.is_mode("MODE_EDITING"):
Expand Down
3 changes: 2 additions & 1 deletion opencodeblocks/graphics/qss/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

from opencodeblocks.graphics.qss import dark_resources

def loadStylesheets(filenames:List[str]):

def loadStylesheets(filenames: List[str]):
styles = ''
for filename in filenames:
file = QFile(filename)
Expand Down
7 changes: 5 additions & 2 deletions opencodeblocks/graphics/qss/dark_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,12 +500,15 @@
rcc_version = 2
qt_resource_struct = qt_resource_struct_v2


def qInitResources():
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct,
qt_resource_name, qt_resource_data)
qt_resource_name, qt_resource_data)


def qCleanupResources():
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct,
qt_resource_name, qt_resource_data)
qt_resource_name, qt_resource_data)


qInitResources()
1 change: 1 addition & 0 deletions opencodeblocks/graphics/theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from PyQt5.Qsci import QsciLexerPython
from PyQt5.QtGui import QColor


class Theme:
""" Class holding the details of a specific theme"""

Expand Down
9 changes: 6 additions & 3 deletions opencodeblocks/graphics/theme_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
This module provides `theme_manager()`,
a method that returns a handle to the theme manager of the application.

The theme manager provides the color scheme for the syntax highlighting of the text areas containing code.
The theme manager provides the color scheme for the syntax highlighting
of the text areas containing code.
"""
import os
from typing import List
Expand All @@ -12,12 +13,13 @@

from opencodeblocks.graphics.theme import Theme


class ThemeManager(QObject):
""" Class loading theme files and providing the options set in those files """

themeChanged = pyqtSignal()

def __init__(self, parent = None):
def __init__(self, parent=None):
""" Load the default themes and the fonts available to construct the ThemeManager """
super().__init__(parent)
self._preferred_fonts = ["Inconsolata", "Roboto Mono", "Courier"]
Expand All @@ -28,7 +30,7 @@ def __init__(self, parent = None):
if font in available_fonts:
self.recommended_font_family = font
break

self._themes = []
self._selected_theme_index = 0
theme_path = "./themes"
Expand All @@ -40,6 +42,7 @@ def __init__(self, parent = None):
with open(full_path, 'r', encoding="utf-8") as f:
theme = Theme(name, f.read())
self._themes.append(theme)

@property
def selected_theme_index(self):
return self._selected_theme_index
Expand Down
6 changes: 4 additions & 2 deletions opencodeblocks/graphics/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from opencodeblocks.graphics.scene import OCBScene
from opencodeblocks.graphics.view import OCBView


class OCBWidget(QWidget):

""" Window for the OCB application. """
Expand Down Expand Up @@ -51,14 +52,15 @@ def isModified(self) -> bool:
def savepath(self):
""" Current cached file save path. Update window title when set."""
return self._savepath

@savepath.setter
def savepath(self, value:str):
def savepath(self, value: str):
self._savepath = value
self.updateTitle()

def save(self):
self.scene.save(self.savepath)

def load(self, filepath:str):
def load(self, filepath: str):
self.scene.load(filepath)
self.savepath = filepath
Loading