Commit 72e23ff7 authored by Nils Cedric Holle's avatar Nils Cedric Holle

Merge branch 'Extensions' into 'master'

Extensions

See merge request !62
parents 03871a68 d8459e07
......@@ -54,7 +54,7 @@ jump to step 4.
4. Install Puzzlestream using pip.
Run::
python3 -m pip install --upgrade puzzlestream
python3 -m pip install --upgrade --user puzzlestream
in the command line to install Puzzlestream.
......
# -*- coding: utf-8 -*-
from puzzlestream.backend.progressupdate import progressUpdate
from puzzlestream.backend.test import test
......
if __name__ == "__main__":
from puzzlestream.launch import main, setStdout
import sys
setStdout()
sys.exit(main())
# -*- coding: utf-8 -*-
from puzzlestream.apps.plot.app import PS1DPlotApp
__all__ = ["PS1DPlotApp"]
# -*- coding: utf-8 -*-
from typing import Callable
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from puzzlestream.backend.stream import PSStream
from puzzlestream.backend.streamsection import PSStreamSection
translate = QCoreApplication.translate
class PSApp:
def __init__(self, data: dict, **pars):
self.data = data
self._guiWidgetClass = PSAppGUIWidget
self.setParameters(**pars)
@property
def code(self) -> str:
text = "from puzzlestream.apps import " + self.__class__.__name__
text += "\next = " + self.__class__.__name__ + "(\n stream"
for key in self.__pars:
text += ",\n %s=%s" % (key, str(self.__pars[key]))
text += "\n)"
return text
@property
def data(self) -> dict:
return self.__data
@data.setter
def data(self, data: dict):
self.__data = data
def showGUI(self, ID: int, modules: dict, stream: PSStream, parent=None):
PSAppGUI(self, ID, modules, stream, self._guiWidgetClass,
parent=parent).show()
def copyCode(self):
clipboard = QApplication.clipboard()
clipboard.setText(self.code)
def setParameters(self, **pars):
self.__pars = pars
class PSAppGUI(QMainWindow):
def __init__(self, app: PSApp, ID: int, modules: dict, stream: PSStream,
widgetClass, parent=None, *args):
super().__init__(*args, parent=parent)
self.__widget = QWidget()
self.__id = ID
self.__app = app
self.__stream = stream
self.__modules = modules
self.__moduleChanger = QComboBox()
self.__moduleIDs = []
self.fillModuleChanger()
self.__moduleChanger.currentIndexChanged.connect(self.__moduleChanged)
self.__appWidget = widgetClass(app)
self.__btnCopyCode = QPushButton("Copy code")
self.__btnCopyCode.pressed.connect(self.__copyCode)
self.__layout = QGridLayout()
self.__widget.setLayout(self.__layout)
self.__layout.addWidget(self.__moduleChanger, 0, 0, 1, 3)
self.__layout.addWidget(self.__appWidget, 1, 0, 1, 3)
self.__layout.addWidget(self.__btnCopyCode, 2, 0, 1, 1)
self.setCentralWidget(self.__widget)
self.retranslateUi()
def fillModuleChanger(self):
self.__moduleChanger.clear()
self.__moduleIDs.clear()
for m in sorted(self.__modules.values()):
self.__moduleChanger.addItem(m.name)
self.__moduleIDs.append(m.id)
current = self.__moduleIDs.index(self.__id)
self.__moduleChanger.setCurrentIndex(current)
def __moduleChanged(self, index: int):
data = PSStreamSection(self.__moduleIDs[index], self.__stream).data
self.__app.data = data
self.__id = self.__moduleIDs[index]
self.__appWidget.reload()
def __copyCode(self):
self.__app.copyCode()
self.__btnCopyCode.setText(
translate("AppGUI", "Code copied to clipboard"))
t = QTimer()
t.singleShot(1000, self.__resetCopyBtnText)
def __resetCopyBtnText(self):
self.__btnCopyCode.setText(translate("AppGUI", "Copy code"))
def retranslateUi(self):
self.__resetCopyBtnText()
self.__appWidget.retranslateUi()
class PSAppGUIWidget(QWidget):
def __init__(self, app: PSApp, parent=None):
super().__init__(parent=parent)
self.__app = app
def reload(self):
raise NotImplementedError()
def retranslateUi(self):
raise NotImplementedError()
# -*- coding: utf-8 -*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from puzzlestream.backend.stream import PSStream
from puzzlestream.apps.base import PSApp, PSAppGUIWidget
app = "PS1DPlotApp"
name = "1D plot"
# icon = "icon.png"
class PS1DPlotApp(PSApp):
def __init__(self, data: dict, **pars):
super().__init__(data, **pars)
self._guiWidgetClass = PS1DPlotAppGUI
@property
def code(self) -> str:
return super().code
def setParameters(self, **pars):
super().setParameters(**pars)
class PS1DPlotAppGUI(PSAppGUIWidget):
def __init__(self, app: PSApp, parent=None):
super().__init__(app, parent=parent)
self.__app = app
self.__layout = QGridLayout()
self.setLayout(self.__layout)
self.__layout.addWidget(QLabel("Plot"), 0, 0)
def reload(self):
pass
def retranslateUi(self):
pass
......@@ -4,7 +4,7 @@ GenericName=Puzzlestream
GenericName[de]=Puzzlestream - Daten Analyse Software
Comment=Data-analysis
Icon=Puzzlestream
Exec=puzzlestream
Exec=python3 -m puzzlestream
Terminal=false
Type=Application
Categories=Application;Science;
......@@ -5,9 +5,11 @@ contains PSMainWindow, a subclass of QMainWindow
"""
import gc
import importlib
import json
import os
import shutil
import inspect
import subprocess
import sys
import time
......@@ -60,6 +62,7 @@ class PSMainWindow(QMainWindow):
self.__manager.scene.itemDeleted.connect(self.__itemDeleted)
self.setupUi()
self.__activeModule = None
self.__subWindows = []
self.puzzleGraphicsView.setScene(self.__manager.scene)
self.puzzleGraphicsView.setConfig(self.__manager.config)
......@@ -165,6 +168,7 @@ class PSMainWindow(QMainWindow):
self.__createCornerToolbarActions()
self.__createStartToolBarActions()
self.__createEditToolBarActions()
self.__createAppsToolBarActions()
self.__createStreamToolBarActions()
self.__createHelpToolBarActions()
self.__updateRecentProjects()
......@@ -803,6 +807,8 @@ class PSMainWindow(QMainWindow):
def __updateActiveModule(self, module: PSModule):
self.__updateEditorModule(module)
self.__activeModule = module
for a in self.appsToolBar.actions():
a.setEnabled(self.__activeModule is not None)
self.outputTextEdit.setText(module.stdout)
cursor = self.outputTextEdit.textCursor()
cursor.movePosition(cursor.End)
......@@ -948,6 +954,26 @@ class PSMainWindow(QMainWindow):
self.__sortImportsInFirstEditor)
self.__connectEditorActions(self.__editors[0])
def __createAppsToolBarActions(self):
self.appsToolBar.clear()
for d in os.walk(os.path.join(
os.path.dirname(__file__), "../apps/")):
if "app.py" in d[2]:
try:
spec = importlib.util.spec_from_file_location(
"app", os.path.join(d[0], "app.py"))
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
extClass = getattr(mod, mod.app)
a = self.appsToolBar.addAction(mod.name)
if self.__activeModule is None:
a.setEnabled(False)
if hasattr(mod, "icon"):
a.setIcon(QIcon(os.path.join(d[0], mod.icon)))
a.triggered.connect(lambda: self.__showAppGUI(extClass))
except Exception as e:
print(e)
def __createLibToolBarActions(self):
self.libToolBar.clear()
self.__pipGUIToolbarAction = self.libToolBar.addAction(
......@@ -1063,6 +1089,19 @@ class PSMainWindow(QMainWindow):
view.show()
self.__subWindows.append(view)
def __showAppGUI(self, AppClass):
if self.__activeModule is not None:
app = AppClass(self.__activeModule.streamSection.data)
app.showGUI(self.__activeModule.id, self.__manager.scene.modules,
self.__manager.stream, parent=self)
else:
notificationsystem.newNotification(
translate(
"MainWindow",
"You have to choose a module before starting an app."
)
)
def __removeFromWindowList(self, window: QMainWindow):
i = self.__subWindows.index(window)
self.__deleteTimer = QTimer()
......@@ -1286,6 +1325,7 @@ class PSMainWindow(QMainWindow):
e.hide()
self.__welcomeLabel.setText(self.__newProjectText)
self.__welcomeLabel.show()
self.__resetActiveModule()
for e in self.__activeElements:
e.setEnabled(False)
......@@ -1472,6 +1512,8 @@ class PSMainWindow(QMainWindow):
def __resetActiveModule(self):
self.__activeModule = None
for a in self.appsToolBar.actions():
a.setEnabled(False)
for a in [self.__plotViewAction, self.__dataViewAction]:
a.setEnabled(False)
......
......@@ -123,6 +123,12 @@ class PSModule(PSPuzzleDockItem):
def __repr__(self) -> str:
return self.name
def __lt__(a, b):
return a.name < b.name
def __gt__(a, b):
return a.name > b.name
def __getstate__(self) -> tuple:
return (self.id, self.centerPos().x(), self.centerPos().y(), self.path,
self.name, self.__libs)
......
......@@ -101,12 +101,13 @@ out = setup(
# What does your project relate to?
keywords="data analysis",
packages=["puzzlestream", "puzzlestream.backend", "puzzlestream.ui"],
packages=["puzzlestream", "puzzlestream.apps", "puzzlestream.apps.plot",
"puzzlestream.backend", "puzzlestream.ui"],
package_dir={"puzzlestream": "./puzzlestream"},
package_data={"": ["icons/*", "ui/style/*",
"ui/translations/*", "misc/*"]},
package_data={"": ["icons/*", "ui/style/*", "ui/translations/*",
"misc/*"]},
data_files=[("share/icons",
["puzzlestream/icons/Puzzlestream.png"]),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment