2021-07-31 22:49:44 +00:00
"""
2022-01-20 17:19:36 +00:00
* LogarithmPlotter - 2 D plotter software to make BODE plots , sequences and repartition functions .
2022-01-12 13:39:23 +00:00
* Copyright ( C ) 2022 Ad5001
2021-07-31 22:49:44 +00:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : / / www . gnu . org / licenses / > .
"""
2021-08-14 16:57:29 +00:00
from time import time
start_time = time ( )
2021-07-31 22:49:44 +00:00
from PySide2 . QtWidgets import QApplication , QFileDialog
from PySide2 . QtQml import QQmlApplicationEngine , qmlRegisterType
2022-01-20 17:19:36 +00:00
from PySide2 . QtCore import Qt , QObject , Signal , Slot , Property , QTranslator , QLocale , QCoreApplication
2021-07-31 22:49:44 +00:00
from PySide2 . QtGui import QIcon , QImage , QKeySequence
from PySide2 import __version__ as PySide2_version
2021-08-14 19:40:42 +00:00
from tempfile import mkstemp
2021-08-26 15:48:12 +00:00
from os import getcwd , chdir , environ , path , remove , close
2021-07-31 22:49:44 +00:00
from platform import release as os_release
from json import dumps , loads
2021-08-26 16:16:26 +00:00
from sys import platform , argv , version as sys_version , exit
2021-08-14 19:40:42 +00:00
from webbrowser import open as openWeb
# Create the temporary file for saving copied screenshots
2021-08-26 15:48:12 +00:00
fd , tmpfile = mkstemp ( suffix = ' .png ' )
2021-08-26 17:54:30 +00:00
pwd = getcwd ( )
2021-08-14 19:40:42 +00:00
2021-08-26 17:54:30 +00:00
chdir ( path . dirname ( path . realpath ( __file__ ) ) )
2021-08-16 17:50:54 +00:00
from sys import path as sys_path
2021-08-26 17:54:30 +00:00
if path . realpath ( path . join ( getcwd ( ) , " .. " ) ) not in sys_path :
sys_path . append ( path . realpath ( path . join ( getcwd ( ) , " .. " ) ) )
2021-08-16 17:50:54 +00:00
2021-08-16 20:05:51 +00:00
from LogarithmPlotter import config , native , __VERSION__
2021-08-16 17:50:54 +00:00
from LogarithmPlotter . update import check_for_updates
2021-07-31 22:49:44 +00:00
2022-01-20 17:19:36 +00:00
config . init ( )
2021-07-31 22:49:44 +00:00
def get_linux_theme ( ) :
des = {
2021-08-14 14:13:14 +00:00
" KDE " : " org.kde.desktop " ,
2021-07-31 22:49:44 +00:00
" gnome " : " default " ,
" lxqt " : " fusion " ,
" mate " : " fusion " ,
}
2021-08-14 19:40:42 +00:00
if " XDG_SESSION_DESKTOP " in environ :
return des [ environ [ " XDG_SESSION_DESKTOP " ] ] if environ [ " XDG_SESSION_DESKTOP " ] in des else " fusion "
2021-07-31 22:49:44 +00:00
else :
# Android
return " Material "
class Helper ( QObject ) :
2022-01-20 17:19:36 +00:00
def __init__ ( self , engine : QQmlApplicationEngine ) :
QObject . __init__ ( self )
self . engine = engine ;
2021-07-31 22:49:44 +00:00
@Slot ( str , str )
def write ( self , filename , filedata ) :
2021-08-26 17:54:30 +00:00
chdir ( pwd )
2021-08-14 19:40:42 +00:00
if path . exists ( path . dirname ( path . realpath ( filename ) ) ) :
2021-07-31 22:49:44 +00:00
if filename . split ( " . " ) [ - 1 ] == " lpf " :
# Add header to file
filedata = " LPFv1 " + filedata
2021-08-14 19:40:42 +00:00
f = open ( path . realpath ( filename ) , ' w ' , - 1 , ' utf8 ' )
2021-07-31 22:49:44 +00:00
f . write ( filedata )
f . close ( )
2021-08-26 17:54:30 +00:00
chdir ( path . dirname ( path . realpath ( __file__ ) ) )
2021-07-31 22:49:44 +00:00
@Slot ( str , result = str )
def load ( self , filename ) :
2021-08-26 17:54:30 +00:00
chdir ( pwd )
2021-07-31 22:49:44 +00:00
data = ' {} '
2022-01-20 17:19:36 +00:00
from PySide2 . QtWidgets import QMessageBox
2021-08-14 19:40:42 +00:00
if path . exists ( path . realpath ( filename ) ) :
f = open ( path . realpath ( filename ) , ' r ' , - 1 , ' utf8 ' )
2021-07-31 22:49:44 +00:00
data = f . read ( )
f . close ( )
try :
if data [ : 5 ] == " LPFv1 " :
# V1 version of the file
data = data [ 5 : ]
elif data [ 0 ] == " { " and " type " in loads ( data ) and loads ( data ) [ " type " ] == " logplotv1 " :
pass
else :
raise Exception ( " Invalid LogarithmPlotter file. " )
except Exception as e : # If file can't be loaded
2022-01-20 17:19:36 +00:00
QMessageBox . warning ( None , ' LogarithmPlotter ' , QCoreApplication . translate ( ' main ' , ' Could not open file " {} " : \n {} ' ) . format ( filename , e ) , QMessageBox . Ok ) # Cannot parse file
2021-07-31 22:49:44 +00:00
else :
2022-01-20 17:19:36 +00:00
QMessageBox . warning ( None , ' LogarithmPlotter ' , QCoreApplication . translate ( ' main ' , ' Could not open file: " {} " \n File does not exist. ' ) . format ( filename ) , QMessageBox . Ok ) # Cannot parse file
2021-08-26 17:54:30 +00:00
chdir ( path . dirname ( path . realpath ( __file__ ) ) )
2021-07-31 22:49:44 +00:00
return data
2022-01-23 16:31:34 +00:00
2021-07-31 22:49:44 +00:00
@Slot ( result = str )
def gettmpfile ( self ) :
2021-08-14 19:40:42 +00:00
global tmpfile
return tmpfile
2021-07-31 22:49:44 +00:00
@Slot ( )
def copyImageToClipboard ( self ) :
2021-08-14 19:40:42 +00:00
global tmpfile
2021-07-31 22:49:44 +00:00
clipboard = QApplication . clipboard ( )
2021-08-14 19:40:42 +00:00
clipboard . setImage ( QImage ( tmpfile ) )
2021-07-31 22:49:44 +00:00
@Slot ( result = str )
def getVersion ( self ) :
return __VERSION__
2021-08-14 19:40:42 +00:00
@Slot ( str , result = str )
def getSetting ( self , namespace ) :
return config . getSetting ( namespace )
@Slot ( str , result = bool )
def getSettingBool ( self , namespace ) :
return config . getSetting ( namespace )
@Slot ( str , str )
def setSetting ( self , namespace , value ) :
return config . setSetting ( namespace , value )
@Slot ( str , bool )
def setSettingBool ( self , namespace , value ) :
return config . setSetting ( namespace , value )
2022-01-20 17:19:36 +00:00
@Slot ( str )
def setLanguage ( self , new_lang ) :
config . setSetting ( " language " , new_lang )
2021-07-31 22:49:44 +00:00
@Slot ( result = str )
def getDebugInfos ( self ) :
"""
Returns the version info about Qt , PySide2 & Python
"""
2022-01-20 17:19:36 +00:00
return QCoreApplication . translate ( ' main ' , " Built with PySide2 (Qt) v {} and python v {} " ) . format ( PySide2_version , sys_version . split ( " \n " ) [ 0 ] )
2021-07-31 22:49:44 +00:00
@Slot ( str )
def openUrl ( self , url ) :
2021-08-14 19:40:42 +00:00
openWeb ( url )
2021-07-31 22:49:44 +00:00
def run ( ) :
2021-08-14 19:40:42 +00:00
environ [ " QT_QUICK_CONTROLS_STYLE " ] = {
2021-07-31 22:49:44 +00:00
" linux " : get_linux_theme ( ) ,
" freebsd " : get_linux_theme ( ) ,
" win32 " : " universal " if os_release == " 10 " else " fusion " ,
" cygwin " : " fusion " ,
" darwin " : " default "
} [ platform ]
2021-08-14 16:57:29 +00:00
dep_time = time ( )
print ( " Loaded dependencies in " + str ( ( dep_time - start_time ) * 1000 ) + " ms. " )
2021-07-31 22:49:44 +00:00
icon_fallbacks = QIcon . fallbackSearchPaths ( ) ;
2021-08-26 17:54:30 +00:00
icon_fallbacks . append ( path . realpath ( path . join ( getcwd ( ) , " qml " , " eu " , " ad5001 " , " LogarithmPlotter " , " icons " ) ) )
icon_fallbacks . append ( path . realpath ( path . join ( getcwd ( ) , " qml " , " eu " , " ad5001 " , " LogarithmPlotter " , " icons " , " settings " ) ) )
icon_fallbacks . append ( path . realpath ( path . join ( getcwd ( ) , " qml " , " eu " , " ad5001 " , " LogarithmPlotter " , " icons " , " settings " , " custom " ) ) )
2021-07-31 22:49:44 +00:00
QIcon . setFallbackSearchPaths ( icon_fallbacks ) ;
app = QApplication ( argv )
app . setApplicationName ( " LogarithmPlotter " )
app . setOrganizationName ( " Ad5001 " )
2021-08-26 17:54:30 +00:00
app . setWindowIcon ( QIcon ( path . realpath ( path . join ( getcwd ( ) , " logarithmplotter.svg " ) ) ) )
2021-08-16 20:05:51 +00:00
2022-01-20 17:19:36 +00:00
# Installing translators
translator = QTranslator ( )
2022-01-20 17:51:57 +00:00
# Check if lang is forced.
forcedlang = [ p for p in argv if p [ : 7 ] == " --lang= " ]
locale = QLocale ( forcedlang [ 0 ] [ 7 : ] ) if len ( forcedlang ) > 0 else QLocale ( )
if ( translator . load ( locale , " lp " , " _ " , path . realpath ( path . join ( getcwd ( ) , " i18n " ) ) ) ) :
2022-01-20 17:19:36 +00:00
app . installTranslator ( translator ) ;
2021-08-16 20:05:51 +00:00
# Installing macOS file handler.
macOSFileOpenHandler = None
if platform == " darwin " :
macOSFileOpenHandler = native . MacOSFileOpenHandler ( )
app . installEventFilter ( macOSFileOpenHandler )
2021-07-31 22:49:44 +00:00
engine = QQmlApplicationEngine ( )
2022-01-20 17:19:36 +00:00
helper = Helper ( engine )
2021-07-31 22:49:44 +00:00
engine . rootContext ( ) . setContextProperty ( " Helper " , helper )
engine . rootContext ( ) . setContextProperty ( " TestBuild " , " --test-build " in argv )
2021-08-14 16:57:29 +00:00
engine . rootContext ( ) . setContextProperty ( " StartTime " , dep_time )
2022-01-20 17:19:36 +00:00
app . translate ( " About " , " About LogarithmPlotter " ) # FOR SOME REASON, if this isn't included, Qt refuses to load the QML file.
2021-07-31 22:49:44 +00:00
2021-08-26 17:54:30 +00:00
engine . addImportPath ( path . realpath ( path . join ( getcwd ( ) , " qml " ) ) )
engine . load ( path . realpath ( path . join ( getcwd ( ) , " qml " , " eu " , " ad5001 " , " LogarithmPlotter " , " LogarithmPlotter.qml " ) ) )
2022-01-20 17:19:36 +00:00
2021-07-31 22:49:44 +00:00
2021-08-26 16:57:49 +00:00
if not engine . rootObjects ( ) :
2021-08-26 17:54:30 +00:00
print ( " No root object " , path . realpath ( path . join ( getcwd ( ) , " qml " ) ) )
print ( path . realpath ( path . join ( getcwd ( ) , " qml " , " eu " , " ad5001 " , " LogarithmPlotter " , " LogarithmPlotter.qml " ) ) )
2021-08-26 16:57:49 +00:00
exit ( - 1 )
2021-08-26 17:54:30 +00:00
chdir ( pwd )
2021-08-16 21:17:38 +00:00
if len ( argv ) > 0 and path . exists ( argv [ - 1 ] ) and argv [ - 1 ] . split ( ' . ' ) [ - 1 ] in [ ' lpf ' ] :
2021-07-31 22:49:44 +00:00
engine . rootObjects ( ) [ 0 ] . loadDiagram ( argv [ - 1 ] )
2021-08-26 17:54:30 +00:00
chdir ( path . dirname ( path . realpath ( __file__ ) ) )
2021-08-14 19:40:42 +00:00
2021-08-16 20:05:51 +00:00
if platform == " darwin " :
macOSFileOpenHandler . init_graphics ( engine . rootObjects ( ) [ 0 ] )
2021-08-14 19:40:42 +00:00
# Check for updates
if config . getSetting ( " check_for_updates " ) :
check_for_updates ( __VERSION__ , engine . rootObjects ( ) [ 0 ] )
2021-07-31 22:49:44 +00:00
exit_code = app . exec_ ( )
2021-08-26 15:48:12 +00:00
close ( fd )
2021-08-14 19:40:42 +00:00
remove ( tmpfile )
config . save ( )
2021-07-31 22:49:44 +00:00
exit ( exit_code )
if __name__ == " __main__ " :
run ( )