From 8120172b3af5d33af44fbf71903bab310efc19ae Mon Sep 17 00:00:00 2001
From: Olle Hansson <olle.hansson@liu.se>
Date: Thu, 30 Mar 2023 14:05:35 +0000
Subject: [PATCH] Guirecentfiles

---
 b_asic/GUI/gui_interface.py | 117 ++++++++++--------------------------
 b_asic/GUI/main_window.py   |  67 ++++++++++++++++++++-
 2 files changed, 97 insertions(+), 87 deletions(-)

diff --git a/b_asic/GUI/gui_interface.py b/b_asic/GUI/gui_interface.py
index cf251c46..6e9cad70 100644
--- a/b_asic/GUI/gui_interface.py
+++ b/b_asic/GUI/gui_interface.py
@@ -35,9 +35,7 @@ class Ui_main_window(object):
             "}"
         )
         self.operation_box.setAlignment(
-            QtCore.Qt.AlignLeading
-            | QtCore.Qt.AlignLeft
-            | QtCore.Qt.AlignVCenter
+            QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter
         )
         self.operation_box.setFlat(False)
         self.operation_box.setCheckable(False)
@@ -49,9 +47,7 @@ class Ui_main_window(object):
         self.core_operations_page = QtWidgets.QWidget()
         self.core_operations_page.setGeometry(QtCore.QRect(0, 0, 171, 217))
         self.core_operations_page.setObjectName("core_operations_page")
-        self.core_operations_list = QtWidgets.QListWidget(
-            self.core_operations_page
-        )
+        self.core_operations_list = QtWidgets.QListWidget(self.core_operations_page)
         self.core_operations_list.setGeometry(QtCore.QRect(10, 0, 141, 211))
         self.core_operations_list.setMinimumSize(QtCore.QSize(141, 0))
         self.core_operations_list.setEditTriggers(
@@ -85,9 +81,7 @@ class Ui_main_window(object):
         self.custom_operations_page = QtWidgets.QWidget()
         self.custom_operations_page.setGeometry(QtCore.QRect(0, 0, 171, 217))
         self.custom_operations_page.setObjectName("custom_operations_page")
-        self.custom_operations_list = QtWidgets.QListWidget(
-            self.custom_operations_page
-        )
+        self.custom_operations_list = QtWidgets.QListWidget(self.custom_operations_page)
         self.custom_operations_list.setGeometry(QtCore.QRect(10, 0, 141, 211))
         self.custom_operations_list.setObjectName("custom_operations_list")
         self.operation_list.addItem(self.custom_operations_page, "")
@@ -97,9 +91,7 @@ class Ui_main_window(object):
         palette = QtGui.QPalette()
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Button, brush)
@@ -120,14 +112,10 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
@@ -139,29 +127,19 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Shadow, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.AlternateBase, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.AlternateBase, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 220))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.ToolTipBase, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipBase, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.ToolTipText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ToolTipText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 128))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Active, QtGui.QPalette.PlaceholderText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.PlaceholderText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Button, brush)
@@ -170,9 +148,7 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Light, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.Midlight, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Midlight, brush)
         brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Dark, brush)
@@ -184,14 +160,10 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
@@ -203,29 +175,19 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Shadow, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.AlternateBase, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.AlternateBase, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 220))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipBase, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipBase, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ToolTipText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 128))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Inactive, QtGui.QPalette.PlaceholderText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.PlaceholderText, brush)
         brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 255, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Button, brush)
@@ -234,9 +196,7 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Light, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.Midlight, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Midlight, brush)
         brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Dark, brush)
@@ -248,14 +208,10 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush)
         brush = QtGui.QBrush(QtGui.QColor(127, 127, 127))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
         palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
@@ -267,24 +223,16 @@ class Ui_main_window(object):
         palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Shadow, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.AlternateBase, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.AlternateBase, brush)
         brush = QtGui.QBrush(QtGui.QColor(255, 255, 220))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipBase, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipBase, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ToolTipText, brush)
         brush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 128))
         brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(
-            QtGui.QPalette.Disabled, QtGui.QPalette.PlaceholderText, brush
-        )
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.PlaceholderText, brush)
         self.menu_bar.setPalette(palette)
         self.menu_bar.setObjectName("menu_bar")
         self.file_menu = QtWidgets.QMenu(self.menu_bar)
@@ -307,6 +255,8 @@ class Ui_main_window(object):
         self.save_menu.setObjectName("save_menu")
         self.load_operations = QtWidgets.QAction(main_window)
         self.load_operations.setObjectName("load_operations")
+        self.recent_sfg = QtWidgets.QMenu(main_window)
+        self.recent_sfg.setObjectName("recent_sfg")
         self.exit_menu = QtWidgets.QAction(main_window)
         self.exit_menu.setObjectName("exit_menu")
         self.actionSimulateSFG = QtWidgets.QAction(main_window)
@@ -326,6 +276,8 @@ class Ui_main_window(object):
         self.file_menu.addAction(self.save_menu)
         self.file_menu.addAction(self.load_operations)
         self.file_menu.addSeparator()
+        self.file_menu.addMenu(self.recent_sfg)
+        self.file_menu.addSeparator()
         self.file_menu.addAction(self.exit_menu)
         self.view_menu.addAction(self.actionToolbar)
         self.run_menu.addAction(self.actionShowPC)
@@ -376,17 +328,14 @@ class Ui_main_window(object):
         self.run_menu.setTitle(_translate("main_window", "Run"))
         self.actionShowPC.setText(_translate("main_window", "Show PG"))
         self.help_menu.setTitle(_translate("main_window", "Help"))
