Started work on Ember

This commit is contained in:
Tiberiu Chibici 2018-07-28 23:56:23 +03:00
commit ac582a8b0b
32 changed files with 239149 additions and 0 deletions

105
.gitignore vendored Normal file
View File

@ -0,0 +1,105 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

30
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}"
},
{
"name": "Python: Attach",
"type": "python",
"request": "attach",
"localRoot": "${workspaceFolder}",
"remoteRoot": "${workspaceFolder}",
"port": 3000,
"secret": "my_secret",
"host": "localhost"
},
{
"name": "Python: main.py",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/main.py"
},
]
}

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"python.pythonPath": "/usr/bin/python3"
}

19
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Build Resources",
"type": "process",
"command": "make",
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

19
Makefile Normal file
View File

@ -0,0 +1,19 @@
RESOURCES=$(shell find . -name '*.qrc')
RESOURCES_OUT=$(RESOURCES:.qrc=_rc.py)
UI=$(shell find . -name '*.ui')
UI_OUT=$(UI:.ui=_ui.py)
all: $(RESOURCES_OUT) $(UI_OUT)
clean:
rm ${UI_OUT}
rm ${RESOURCES_OUT}
%_rc.py: %.qrc
pyrcc5 $< -o $@
%_ui.py: %.ui
pyuic5 $< -o $@
.PHONY: all clean

0
business/__init__.py Normal file
View File

View File

@ -0,0 +1,42 @@
from model.project import Project
class ProjectManager(object):
def __init__(self, appDataStorage):
self.__appDataStorage = appDataStorage
self.__recentProjects = []
def getRecentProjects(self):
if self.__recentProjects is None:
self.__recentProjects = list(self.__appDataStorage.readRecentProjects())
return self.__recentProjects
def pinRecentProject(self, entry, isPinned = True):
entry['pinned'] = isPinned
self.__appDataStorage.writeRecentProjects(self.__recentProjects)
def debug_populateRecentProjects(self):
self.__recentProjects.append({
'name' : 'Debug project',
'path' : '/home/tibi/Videos/project.pro',
'pinned' : True,
'date' : 1
})
self.__recentProjects.append({
'name' : 'Debug project 2',
'path' : '/home/tibi/Videos/project2.pro',
'pinned' : False,
'date' : 2
})
self.__recentProjects.append({
'name' : 'Debug project 3',
'path' : '/home/tibi/Videos/project3.pro',
'pinned' : False,
'date' : 3
})
self.__recentProjects.append({
'name' : 'Debug project 4',
'path' : '/home/tibi/Videos/project4.pro',
'pinned' : False,
'date' : 4
})

View File

@ -0,0 +1,34 @@
Font Awesome Free License
-------------------------
Font Awesome Free is free, open source, and GPL friendly. You can use it for
commercial projects, open source projects, or really almost whatever you want.
Full Font Awesome Free license: https://fontawesome.com/license.
# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
In the Font Awesome Free download, the CC BY 4.0 license applies to all icons
packaged as SVG and JS file types.
# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)
In the Font Awesome Free download, the SIL OLF license applies to all icons
packaged as web and desktop font files.
# Code: MIT License (https://opensource.org/licenses/MIT)
In the Font Awesome Free download, the MIT license applies to all non-font and
non-icon files.
# Attribution
Attribution is required by MIT, SIL OLF, and CC BY licenses. Downloaded Font
Awesome Free files already contain embedded comments with sufficient
attribution, so you shouldn't need to do anything additional when using these
files normally.
We've kept attribution comments terse, so we ask that you do not actively work
to remove them from files, especially code. They're a great way for folks to
learn about Font Awesome.
# Brand Icons
All brand icons are trademarks of their respective owners. The use of these
trademarks does not indicate endorsement of the trademark holder by Font
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
to represent the company, product, or service to which they refer.**

Binary file not shown.

Binary file not shown.

BIN
img/charcoal-2396754.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

BIN
img/spark-959254.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

4
main.py Normal file
View File

@ -0,0 +1,4 @@
import sys
from ui.ember_application import EmberApplication
EmberApplication(sys.argv).start()

0
model/__init__.py Normal file
View File

2
model/composition.py Normal file
View File

@ -0,0 +1,2 @@
class CompositionClip(object):

7
model/project.py Normal file
View File

@ -0,0 +1,7 @@
class Project(object):
def __init__(self):
self.root_dir = None
def get_items(self):
pass

