Finished welcome dialog. New project dialog prototype.
This commit is contained in:
parent
59cd033cad
commit
037843d14f
5
Makefile
5
Makefile
@ -7,8 +7,9 @@ UI_OUT=$(UI:.ui=_ui.py)
|
|||||||
all: $(RESOURCES_OUT) $(UI_OUT)
|
all: $(RESOURCES_OUT) $(UI_OUT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm ${UI_OUT}
|
rm -f ${UI_OUT}
|
||||||
rm ${RESOURCES_OUT}
|
rm -f ${RESOURCES_OUT}
|
||||||
|
find -name '__pycache__' -exec rm -rf "{}" \;
|
||||||
|
|
||||||
%_rc.py: %.qrc
|
%_rc.py: %.qrc
|
||||||
pyrcc5 $< -o $@
|
pyrcc5 $< -o $@
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
from .project_manager import ProjectManager
|
@ -1,49 +1,90 @@
|
|||||||
|
from typing import Iterable
|
||||||
|
|
||||||
from model.project import Project
|
from model.project import Project
|
||||||
|
from model import Project, RecentProject
|
||||||
|
from storage import AppDataStorage
|
||||||
|
|
||||||
class ProjectManager(object):
|
class ProjectManager(object):
|
||||||
|
|
||||||
def __init__(self, appDataStorage):
|
def __init__(self, appDataStorage : AppDataStorage):
|
||||||
self.__appDataStorage = appDataStorage
|
self.__appDataStorage = appDataStorage
|
||||||
self.__recentProjects = None
|
self.__recentProjects : dict = None
|
||||||
|
|
||||||
def getRecentProjects(self):
|
"""
|
||||||
|
Gets a list of recent projects. The list is lazily loaded on the first call.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list of RecentProjects
|
||||||
|
"""
|
||||||
|
def getRecentProjects(self) -> Iterable[RecentProject]:
|
||||||
if self.__recentProjects is None:
|
if self.__recentProjects is None:
|
||||||
self.__recentProjects = {}
|
self.__recentProjects = {}
|
||||||
for item in self.__appDataStorage.readRecentProjects():
|
for item in self.__appDataStorage.readRecentProjects():
|
||||||
self.__recentProjects[item['path']] = item
|
self.__recentProjects[item.path] = item
|
||||||
|
|
||||||
return self.__recentProjects.values()
|
return self.__recentProjects.values()
|
||||||
|
|
||||||
def pinRecentProject(self, entry, isPinned = True):
|
"""
|
||||||
entry['pinned'] = isPinned
|
Pins a recent project.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entry: recent project
|
||||||
|
isPinned: pinned or not
|
||||||
|
"""
|
||||||
|
def pinRecentProject(self, entry : RecentProject, isPinned : bool = True):
|
||||||
|
entry.pinned = isPinned
|
||||||
self.__appDataStorage.writeRecentProjects(self.__recentProjects.values())
|
self.__appDataStorage.writeRecentProjects(self.__recentProjects.values())
|
||||||
|
|
||||||
def deleteRecentProject(self, entry):
|
"""
|
||||||
self.__recentProjects.pop(entry['path'], None)
|
Deletes a recent project.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entry: recent project
|
||||||
|
"""
|
||||||
|
def deleteRecentProject(self, entry : RecentProject):
|
||||||
|
self.__recentProjects.pop(entry.path, None)
|
||||||
self.__appDataStorage.writeRecentProjects(self.__recentProjects.values())
|
self.__appDataStorage.writeRecentProjects(self.__recentProjects.values())
|
||||||
|
|
||||||
def debug_populateRecentProjects(self):
|
"""
|
||||||
self.__recentProjects['/home/tibi/Videos/project.pro'] = {
|
Creates a new project at the given path, and returns the created project.
|
||||||
'name' : 'Debug project',
|
|
||||||
'path' : '/home/tibi/Videos/project.pro',
|
Args:
|
||||||
'pinned' : True,
|
path: path to project file
|
||||||
'date' : 1
|
"""
|
||||||
}
|
def newProject(self, path : str) -> Project:
|
||||||
self.__recentProjects['/home/tibi/Videos/project2.pro'] = {
|
return Project(path)
|
||||||
'name' : 'Debug project 2',
|
|
||||||
'path' : '/home/tibi/Videos/project2.pro',
|
"""
|
||||||
'pinned' : False,
|
Opens an existing project.
|
||||||
'date' : 2
|
|
||||||
}
|
Args:
|
||||||
self.__recentProjects['/home/tibi/Videos/project3.pro'] = {
|
path: path to project file
|
||||||
'name' : 'Debug project 3',
|
"""
|
||||||
'path' : '/home/tibi/Videos/project3.pro',
|
def openProject(self, path : str) -> Project:
|
||||||
'pinned' : False,
|
return Project(path)
|
||||||
'date' : 3
|
|
||||||
}
|
# def debug_populateRecentProjects(self):
|
||||||
self.__recentProjects['/home/tibi/Videos/project4.pro'] = {
|
# self.__recentProjects['/home/tibi/Videos/project.pro'] = {
|
||||||
'name' : 'Debug project 4',
|
# 'name' : 'Debug project',
|
||||||
'path' : '/home/tibi/Videos/project4.pro',
|
# 'path' : '/home/tibi/Videos/project.pro',
|
||||||
'pinned' : False,
|
# 'pinned' : True,
|
||||||
'date' : 4
|
# 'date' : 1
|
||||||
}
|
# }
|
||||||
|
# self.__recentProjects['/home/tibi/Videos/project2.pro'] = {
|
||||||
|
# 'name' : 'Debug project 2',
|
||||||
|
# 'path' : '/home/tibi/Videos/project2.pro',
|
||||||
|
# 'pinned' : False,
|
||||||
|
# 'date' : 2
|
||||||
|
# }
|
||||||
|
# self.__recentProjects['/home/tibi/Videos/project3.pro'] = {
|
||||||
|
# 'name' : 'Debug project 3',
|
||||||
|
# 'path' : '/home/tibi/Videos/project3.pro',
|
||||||
|
# 'pinned' : False,
|
||||||
|
# 'date' : 3
|
||||||
|
# }
|
||||||
|
# self.__recentProjects['/home/tibi/Videos/project4.pro'] = {
|
||||||
|
# 'name' : 'Debug project 4',
|
||||||
|
# 'path' : '/home/tibi/Videos/project4.pro',
|
||||||
|
# 'pinned' : False,
|
||||||
|
# 'date' : 4
|
||||||
|
# }
|
@ -0,0 +1,2 @@
|
|||||||
|
from .recent_project import RecentProject
|
||||||
|
from .project import Project
|
@ -1,7 +1,7 @@
|
|||||||
class Project(object):
|
class Project(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, path):
|
||||||
self.root_dir = None
|
self.root_dir = path
|
||||||
|
|
||||||
def get_items(self):
|
def get_items(self):
|
||||||
pass
|
pass
|
60
model/recent_project.py
Normal file
60
model/recent_project.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import time
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
class RecentProject(object):
|
||||||
|
|
||||||
|
DICT_FIELDS = [ 'path', 'name', 'dateAccessed', 'pinned' ]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Creates new instance of RecentProject.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: name of the project
|
||||||
|
path: path to the project
|
||||||
|
dateAccessed: date (unix time) when project was last accessed
|
||||||
|
pinned: the project is pinned by the user
|
||||||
|
|
||||||
|
Remarks:
|
||||||
|
If dateAccessed = None, it will be set to the current date and time.
|
||||||
|
"""
|
||||||
|
def __init__(self, name: str, path: str, dateAccessed : int = None, pinned : bool = False):
|
||||||
|
self.name = name
|
||||||
|
self.path = path
|
||||||
|
self.dateAccessed = dateAccessed
|
||||||
|
self.pinned = pinned
|
||||||
|
|
||||||
|
if (self.dateAccessed is None):
|
||||||
|
self.dateAccessed = int(time.time())
|
||||||
|
|
||||||
|
"""
|
||||||
|
Creates new instance of RecentProject from a dictionary.
|
||||||
|
If the dateAccessed and pinned fields are strings, they are parsed.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError if date cannot be parsed.
|
||||||
|
"""
|
||||||
|
@staticmethod
|
||||||
|
def fromDictionary(data : dict) -> 'RecentProject':
|
||||||
|
name = data['name']
|
||||||
|
path = data['path']
|
||||||
|
dateAccessed = data['dateAccessed']
|
||||||
|
pinned = data['pinned']
|
||||||
|
|
||||||
|
if isinstance(dateAccessed, str):
|
||||||
|
dateAccessed = int(dateAccessed)
|
||||||
|
|
||||||
|
if isinstance(pinned, str):
|
||||||
|
pinned = pinned.lower() in [ 'yes', 'y', 'true', '1', 'on' ]
|
||||||
|
|
||||||
|
return RecentProject(name, path, dateAccessed, pinned)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Serialize to dictionary.
|
||||||
|
"""
|
||||||
|
def toDictionary(self) -> dict:
|
||||||
|
return {
|
||||||
|
"name" : self.name,
|
||||||
|
"path" : self.path,
|
||||||
|
"dateAccessed" : self.dateAccessed,
|
||||||
|
"pinned" : self.pinned
|
||||||
|
}
|
@ -3,4 +3,6 @@ APP_VERSION = "1.0"
|
|||||||
APP_AUTHOR = "Tiberiu Chibici"
|
APP_AUTHOR = "Tiberiu Chibici"
|
||||||
APP_AUTHOR_SHORT = "TibiCh"
|
APP_AUTHOR_SHORT = "TibiCh"
|
||||||
|
|
||||||
|
PROJECT_EXTENSION = "emproj"
|
||||||
|
|
||||||
DEBUG = 1
|
DEBUG = 1
|
17460
resources_rc.py
17460
resources_rc.py
File diff suppressed because it is too large
Load Diff
1
storage/__init__.py
Normal file
1
storage/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .appdata_storage import AppDataStorage
|
@ -2,14 +2,15 @@ import appdirs
|
|||||||
import os
|
import os
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
import csv
|
import csv
|
||||||
|
from typing import Iterable
|
||||||
|
|
||||||
from properties import config
|
from properties import config
|
||||||
|
from model import RecentProject
|
||||||
|
|
||||||
class AppDataStorage(object):
|
class AppDataStorage(object):
|
||||||
|
|
||||||
SETTINGS_FILE = "config.ini"
|
SETTINGS_FILE = "config.ini"
|
||||||
RECENT_PROJECTS_FILE = "recent.cfg"
|
RECENT_PROJECTS_FILE = "recent.cfg"
|
||||||
RECENT_PROJECTS_FIELDS = ["path", "name", "date", "pinned"]
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__appDataPath = appdirs.user_data_dir(config.APP_NAME, config.APP_AUTHOR_SHORT, config.APP_VERSION)
|
self.__appDataPath = appdirs.user_data_dir(config.APP_NAME, config.APP_AUTHOR_SHORT, config.APP_VERSION)
|
||||||
@ -30,20 +31,33 @@ class AppDataStorage(object):
|
|||||||
def writeSettings(self, settings):
|
def writeSettings(self, settings):
|
||||||
pass # todo: finish this
|
pass # todo: finish this
|
||||||
|
|
||||||
def __parseRow(self, row):
|
"""
|
||||||
row['date'] = int(row['date'])
|
Reads recent projects list.
|
||||||
row['pinned'] = row['pinned'].lower() in ['true', 'yes', '1', 'on']
|
|
||||||
return row
|
|
||||||
|
|
||||||
def readRecentProjects(self):
|
Returns:
|
||||||
|
list of recent projects
|
||||||
|
"""
|
||||||
|
def readRecentProjects(self) -> Iterable[RecentProject]:
|
||||||
if (os.path.exists(self.__recentProjectsPath)):
|
if (os.path.exists(self.__recentProjectsPath)):
|
||||||
with open(self.__recentProjectsPath, 'r') as recentProjectsFile:
|
with open(self.__recentProjectsPath, 'r') as recentProjectsFile:
|
||||||
csvreader = csv.DictReader(recentProjectsFile, fieldnames=AppDataStorage.RECENT_PROJECTS_FIELDS)
|
csvreader = csv.DictReader(recentProjectsFile, fieldnames=RecentProject.DICT_FIELDS)
|
||||||
for row in csvreader:
|
for row in csvreader:
|
||||||
yield self.__parseRow(row)
|
try:
|
||||||
|
yield RecentProject.fromDictionary(row)
|
||||||
|
except ValueError:
|
||||||
|
print("Recent projects parse error - invalid date.", row)
|
||||||
|
except KeyError:
|
||||||
|
print("Recent projects parse error - fields not valid.", row)
|
||||||
|
|
||||||
def writeRecentProjects(self, items):
|
"""
|
||||||
|
Writes a list of recent projects.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
items: list of RecentProjects
|
||||||
|
"""
|
||||||
|
def writeRecentProjects(self, items : Iterable[RecentProject]) -> None:
|
||||||
self.__createPath(self.__recentProjectsPath)
|
self.__createPath(self.__recentProjectsPath)
|
||||||
with open(self.__recentProjectsPath, 'w') as recentProjectsFile:
|
with open(self.__recentProjectsPath, 'w') as recentProjectsFile:
|
||||||
csvwriter = csv.DictWriter(recentProjectsFile, AppDataStorage.RECENT_PROJECTS_FIELDS)
|
csvwriter = csv.DictWriter(recentProjectsFile, RecentProject.DICT_FIELDS)
|
||||||
csvwriter.writerows(items)
|
for item in items:
|
||||||
|
csvwriter.writerow(item.toDictionary())
|
@ -1,15 +1,20 @@
|
|||||||
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QWidget
|
import traceback
|
||||||
|
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QWidget, QApplication, QMessageBox
|
||||||
|
from PyQt5.QtCore import QTimer
|
||||||
|
|
||||||
|
from model import Project
|
||||||
|
from business import ProjectManager
|
||||||
from ui.project.project_panel import ProjectPanel
|
from ui.project.project_panel import ProjectPanel
|
||||||
|
from ui.project.new_project_dialog import NewProjectDialog
|
||||||
from ui.welcome.welcome_dialog import WelcomeDialog
|
from ui.welcome.welcome_dialog import WelcomeDialog
|
||||||
|
|
||||||
class MainWindow(QMainWindow):
|
class MainWindow(QMainWindow):
|
||||||
|
|
||||||
def __init__(self, projectManager):
|
def __init__(self, projectManager : ProjectManager):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.__projectManager = projectManager
|
self.__projectManager = projectManager
|
||||||
self.setupUi()
|
self.setupUi()
|
||||||
self.initializeApp()
|
QTimer.singleShot(0, self.showWelcomeDialog)
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
self.projectPanel = ProjectPanel()
|
self.projectPanel = ProjectPanel()
|
||||||
@ -22,10 +27,28 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
self.setCentralWidget(cwidget)
|
self.setCentralWidget(cwidget)
|
||||||
|
|
||||||
def initializeApp(self):
|
def showWelcomeDialog(self):
|
||||||
|
|
||||||
# Show welcome dialog
|
# Show welcome dialog
|
||||||
welcome = WelcomeDialog(self.__projectManager)
|
welcome = WelcomeDialog(self.__projectManager, self)
|
||||||
res = welcome.exec()
|
if welcome.exec() > 0:
|
||||||
|
if welcome.resultAction == WelcomeDialog.NEW_PROJECT:
|
||||||
|
self.newProject()
|
||||||
|
elif welcome.resultAction == WelcomeDialog.OPEN_PROJECT:
|
||||||
|
self.openProject(welcome.projectToOpen)
|
||||||
|
|
||||||
print("Dialog result:", res)
|
def newProject(self):
|
||||||
|
dialog = NewProjectDialog(self.__projectManager, self)
|
||||||
|
if dialog.exec() > 0:
|
||||||
|
self.loadProject(dialog.project)
|
||||||
|
|
||||||
|
def openProject(self, projectPath : str = None):
|
||||||
|
try:
|
||||||
|
project = self.__projectManager.openProject(projectPath)
|
||||||
|
except Exception as ex:
|
||||||
|
print("Failed to open project: ", traceback.format_exc())
|
||||||
|
QMessageBox.critical(self,
|
||||||
|
self.tr('An error occurred'),
|
||||||
|
self.tr('The project could not be open.'))
|
||||||
|
|
||||||
|
def loadProject(self, project : Project):
|
||||||
|
pass
|
61
ui/project/new_project_dialog.py
Normal file
61
ui/project/new_project_dialog.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import traceback
|
||||||
|
from PyQt5.QtWidgets import QDialog, QWidget, QDialogButtonBox, QFileDialog, QPushButton, QMessageBox
|
||||||
|
|
||||||
|
from model import Project
|
||||||
|
from business import ProjectManager
|
||||||
|
from properties.config import PROJECT_EXTENSION
|
||||||
|
from ui.project.new_project_dialog_ui import Ui_NewProjectDialog
|
||||||
|
|
||||||
|
class NewProjectDialog(QDialog):
|
||||||
|
|
||||||
|
def __init__(self, projectManager : ProjectManager, parent : QWidget = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.__projectManager = projectManager
|
||||||
|
self.project : Project = None
|
||||||
|
self.setupUi()
|
||||||
|
self.setupActions()
|
||||||
|
self.validate()
|
||||||
|
|
||||||
|
def setupUi(self):
|
||||||
|
self.ui = Ui_NewProjectDialog()
|
||||||
|
self.ui.setupUi(self)
|
||||||
|
self.__buttonOk : QPushButton = self.ui.buttonBox.button(QDialogButtonBox.Ok)
|
||||||
|
|
||||||
|
def setupActions(self):
|
||||||
|
self.ui.buttonBrowse.pressed.connect(self.browsePressed)
|
||||||
|
self.ui.textProjectPath.textChanged.connect(self.projectPathChanged)
|
||||||
|
self.ui.buttonBox.accepted.connect(self.okPressed)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
valid = True
|
||||||
|
if not self.ui.textProjectPath.text():
|
||||||
|
valid = False
|
||||||
|
self.__buttonOk.setEnabled(valid)
|
||||||
|
|
||||||
|
def browsePressed(self):
|
||||||
|
path = QFileDialog.getSaveFileName(
|
||||||
|
self,
|
||||||
|
self.tr('New project'),
|
||||||
|
'',
|
||||||
|
self.tr(f'Project files (*.{PROJECT_EXTENSION});;All files (*.*)'))
|
||||||
|
|
||||||
|
if path[0]:
|
||||||
|
self.ui.textProjectPath.setText(path[0])
|
||||||
|
|
||||||
|
def projectPathChanged(self):
|
||||||
|
self.validate()
|
||||||
|
|
||||||
|
def okPressed(self):
|
||||||
|
try:
|
||||||
|
path = self.ui.textProjectPath.text()
|
||||||
|
self.project = self.__projectManager.newProject(path)
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
print("Failed to create project: ", traceback.format_exc())
|
||||||
|
QMessageBox.critical(self,
|
||||||
|
self.tr('An error occurred'),
|
||||||
|
self.tr('The project could not be created in the given location.'))
|
||||||
|
|
||||||
|
|
||||||
|
|
239
ui/project/new_project_dialog.ui
Normal file
239
ui/project/new_project_dialog.ui
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>NewProjectDialog</class>
|
||||||
|
<widget class="QDialog" name="NewProjectDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>486</width>
|
||||||
|
<height>299</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>New project</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="_panelProjectPath" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="labelProjectPath">
|
||||||
|
<property name="text">
|
||||||
|
<string>Project path:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="textProjectPath">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buttonBrowse">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Browse...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupVideoSettings">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>2</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Video settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="labelColorDepth">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>110</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Color depth:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="comboColorDepth">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>150</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>8 bits/channel</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>16 bits/channel</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>32 bits/channel (float)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="labelColorSpace">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>110</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Color space:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="comboColorSpace">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>sRGB</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupAudioSettings">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Audio settings</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="labelSampleRate">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>110</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sample rate:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="comboSampleRate">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>32 kHz</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>44.1 kHz</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>48 kHz</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>88.2 kHz</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>96 kHz</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>192 kHz</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>NewProjectDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
124
ui/project/new_project_dialog_ui.py
Normal file
124
ui/project/new_project_dialog_ui.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'ui/project/new_project_dialog.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.10.1
|
||||||
|
#
|
||||||
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
class Ui_NewProjectDialog(object):
|
||||||
|
def setupUi(self, NewProjectDialog):
|
||||||
|
NewProjectDialog.setObjectName("NewProjectDialog")
|
||||||
|
NewProjectDialog.resize(486, 299)
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout(NewProjectDialog)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self._panelProjectPath = QtWidgets.QWidget(NewProjectDialog)
|
||||||
|
self._panelProjectPath.setObjectName("_panelProjectPath")
|
||||||
|
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self._panelProjectPath)
|
||||||
|
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||||
|
self.labelProjectPath = QtWidgets.QLabel(self._panelProjectPath)
|
||||||
|
self.labelProjectPath.setObjectName("labelProjectPath")
|
||||||
|
self.horizontalLayout_3.addWidget(self.labelProjectPath)
|
||||||
|
self.textProjectPath = QtWidgets.QLineEdit(self._panelProjectPath)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.textProjectPath.sizePolicy().hasHeightForWidth())
|
||||||
|
self.textProjectPath.setSizePolicy(sizePolicy)
|
||||||
|
self.textProjectPath.setObjectName("textProjectPath")
|
||||||
|
self.horizontalLayout_3.addWidget(self.textProjectPath)
|
||||||
|
self.buttonBrowse = QtWidgets.QPushButton(self._panelProjectPath)
|
||||||
|
self.buttonBrowse.setObjectName("buttonBrowse")
|
||||||
|
self.horizontalLayout_3.addWidget(self.buttonBrowse)
|
||||||
|
self.verticalLayout.addWidget(self._panelProjectPath)
|
||||||
|
self.groupVideoSettings = QtWidgets.QGroupBox(NewProjectDialog)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(2)
|
||||||
|
sizePolicy.setHeightForWidth(self.groupVideoSettings.sizePolicy().hasHeightForWidth())
|
||||||
|
self.groupVideoSettings.setSizePolicy(sizePolicy)
|
||||||
|
self.groupVideoSettings.setObjectName("groupVideoSettings")
|
||||||
|
self.formlayout = QtWidgets.QFormLayout(self.groupVideoSettings)
|
||||||
|
self.formlayout.setContentsMargins(20, -1, 20, -1)
|
||||||
|
self.formlayout.setObjectName("formlayout")
|
||||||
|
self.labelColorDepth = QtWidgets.QLabel(self.groupVideoSettings)
|
||||||
|
self.labelColorDepth.setMinimumSize(QtCore.QSize(110, 0))
|
||||||
|
self.labelColorDepth.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.labelColorDepth.setObjectName("labelColorDepth")
|
||||||
|
self.formlayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.labelColorDepth)
|
||||||
|
self.comboColorDepth = QtWidgets.QComboBox(self.groupVideoSettings)
|
||||||
|
self.comboColorDepth.setMinimumSize(QtCore.QSize(150, 0))
|
||||||
|
self.comboColorDepth.setObjectName("comboColorDepth")
|
||||||
|
self.comboColorDepth.addItem("")
|
||||||
|
self.comboColorDepth.addItem("")
|
||||||
|
self.comboColorDepth.addItem("")
|
||||||
|
self.formlayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.comboColorDepth)
|
||||||
|
self.labelColorSpace = QtWidgets.QLabel(self.groupVideoSettings)
|
||||||
|
self.labelColorSpace.setMinimumSize(QtCore.QSize(110, 0))
|
||||||
|
self.labelColorSpace.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.labelColorSpace.setObjectName("labelColorSpace")
|
||||||
|
self.formlayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.labelColorSpace)
|
||||||
|
self.comboColorSpace = QtWidgets.QComboBox(self.groupVideoSettings)
|
||||||
|
self.comboColorSpace.setObjectName("comboColorSpace")
|
||||||
|
self.comboColorSpace.addItem("")
|
||||||
|
self.formlayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.comboColorSpace)
|
||||||
|
self.verticalLayout.addWidget(self.groupVideoSettings)
|
||||||
|
self.groupAudioSettings = QtWidgets.QGroupBox(NewProjectDialog)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(1)
|
||||||
|
sizePolicy.setHeightForWidth(self.groupAudioSettings.sizePolicy().hasHeightForWidth())
|
||||||
|
self.groupAudioSettings.setSizePolicy(sizePolicy)
|
||||||
|
self.groupAudioSettings.setObjectName("groupAudioSettings")
|
||||||
|
self.formLayout_2 = QtWidgets.QFormLayout(self.groupAudioSettings)
|
||||||
|
self.formLayout_2.setContentsMargins(20, -1, 20, -1)
|
||||||
|
self.formLayout_2.setObjectName("formLayout_2")
|
||||||
|
self.labelSampleRate = QtWidgets.QLabel(self.groupAudioSettings)
|
||||||
|
self.labelSampleRate.setMinimumSize(QtCore.QSize(110, 0))
|
||||||
|
self.labelSampleRate.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.labelSampleRate.setObjectName("labelSampleRate")
|
||||||
|
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.labelSampleRate)
|
||||||
|
self.comboSampleRate = QtWidgets.QComboBox(self.groupAudioSettings)
|
||||||
|
self.comboSampleRate.setObjectName("comboSampleRate")
|
||||||
|
self.comboSampleRate.addItem("")
|
||||||
|
self.comboSampleRate.addItem("")
|
||||||
|
self.comboSampleRate.addItem("")
|
||||||
|
self.comboSampleRate.addItem("")
|
||||||
|
self.comboSampleRate.addItem("")
|
||||||
|
self.comboSampleRate.addItem("")
|
||||||
|
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.comboSampleRate)
|
||||||
|
self.verticalLayout.addWidget(self.groupAudioSettings)
|
||||||
|
self.buttonBox = QtWidgets.QDialogButtonBox(NewProjectDialog)
|
||||||
|
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||||
|
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
|
||||||
|
self.buttonBox.setObjectName("buttonBox")
|
||||||
|
self.verticalLayout.addWidget(self.buttonBox)
|
||||||
|
|
||||||
|
self.retranslateUi(NewProjectDialog)
|
||||||
|
self.comboSampleRate.setCurrentIndex(2)
|
||||||
|
self.buttonBox.rejected.connect(NewProjectDialog.reject)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(NewProjectDialog)
|
||||||
|
|
||||||
|
def retranslateUi(self, NewProjectDialog):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
NewProjectDialog.setWindowTitle(_translate("NewProjectDialog", "New project"))
|
||||||
|
self.labelProjectPath.setText(_translate("NewProjectDialog", "Project path:"))
|
||||||
|
self.buttonBrowse.setText(_translate("NewProjectDialog", "&Browse..."))
|
||||||
|
self.groupVideoSettings.setTitle(_translate("NewProjectDialog", "Video settings"))
|
||||||
|
self.labelColorDepth.setText(_translate("NewProjectDialog", "Color depth:"))
|
||||||
|
self.comboColorDepth.setItemText(0, _translate("NewProjectDialog", "8 bits/channel"))
|
||||||
|
self.comboColorDepth.setItemText(1, _translate("NewProjectDialog", "16 bits/channel"))
|
||||||
|
self.comboColorDepth.setItemText(2, _translate("NewProjectDialog", "32 bits/channel (float)"))
|
||||||
|
self.labelColorSpace.setText(_translate("NewProjectDialog", "Color space:"))
|
||||||
|
self.comboColorSpace.setItemText(0, _translate("NewProjectDialog", "sRGB"))
|
||||||
|
self.groupAudioSettings.setTitle(_translate("NewProjectDialog", "Audio settings"))
|
||||||
|
self.labelSampleRate.setText(_translate("NewProjectDialog", "Sample rate:"))
|
||||||
|
self.comboSampleRate.setItemText(0, _translate("NewProjectDialog", "32 kHz"))
|
||||||
|
self.comboSampleRate.setItemText(1, _translate("NewProjectDialog", "44.1 kHz"))
|
||||||
|
self.comboSampleRate.setItemText(2, _translate("NewProjectDialog", "48 kHz"))
|
||||||
|
self.comboSampleRate.setItemText(3, _translate("NewProjectDialog", "88.2 kHz"))
|
||||||
|
self.comboSampleRate.setItemText(4, _translate("NewProjectDialog", "96 kHz"))
|
||||||
|
self.comboSampleRate.setItemText(5, _translate("NewProjectDialog", "192 kHz"))
|
||||||
|
|
0
ui/welcome/__init__.py
Normal file
0
ui/welcome/__init__.py
Normal file
@ -1,72 +0,0 @@
|
|||||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QToolButton, QLayout
|
|
||||||
from PyQt5.QtCore import pyqtSignal
|
|
||||||
from PyQt5.QtGui import QFont
|
|
||||||
|
|
||||||
class RecentProjectWidget(QWidget):
|
|
||||||
|
|
||||||
deleted = pyqtSignal()
|
|
||||||
pinned = pyqtSignal(bool)
|
|
||||||
|
|
||||||
def __init__(self, recentProject):
|
|
||||||
super().__init__()
|
|
||||||
self.project = recentProject
|
|
||||||
self.__selected = False
|
|
||||||
self.setupUi()
|
|
||||||
self.setupActions()
|
|
||||||
self.__setProject(recentProject)
|
|
||||||
self.setSelected(False)
|
|
||||||
|
|
||||||
def setupUi(self):
|
|
||||||
layout = QHBoxLayout()
|
|
||||||
|
|
||||||
# label
|
|
||||||
self.__text = QLabel()
|
|
||||||
layout.addWidget(self.__text)
|
|
||||||
|
|
||||||
# space
|
|
||||||
layout.addStretch()
|
|
||||||
|
|
||||||
# pin button
|
|
||||||
self.__pin_button = QToolButton()
|
|
||||||
self.__pin_button.setFont(QFont("Font Awesome 5 Free"))
|
|
||||||
self.__pin_button.setText("\uf08d")
|
|
||||||
self.__pin_button.setCheckable(True)
|
|
||||||
layout.addWidget(self.__pin_button)
|
|
||||||
|
|
||||||
# delete button
|
|
||||||
self.__del_button = QToolButton()
|
|
||||||
self.__del_button.setFont(QFont("Font Awesome 5 Free"))
|
|
||||||
self.__del_button.setText("\uf2ed")
|
|
||||||
layout.addWidget(self.__del_button)
|
|
||||||
|
|
||||||
# pin indicator
|
|
||||||
self.__pin_indicator = QLabel()
|
|
||||||
self.__pin_indicator.setFont(QFont("Font Awesome 5 Free"))
|
|
||||||
self.__pin_indicator.setText("\uf08d")
|
|
||||||
layout.addWidget(self.__pin_indicator)
|
|
||||||
|
|
||||||
# done
|
|
||||||
layout.setSizeConstraint(QLayout.SetMinimumSize)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
def setupActions(self):
|
|
||||||
self.__pin_button.toggled.connect(self.__pinnedToggled)
|
|
||||||
self.__del_button.pressed.connect(self.deleted)
|
|
||||||
|
|
||||||
def setSelected(self, selected = True):
|
|
||||||
self.__selected = selected
|
|
||||||
self.__pin_button.setVisible(selected)
|
|
||||||
self.__del_button.setVisible(selected)
|
|
||||||
self.__pin_indicator.setVisible(not self.__selected and self.__pin_button.isChecked())
|
|
||||||
|
|
||||||
def setPinned(self, isPinned = True):
|
|
||||||
self.__pin_button.setChecked(isPinned)
|
|
||||||
|
|
||||||
def __setProject(self, project):
|
|
||||||
self.__text = project['name']
|
|
||||||
self.setPinned(project['pinned'])
|
|
||||||
|
|
||||||
def __pinnedToggled(self, isPinned):
|
|
||||||
self.__pin_indicator.setVisible(not self.__selected and isPinned)
|
|
||||||
if (isPinned != self.project['pinned']):
|
|
||||||
self.pinned.emit(isPinned)
|
|
@ -1,91 +1,171 @@
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QDialog, QCommandLinkButton, QListWidgetItem
|
from PyQt5.QtWidgets import QDialog, QCommandLinkButton, QListWidgetItem, QFileDialog, QWidget, QHBoxLayout, QLabel, QToolButton, QLayout
|
||||||
from PyQt5.QtGui import QPixmap
|
from PyQt5.QtGui import QPixmap, QResizeEvent, QFont
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt, pyqtSignal
|
||||||
|
|
||||||
from ui.welcome.recent_project import RecentProjectWidget
|
|
||||||
from ui.welcome.welcome_dialog_ui import Ui_WelcomeDialog
|
from ui.welcome.welcome_dialog_ui import Ui_WelcomeDialog
|
||||||
|
from model import RecentProject
|
||||||
|
from business import ProjectManager
|
||||||
|
from properties.config import PROJECT_EXTENSION
|
||||||
|
|
||||||
|
|
||||||
|
class RecentProjectListWidget(QWidget):
|
||||||
|
|
||||||
|
deleted = pyqtSignal()
|
||||||
|
pinned = pyqtSignal(bool)
|
||||||
|
|
||||||
|
def __init__(self, recentProject : RecentProject):
|
||||||
|
super().__init__()
|
||||||
|
self.project = recentProject
|
||||||
|
self.__selected = False
|
||||||
|
self.setupUi()
|
||||||
|
self.setupActions()
|
||||||
|
self.__setProject(recentProject)
|
||||||
|
self.setSelected(False)
|
||||||
|
|
||||||
|
def setupUi(self):
|
||||||
|
layout = QHBoxLayout()
|
||||||
|
|
||||||
|
# label
|
||||||
|
self.__text = QLabel()
|
||||||
|
layout.addWidget(self.__text)
|
||||||
|
|
||||||
|
# space
|
||||||
|
layout.addStretch()
|
||||||
|
|
||||||
|
# pin button
|
||||||
|
self.__pin_button = QToolButton()
|
||||||
|
self.__pin_button.setFont(QFont("Font Awesome 5 Free"))
|
||||||
|
self.__pin_button.setText("\uf08d")
|
||||||
|
self.__pin_button.setCheckable(True)
|
||||||
|
layout.addWidget(self.__pin_button)
|
||||||
|
|
||||||
|
# delete button
|
||||||
|
self.__del_button = QToolButton()
|
||||||
|
self.__del_button.setFont(QFont("Font Awesome 5 Free"))
|
||||||
|
self.__del_button.setText("\uf2ed")
|
||||||
|
layout.addWidget(self.__del_button)
|
||||||
|
|
||||||
|
# pin indicator
|
||||||
|
self.__pin_indicator = QLabel()
|
||||||
|
self.__pin_indicator.setFont(QFont("Font Awesome 5 Free"))
|
||||||
|
self.__pin_indicator.setText("\uf08d")
|
||||||
|
layout.addWidget(self.__pin_indicator)
|
||||||
|
|
||||||
|
# done
|
||||||
|
layout.setSizeConstraint(QLayout.SetMinimumSize)
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
def setupActions(self):
|
||||||
|
self.__pin_button.toggled.connect(self.__pinnedToggled)
|
||||||
|
self.__del_button.pressed.connect(self.deleted)
|
||||||
|
|
||||||
|
def setSelected(self, selected : bool = True):
|
||||||
|
self.__selected = selected
|
||||||
|
self.__pin_button.setVisible(selected)
|
||||||
|
self.__del_button.setVisible(selected)
|
||||||
|
self.__pin_indicator.setVisible(not self.__selected and self.__pin_button.isChecked())
|
||||||
|
|
||||||
|
def setPinned(self, isPinned : bool = True):
|
||||||
|
self.__pin_button.setChecked(isPinned)
|
||||||
|
|
||||||
|
def __setProject(self, project : RecentProject):
|
||||||
|
self.__text = project.name
|
||||||
|
self.setPinned(project.pinned)
|
||||||
|
|
||||||
|
def __pinnedToggled(self, isPinned : bool):
|
||||||
|
self.__pin_indicator.setVisible(not self.__selected and isPinned)
|
||||||
|
if (isPinned != self.project.pinned):
|
||||||
|
self.pinned.emit(isPinned)
|
||||||
|
|
||||||
|
|
||||||
class WelcomeDialog(QDialog):
|
class WelcomeDialog(QDialog):
|
||||||
NEW_PROJECT = 0
|
NEW_PROJECT = 0
|
||||||
OPEN_PROJECT = 1
|
OPEN_PROJECT = 1
|
||||||
|
|
||||||
def __init__(self, projectManager):
|
def __init__(self, projectManager : ProjectManager, parent : QWidget = None):
|
||||||
super().__init__()
|
super().__init__(parent)
|
||||||
self.__projectManager = projectManager
|
self.__projectManager = projectManager
|
||||||
self.resultAction = None
|
self.resultAction : int = None
|
||||||
self.projectToOpen = None
|
self.projectToOpen : str = None
|
||||||
self.setResult(QDialog.Rejected)
|
self.setResult(QDialog.Rejected)
|
||||||
self.setupUi()
|
self.setupUi()
|
||||||
self.setupActions()
|
self.setupActions()
|
||||||
self.populateRecentProjects()
|
self.populateRecentProjects()
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self) -> None:
|
||||||
self.ui = Ui_WelcomeDialog()
|
self.ui = Ui_WelcomeDialog()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
self.image = QPixmap(self.ui.picture.pixmap())
|
self.image = QPixmap(self.ui.picture.pixmap())
|
||||||
|
|
||||||
def setupActions(self):
|
def setupActions(self) -> None:
|
||||||
self.ui.buttonNewProject.pressed.connect(self.newProjectPressed)
|
self.ui.buttonNewProject.pressed.connect(self.newProjectPressed)
|
||||||
self.ui.buttonOpenProject.pressed.connect(self.openProjectPressed)
|
self.ui.buttonOpenProject.pressed.connect(self.openProjectPressed)
|
||||||
self.ui.listRecentProjects.currentItemChanged.connect(self.listRecentProjectsCurrentChanged)
|
self.ui.listRecentProjects.currentItemChanged.connect(self.listRecentProjectsCurrentChanged)
|
||||||
self.ui.listRecentProjects.itemActivated.connect(self.listRecentProjectsItemActivated)
|
self.ui.listRecentProjects.itemActivated.connect(self.listRecentProjectsItemActivated)
|
||||||
|
|
||||||
def resizeEvent(self, event):
|
def resizeEvent(self, event : QResizeEvent) -> None:
|
||||||
super().resizeEvent(event)
|
super().resizeEvent(event)
|
||||||
|
|
||||||
picSize = self.ui.picture.size()
|
picSize = self.ui.picture.size()
|
||||||
pic = self.image.scaled(picSize, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
|
pic = self.image.scaled(picSize, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
|
||||||
self.ui.picture.setPixmap(pic)
|
self.ui.picture.setPixmap(pic)
|
||||||
|
|
||||||
def populateRecentProjects(self):
|
def populateRecentProjects(self) -> None:
|
||||||
projects = list(self.__projectManager.getRecentProjects())
|
projects = list(self.__projectManager.getRecentProjects())
|
||||||
projects = sorted(projects, key=lambda x: (x['pinned'], x['date']), reverse=True)
|
projects = sorted(projects, key=lambda x: (x.pinned, x.dateAccessed), reverse=True)
|
||||||
|
|
||||||
for project in projects:
|
for project in projects:
|
||||||
|
|
||||||
widget = RecentProjectWidget(project)
|
widget = RecentProjectListWidget(project)
|
||||||
widget.pinned.connect(self.__projectPinned)
|
widget.pinned.connect(self.__projectPinned)
|
||||||
widget.deleted.connect(self.__projectDeleted)
|
widget.deleted.connect(self.__projectDeleted)
|
||||||
|
|
||||||
item = QListWidgetItem(project['name'])
|
item = QListWidgetItem(project.name)
|
||||||
item.setData(Qt.UserRole, project)
|
item.setData(Qt.UserRole, project)
|
||||||
item.setSizeHint(widget.sizeHint())
|
item.setSizeHint(widget.sizeHint())
|
||||||
|
|
||||||
self.ui.listRecentProjects.addItem(item)
|
self.ui.listRecentProjects.addItem(item)
|
||||||
self.ui.listRecentProjects.setItemWidget(item, widget)
|
self.ui.listRecentProjects.setItemWidget(item, widget)
|
||||||
|
|
||||||
def newProjectPressed(self):
|
def newProjectPressed(self) -> None:
|
||||||
self.resultAction = WelcomeDialog.NEW_PROJECT
|
self.resultAction = WelcomeDialog.NEW_PROJECT
|
||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
def openProjectPressed(self):
|
def openProjectPressed(self) -> None:
|
||||||
# TODO: show open dialog
|
proj = QFileDialog.getOpenFileName(
|
||||||
self.resultAction = WelcomeDialog.OPEN_PROJECT
|
self,
|
||||||
self.accept()
|
self.tr('Open project'),
|
||||||
|
'',
|
||||||
|
self.tr(f'Project files (*.{PROJECT_EXTENSION});;All files (*.*)'))
|
||||||
|
|
||||||
def listRecentProjectsCurrentChanged(self, current, previous):
|
if proj[0]:
|
||||||
|
self.projectToOpen = proj[0]
|
||||||
|
self.resultAction = WelcomeDialog.OPEN_PROJECT
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
def listRecentProjectsCurrentChanged(self, current : QListWidgetItem, previous : QListWidgetItem) -> None:
|
||||||
if not current is None:
|
if not current is None:
|
||||||
recentProjectWidget = self.ui.listRecentProjects.itemWidget(current)
|
RecentProjectListWidget = self.ui.listRecentProjects.itemWidget(current)
|
||||||
recentProjectWidget.setSelected(True)
|
RecentProjectListWidget.setSelected(True)
|
||||||
|
|
||||||
if not previous is None:
|
if not previous is None:
|
||||||
recentProjectWidget = self.ui.listRecentProjects.itemWidget(previous)
|
RecentProjectListWidget = self.ui.listRecentProjects.itemWidget(previous)
|
||||||
if not recentProjectWidget is None:
|
if not RecentProjectListWidget is None:
|
||||||
recentProjectWidget.setSelected(False)
|
RecentProjectListWidget.setSelected(False)
|
||||||
|
|
||||||
def listRecentProjectsItemActivated(self, item):
|
def listRecentProjectsItemActivated(self, item : QListWidgetItem) -> None:
|
||||||
project = item.data(Qt.UserRole)
|
project : RecentProject = item.data(Qt.UserRole)
|
||||||
self.resultAction = WelcomeDialog.OPEN_PROJECT
|
self.resultAction = WelcomeDialog.OPEN_PROJECT
|
||||||
self.projectToOpen = project['path']
|
self.projectToOpen = project.path
|
||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
def __projectPinned(self, isPinned):
|
def __projectPinned(self, isPinned : bool) -> None:
|
||||||
project = self.ui.listRecentProjects.currentItem().data(Qt.UserRole)
|
project = self.ui.listRecentProjects.currentItem().data(Qt.UserRole)
|
||||||
self.__projectManager.pinRecentProject(project, isPinned)
|
self.__projectManager.pinRecentProject(project, isPinned)
|
||||||
|
|
||||||
def __projectDeleted(self):
|
def __projectDeleted(self) -> None:
|
||||||
project = self.ui.listRecentProjects.currentItem().data(Qt.UserRole)
|
project = self.ui.listRecentProjects.currentItem().data(Qt.UserRole)
|
||||||
try:
|
try:
|
||||||
self.__projectManager.deleteRecentProject(project)
|
self.__projectManager.deleteRecentProject(project)
|
||||||
|
Loading…
Reference in New Issue
Block a user