-        self.actionSimulateSFG.setText(
-            _translate("main_window", "Simulate SFG")
-        )
+        self.actionSimulateSFG.setText(_translate("main_window", "Simulate SFG"))
         self.aboutBASIC.setText(_translate("main_window", "About B-ASIC"))
         self.faqBASIC.setText(_translate("main_window", "FAQ"))
         self.keybindsBASIC.setText(_translate("main_window", "Keybinds"))
         self.load_menu.setText(_translate("main_window", "Load SFG"))
         self.save_menu.setText(_translate("main_window", "Save SFG"))
-        self.load_operations.setText(
-            _translate("main_window", "Load operations")
-        )
+        self.load_operations.setText(_translate("main_window", "Load operations"))
+        self.recent_sfg.setTitle(_translate("main_window", "Recent SFG"))
         self.exit_menu.setText(_translate("main_window", "Exit"))
         self.exit_menu.setShortcut(_translate("main_window", "Ctrl+Q"))
         self.actionToolbar.setText(_translate("main_window", "Toolbar"))
diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py
index 240a935c..50120146 100644
--- a/b_asic/GUI/main_window.py
+++ b/b_asic/GUI/main_window.py
@@ -8,10 +8,11 @@ import importlib
 import logging
 import os
 import sys
+from collections import deque
 from pprint import pprint
 from typing import Dict, List, Optional, Tuple
 
-from qtpy.QtCore import QFileInfo, QSize, Qt
+from qtpy.QtCore import QCoreApplication, QFileInfo, QSettings, QSize, Qt
 from qtpy.QtGui import QCursor, QIcon, QKeySequence, QPainter
 from qtpy.QtWidgets import (
     QAction,
@@ -30,6 +31,7 @@ from qtpy.QtWidgets import (
 
 import b_asic.core_operations
 import b_asic.special_operations
+from b_asic._version import __version__
 from b_asic.GUI._preferences import GAP, GRID, MINBUTTONSIZE, PORTHEIGHT
 from b_asic.GUI.arrow import Arrow
 from b_asic.GUI.drag_button import DragButton
@@ -56,6 +58,11 @@ from b_asic.special_operations import Input, Output
 
 logging.basicConfig(level=logging.INFO)
 
+QCoreApplication.setOrganizationName("Linköping University")
+QCoreApplication.setOrganizationDomain("liu.se")
+QCoreApplication.setApplicationName("B-ASIC SFG GUI")
+QCoreApplication.setApplicationVersion(__version__)
+
 
 @decorate_class(handle_error)
 class MainWindow(QMainWindow):
@@ -97,6 +104,10 @@ class MainWindow(QMainWindow):
         self.toolbar.addAction("Clear workspace", self.clear_workspace)
 
         # Add operations
+        self.maxFileNr = 4
+        self.recentFilesList = []
+        self.recentFilePaths = deque(maxlen=self.maxFileNr)
+
         self.add_operations_from_namespace(
             b_asic.core_operations, self.ui.core_operations_list
         )
@@ -145,6 +156,7 @@ class MainWindow(QMainWindow):
         self.shortcut_help.activated.connect(self.display_faq_page)
         self.shortcut_signal = QShortcut(QKeySequence(Qt.Key_Space), self)
         self.shortcut_signal.activated.connect(self._connect_callback)
+        self.createActionsAndMenus()
 
         self._keybindings_page = None
         self._about_page = None
@@ -225,6 +237,7 @@ class MainWindow(QMainWindow):
         module, accepted = QFileDialog().getOpenFileName()
         if not accepted:
             return
+        self.addRecentFile(module)
         self._load_from_file(module)
 
     def _load_from_file(self, module) -> None:
@@ -256,9 +269,7 @@ class MainWindow(QMainWindow):
         if positions is None:
             positions = {}
 
-        # print(sfg)
         for op in sfg.split():
-            # print(op)
             self.create_operation(
                 op,
                 positions[op.graph_id][0:2] if op.graph_id in positions else None,
@@ -299,6 +310,56 @@ class MainWindow(QMainWindow):
         self.sfg_dict[sfg.name] = sfg
         self.update()
 
+    def createActionsAndMenus(self):
+        for i in range(self.maxFileNr):
+            recentFileAction = QAction(self.ui.recent_sfg)
+            recentFileAction.setVisible(False)
+            recentFileAction.triggered.connect(
+                lambda b=0, x=recentFileAction: self.openRecent(x)
+            )
+            self.recentFilesList.append(recentFileAction)
+            self.ui.recent_sfg.addAction(recentFileAction)
+
+        self.updateRecentActionList()
+
+    def updateRecentActionList(self):
+        settings = QSettings()
+
+        rfp = settings.value("SFG/recentFiles")
+
+        # print(rfp)
+        if rfp:
+            dequelen = len(rfp)
+            if dequelen > 0:
+                for i in range(dequelen):
+                    action = self.recentFilesList[i]
+                    action.setText(rfp[i].fileName())
+                    action.setData(rfp[i])
+                    action.setVisible(True)
+
+                for i in range(dequelen, self.maxFileNr):
+                    self.recentFilesList[i].setVisible(False)
+
+    def openRecent(self, action):
+        self._load_from_file(action.data().filePath())
+
+    def addRecentFile(self, module):
+        settings = QSettings()
+
+        rfp = settings.value("SFG/recentFiles")
+
+        recentFile = QFileInfo(module)
+        if rfp:
+            if recentFile not in rfp:
+                rfp.append(recentFile)
+        else:
+            rfp = deque(maxlen=self.maxFileNr)
+            rfp.append(recentFile)
+
+        settings.setValue("SFG/recentFiles", rfp)
+
+        self.updateRecentActionList()
+
     def exit_app(self) -> None:
         self.logger.info("Exiting the application.")
         QApplication.quit()
-- 
GitLab