6
model/project_item.py Normal file
View File

@ -0,0 +1,6 @@
class ProjectItem(object):
def __init__(self, filename):
self.filename = filename

0
properties/__init__.py Normal file
View File

6
properties/config.py Normal file
View File

@ -0,0 +1,6 @@
APP_NAME = "Ember"
APP_VERSION = "1.0"
APP_AUTHOR = "Tiberiu Chibici"
APP_AUTHOR_SHORT = "TibiCh"
DEBUG = 1

11
resources.qrc Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/">
<!-- Fonts -->
<file alias="FontAwesome-Solid.otf">fonts/FontAwesomeSolid-5.2.otf</file>
<file alias="FontAwesome-Regular.otf">fonts/FontAwesomeRegular-5.2.otf</file>
<!-- Picture -->
<file alias="WelcomeBanner.jpg">img/charcoal-2396754.jpg</file>
</qresource>
</RCC>

238313
resources_rc.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
import appdirs
import os
from configparser import ConfigParser
import csv
from properties import config
class AppDataStorage(object):
SETTINGS_FILE = "config.ini"
RECENT_PROJECTS_FILE = "recent.cfg"
RECENT_PROJECTS_FIELDS = ["path", "name", "date", "pinned"]
def __init__(self):
self.__appDataPath = appdirs.user_data_dir(config.APP_NAME, config.APP_AUTHOR_SHORT, config.APP_VERSION)
self.__settingsPath = os.path.join(self.__appDataPath, AppDataStorage.SETTINGS_FILE)
self.__recentProjectsPath = os.path.join(self.__appDataPath, AppDataStorage.RECENT_PROJECTS_FILE)
# make missing dirs in path
def __createPath(self, path):
dir = os.path.dirname(path)
os.makedirs(dir, exist_ok=True)
def readSettings(self):
if (os.path.exists(self.__settingsPath)):
parser = ConfigParser()
parser.read(self.__settingsPath)
# todo: finish this
def writeSettings(self, settings):
pass # todo: finish this
def readRecentProjects(self):
if (os.path.exists(self.__recentProjectsPath)):
with open(self.__recentProjectsPath, 'rb') as recentProjectsFile:
csvreader = csv.DictReader(recentProjectsFile, fieldnames=AppDataStorage.RECENT_PROJECTS_FIELDS)
for row in csvreader:
yield row
def writeRecentProjects(self, items):
self.__createPath(self.__recentProjectsPath)
with open(self.__recentProjectsPath, 'wb') as recentProjectsFile:
csvwriter = csv.DictWriter(recentProjectsFile, AppDataStorage.RECENT_PROJECTS_FIELDS)
csvwriter.writerows(items)

26
ui/ember_application.py Normal file
View File

@ -0,0 +1,26 @@
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QFontDatabase
from ui.main_window import MainWindow
from business.project_manager import ProjectManager
from storage.appdata_storage import AppDataStorage
class EmberApplication(QApplication):
def __init__(self, argv):
super().__init__(argv)
def start(self):
QFontDatabase.addApplicationFont(":/FontAwesome-Solid.otf")
QFontDatabase.addApplicationFont(":/FontAwesome-Regular.otf")
# setup resources
appDataStorage = AppDataStorage()
projectManager = ProjectManager(appDataStorage)
projectManager.debug_populateRecentProjects()
# show main window
mainwindow = MainWindow(projectManager)
mainwindow.show()
exit(self.exec_())

31
ui/main_window.py Normal file
View File

@ -0,0 +1,31 @@
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QWidget
from ui.project.project_panel import ProjectPanel
from ui.welcome.welcome_dialog import WelcomeDialog
class MainWindow(QMainWindow):
def __init__(self, projectManager):
super().__init__()
self.__projectManager = projectManager
self.setupUi()
self.initializeApp()
def setupUi(self):
self.projectPanel = ProjectPanel()
layout = QVBoxLayout()
layout.addWidget(self.projectPanel)
cwidget = QWidget()
cwidget.setLayout(layout)
self.setCentralWidget(cwidget)
def initializeApp(self):
# Show welcome dialog
welcome = WelcomeDialog(self.__projectManager)
res = welcome.exec()
print("Dialog result:", res)

View File

@ -0,0 +1,12 @@
from PyQt5 import QtCore, QtWidgets, uic
import os
from ui.project.project_panel_ui import Ui_Form
class ProjectPanel(QtWidgets.QWidget):
def __init__(self):
super(ProjectPanel, self).__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>90</x>
<y>40</y>
<width>84</width>
<height>34</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>80</x>
<y>150</y>
<width>86</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_2">
<property name="geometry">
<rect>
<x>80</x>
<y>180</y>
<width>86</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/project/project_panel.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_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(90, 40, 84, 34))
self.pushButton.setObjectName("pushButton")
self.checkBox = QtWidgets.QCheckBox(Form)
self.checkBox.setGeometry(QtCore.QRect(80, 150, 86, 22))
self.checkBox.setObjectName("checkBox")
self.checkBox_2 = QtWidgets.QCheckBox(Form)
self.checkBox_2.setGeometry(QtCore.QRect(80, 180, 86, 22))
self.checkBox_2.setObjectName("checkBox_2")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.pushButton.setText(_translate("Form", "PushButton"))
self.checkBox.setText(_translate("Form", "CheckBox"))
self.checkBox_2.setText(_translate("Form", "CheckBox"))

View File

@ -0,0 +1,33 @@
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QToolButton, QLayout
from PyQt5.QtGui import QFont
class RecentProjectWidget(QWidget):
def __init__(self, recentProject):
super().__init__()
self.setupUi()
self.setProject(recentProject)
def setupUi(self):
layout = QHBoxLayout()
# label
self.__text = QLabel()
layout.addWidget(self.__text)
# space
layout.addStretch()
# pin button
self.__button = QToolButton()
self.__button.setFont(QFont("Font Awesome 5 Free"))
self.__button.setText("\uf08d")
self.__button.setCheckable(True)
layout.addWidget(self.__button)
# done
layout.setSizeConstraint(QLayout.SetMinimumSize)
self.setLayout(layout)
def setProject(self, project):
self.__text = project['name']
self.__button.setChecked(project['pinned'])

View File

@ -0,0 +1,65 @@
import os
import functools
from enum import Enum
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QWidget, QCommandLinkButton, QListWidgetItem
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
from PyQt5 import uic
from util import str_compare
from ui.welcome.recent_project import RecentProjectWidget
from ui.welcome.welcome_dialog_ui import Ui_WelcomeDialog
class WelcomeDialogResult(Enum):
NewProject = 0
OpenProject = 1
OpenRecentProject = 2
class WelcomeDialog(QDialog):
def __init__(self, projectManager):
super().__init__()
self.__projectManager = projectManager
self.__resultAction = None
self.setResult(QDialog.Rejected)
self.setupUi()
self.setupActions()
self.populateRecentProjects()
def setupUi(self):
self.ui = Ui_WelcomeDialog()
self.ui.setupUi(self)
self.image = QPixmap(self.ui.picture.pixmap())
def setupActions(self):
self.ui.buttonNewProject.pressed.connect(self.newProjectPressed)
self.ui.buttonOpenProject.pressed.connect(self.openProjectPressed)
def resizeEvent(self, event):
super().resizeEvent(event)
picSize = self.ui.picture.size()
pic = self.image.scaled(picSize, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
self.ui.picture.setPixmap(pic)
def populateRecentProjects(self):
projects = list(self.__projectManager.getRecentProjects())
projects = sorted(projects, key=lambda x: (x['pinned'], x['date']), reverse=True)
for project in projects:
item = QListWidgetItem(project['name'])
item.setData(Qt.UserRole, project)
widget = RecentProjectWidget(project)
item.setSizeHint(widget.sizeHint())
self.ui.listRecentProjects.addItem(item)
self.ui.listRecentProjects.setItemWidget(item, widget)
def newProjectPressed(self):
self.__resultAction = WelcomeDialogResult.NewProject
self.accept()
def openProjectPressed(self):
self.__resultAction = WelcomeDialogResult.OpenProject
self.accept()

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WelcomeDialog</class>
<widget class="QDialog" name="WelcomeDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>667</width>
<height>601</height>
</rect>
</property>
<property name="windowTitle">
<string>Welcome</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="picture">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>120</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../resources.qrc">:/WelcomeBanner.jpg</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QWidget" name="panelRecentProjects" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="labelRecentProjects">
<property name="font">
<font>
<pointsize>13</pointsize>
</font>
</property>
<property name="text">
<string>Recent projects</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listRecentProjects">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="panelButtons" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCommandLinkButton" name="buttonNewProject">
<property name="text">
<string>&amp;New Project</string>
</property>
<property name="description">
<string>Create a new project.</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="buttonOpenProject">
<property name="text">
<string>&amp;Open Project</string>
</property>
<property name="description">
<string>Open an existing project.</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../../resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/welcome/welcome_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_WelcomeDialog(object):
def setupUi(self, WelcomeDialog):
WelcomeDialog.setObjectName("WelcomeDialog")
WelcomeDialog.setWindowModality(QtCore.Qt.WindowModal)
WelcomeDialog.resize(667, 601)
self.verticalLayout = QtWidgets.QVBoxLayout(WelcomeDialog)
self.verticalLayout.setObjectName("verticalLayout")
self.picture = QtWidgets.QLabel(WelcomeDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.picture.sizePolicy().hasHeightForWidth())
self.picture.setSizePolicy(sizePolicy)
self.picture.setMinimumSize(QtCore.QSize(0, 120))
self.picture.setMaximumSize(QtCore.QSize(16777215, 120))
self.picture.setText("")
self.picture.setPixmap(QtGui.QPixmap(":/WelcomeBanner.jpg"))
self.picture.setScaledContents(False)
self.picture.setAlignment(QtCore.Qt.AlignCenter)
self.picture.setObjectName("picture")
self.verticalLayout.addWidget(self.picture)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.panelRecentProjects = QtWidgets.QWidget(WelcomeDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(2)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.panelRecentProjects.sizePolicy().hasHeightForWidth())
self.panelRecentProjects.setSizePolicy(sizePolicy)
self.panelRecentProjects.setObjectName("panelRecentProjects")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.panelRecentProjects)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.labelRecentProjects = QtWidgets.QLabel(self.panelRecentProjects)
font = QtGui.QFont()
font.setPointSize(13)
self.labelRecentProjects.setFont(font)
self.labelRecentProjects.setObjectName("labelRecentProjects")
self.verticalLayout_3.addWidget(self.labelRecentProjects)
self.listRecentProjects = QtWidgets.QListWidget(self.panelRecentProjects)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.listRecentProjects.sizePolicy().hasHeightForWidth())
self.listRecentProjects.setSizePolicy(sizePolicy)
self.listRecentProjects.setObjectName("listRecentProjects")
self.verticalLayout_3.addWidget(self.listRecentProjects)
self.horizontalLayout.addWidget(self.panelRecentProjects)
self.panelButtons = QtWidgets.QWidget(WelcomeDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(1)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.panelButtons.sizePolicy().hasHeightForWidth())
self.panelButtons.setSizePolicy(sizePolicy)
self.panelButtons.setObjectName("panelButtons")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.panelButtons)
self.verticalLayout_2.setObjectName("verticalLayout_2")
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding)
self.verticalLayout_2.addItem(spacerItem)
self.buttonNewProject = QtWidgets.QCommandLinkButton(self.panelButtons)
self.buttonNewProject.setObjectName("buttonNewProject")
self.verticalLayout_2.addWidget(self.buttonNewProject)
self.buttonOpenProject = QtWidgets.QCommandLinkButton(self.panelButtons)
self.buttonOpenProject.setObjectName("buttonOpenProject")
self.verticalLayout_2.addWidget(self.buttonOpenProject)
self.horizontalLayout.addWidget(self.panelButtons)
self.verticalLayout.addLayout(self.horizontalLayout)
self.retranslateUi(WelcomeDialog)
QtCore.QMetaObject.connectSlotsByName(WelcomeDialog)
def retranslateUi(self, WelcomeDialog):
_translate = QtCore.QCoreApplication.translate
WelcomeDialog.setWindowTitle(_translate("WelcomeDialog", "Welcome"))
self.labelRecentProjects.setText(_translate("WelcomeDialog", "Recent projects"))
self.buttonNewProject.setText(_translate("WelcomeDialog", "&New Project"))
self.buttonNewProject.setDescription(_translate("WelcomeDialog", "Create a new project."))
self.buttonOpenProject.setText(_translate("WelcomeDialog", "&Open Project"))
self.buttonOpenProject.setDescription(_translate("WelcomeDialog", "Open an existing project."))
import resources_rc

9
util/str_compare.py Normal file
View File

@ -0,0 +1,9 @@
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def unicode_compare_ignore_case(str1, str2):
str1 = normalize_caseless(str1)
str2 = normalize_caseless(str2)
return (str1>str2) - (str1<str2)