Collection of tools useful for audio production
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
9.4KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Common/Shared code
  4. # Copyright (C) 2010-2018 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the COPYING file
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. import os
  20. import sys
  21. from codecs import open as codecopen
  22. from unicodedata import normalize
  23. if True:
  24. from PyQt5.QtCore import pyqtSignal, qWarning
  25. from PyQt5.QtGui import QIcon
  26. from PyQt5.QtWidgets import QApplication, QFileDialog, QMessageBox
  27. else:
  28. from PyQt4.QtCore import pyqtSignal, qWarning
  29. from PyQt4.QtGui import QIcon
  30. from PyQt4.QtGui import QApplication, QFileDialog, QMessageBox
  31. # ------------------------------------------------------------------------------------------------------------
  32. # Set Platform
  33. if sys.platform == "darwin":
  34. from PyQt5.QtGui import qt_mac_set_menubar_icons
  35. qt_mac_set_menubar_icons(False)
  36. HAIKU = False
  37. LINUX = False
  38. MACOS = True
  39. WINDOWS = False
  40. elif "haiku" in sys.platform:
  41. HAIKU = True
  42. LINUX = False
  43. MACOS = False
  44. WINDOWS = False
  45. elif "linux" in sys.platform:
  46. HAIKU = False
  47. LINUX = True
  48. MACOS = False
  49. WINDOWS = False
  50. elif sys.platform in ("win32", "win64", "cygwin"):
  51. WINDIR = os.getenv("WINDIR")
  52. HAIKU = False
  53. LINUX = False
  54. MACOS = False
  55. WINDOWS = True
  56. else:
  57. HAIKU = False
  58. LINUX = False
  59. MACOS = False
  60. WINDOWS = False
  61. # ------------------------------------------------------------------------------------------------------------
  62. # Try Import Signal
  63. try:
  64. from signal import signal, SIGINT, SIGTERM, SIGUSR1, SIGUSR2
  65. haveSignal = True
  66. except:
  67. haveSignal = False
  68. # ------------------------------------------------------------------------------------------------------------
  69. # Set Version
  70. VERSION = "0.8.1"
  71. # ------------------------------------------------------------------------------------------------------------
  72. # Set Debug mode
  73. DEBUG = bool("-d" in sys.argv or "-debug" in sys.argv or "--debug" in sys.argv)
  74. # ------------------------------------------------------------------------------------------------------------
  75. # Global variables
  76. global gGui
  77. gGui = None
  78. # ------------------------------------------------------------------------------------------------------------
  79. # Set TMP
  80. TMP = os.getenv("TMP")
  81. if TMP is None:
  82. if WINDOWS:
  83. qWarning("TMP variable not set")
  84. TMP = os.path.join(WINDIR, "temp")
  85. else:
  86. TMP = "/tmp"
  87. # ------------------------------------------------------------------------------------------------------------
  88. # Set HOME
  89. HOME = os.getenv("HOME")
  90. if HOME is None:
  91. HOME = os.path.expanduser("~")
  92. if not WINDOWS:
  93. qWarning("HOME variable not set")
  94. if not os.path.exists(HOME):
  95. qWarning("HOME does not exist")
  96. HOME = TMP
  97. # ------------------------------------------------------------------------------------------------------------
  98. # Set PATH
  99. PATH = os.getenv("PATH")
  100. if PATH is None:
  101. qWarning("PATH variable not set")
  102. if MACOS:
  103. PATH = ("/opt/local/bin", "/usr/local/bin", "/usr/bin", "/bin")
  104. elif WINDOWS:
  105. PATH = (os.path.join(WINDIR, "system32"), WINDIR)
  106. else:
  107. PATH = ("/usr/local/bin", "/usr/bin", "/bin")
  108. else:
  109. PATH = PATH.split(os.pathsep)
  110. # ------------------------------------------------------------------------------------------------------------
  111. # Remove/convert non-ascii chars from a string
  112. def asciiString(string):
  113. return normalize("NFKD", string).encode("ascii", "ignore").decode("utf-8")
  114. # ------------------------------------------------------------------------------------------------------------
  115. # Convert a ctypes c_char_p into a python string
  116. def cString(value):
  117. if not value:
  118. return ""
  119. if isinstance(value, str):
  120. return value
  121. return value.decode("utf-8", errors="ignore")
  122. # ------------------------------------------------------------------------------------------------------------
  123. # Check if a value is a number (float support)
  124. def isNumber(value):
  125. try:
  126. float(value)
  127. return True
  128. except:
  129. return False
  130. # ------------------------------------------------------------------------------------------------------------
  131. # Convert a value to a list
  132. def toList(value):
  133. if value is None:
  134. return []
  135. elif not isinstance(value, list):
  136. return [value]
  137. else:
  138. return value
  139. # ------------------------------------------------------------------------------------------------------------
  140. # Unicode open
  141. def uopen(filename, mode="r"):
  142. return codecopen(filename, encoding="utf-8", mode=mode)
  143. # ------------------------------------------------------------------------------------------------------------
  144. # QLineEdit and QPushButton combo
  145. def getAndSetPath(self_, currentPath, lineEdit):
  146. newPath = QFileDialog.getExistingDirectory(self_, self_.tr("Set Path"), currentPath, QFileDialog.ShowDirsOnly)
  147. if newPath:
  148. lineEdit.setText(newPath)
  149. return newPath
  150. # ------------------------------------------------------------------------------------------------------------
  151. # Get Icon from user theme, using our own as backup (Oxygen)
  152. def getIcon(icon, size=16):
  153. return QIcon.fromTheme(icon, QIcon(":/%ix%i/%s.png" % (size, size, icon)))
  154. # ------------------------------------------------------------------------------------------------------------
  155. # Custom MessageBox
  156. def CustomMessageBox(self_, icon, title, text, extraText="", buttons=QMessageBox.Yes|QMessageBox.No, defButton=QMessageBox.No):
  157. msgBox = QMessageBox(self_)
  158. msgBox.setIcon(icon)
  159. msgBox.setWindowTitle(title)
  160. msgBox.setText(text)
  161. msgBox.setInformativeText(extraText)
  162. msgBox.setStandardButtons(buttons)
  163. msgBox.setDefaultButton(defButton)
  164. return msgBox.exec_()
  165. # ------------------------------------------------------------------------------------------------------------
  166. # Signal handler
  167. def setUpSignals(self_):
  168. global gGui
  169. if gGui is None:
  170. gGui = self_
  171. if not haveSignal:
  172. return
  173. signal(SIGINT, signalHandler)
  174. signal(SIGTERM, signalHandler)
  175. signal(SIGUSR1, signalHandler)
  176. signal(SIGUSR2, signalHandler)
  177. gGui.SIGTERM.connect(closeWindowHandler)
  178. gGui.SIGUSR2.connect(showWindowHandler)
  179. def signalHandler(sig, frame):
  180. global gGui
  181. if gGui is None:
  182. return
  183. if sig in (SIGINT, SIGTERM):
  184. gGui.SIGTERM.emit()
  185. elif sig == SIGUSR1:
  186. gGui.SIGUSR1.emit()
  187. elif sig == SIGUSR2:
  188. gGui.SIGUSR2.emit()
  189. def closeWindowHandler():
  190. global gGui
  191. if gGui is None:
  192. return
  193. gGui.hide()
  194. gGui.close()
  195. QApplication.instance().quit()
  196. gGui = None
  197. def showWindowHandler():
  198. global gGui
  199. if gGui is None:
  200. return
  201. if gGui.isMaximized():
  202. gGui.showMaximized()
  203. else:
  204. gGui.showNormal()
  205. # ------------------------------------------------------------------------------------------------------------
  206. # Shared Icons
  207. def setIcons(self_, modes):
  208. global gGui
  209. if gGui is None:
  210. gGui = self_
  211. if "canvas" in modes:
  212. gGui.ui.act_canvas_arrange.setIcon(getIcon("view-sort-ascending"))
  213. gGui.ui.act_canvas_refresh.setIcon(getIcon("view-refresh"))
  214. gGui.ui.act_canvas_zoom_fit.setIcon(getIcon("zoom-fit-best"))
  215. gGui.ui.act_canvas_zoom_in.setIcon(getIcon("zoom-in"))
  216. gGui.ui.act_canvas_zoom_out.setIcon(getIcon("zoom-out"))
  217. gGui.ui.act_canvas_zoom_100.setIcon(getIcon("zoom-original"))
  218. gGui.ui.b_canvas_zoom_fit.setIcon(getIcon("zoom-fit-best"))
  219. gGui.ui.b_canvas_zoom_in.setIcon(getIcon("zoom-in"))
  220. gGui.ui.b_canvas_zoom_out.setIcon(getIcon("zoom-out"))
  221. gGui.ui.b_canvas_zoom_100.setIcon(getIcon("zoom-original"))
  222. if "jack" in modes:
  223. gGui.ui.act_jack_clear_xruns.setIcon(getIcon("edit-clear"))
  224. gGui.ui.act_jack_configure.setIcon(getIcon("configure"))
  225. gGui.ui.act_jack_render.setIcon(getIcon("media-record"))
  226. gGui.ui.b_jack_clear_xruns.setIcon(getIcon("edit-clear"))
  227. gGui.ui.b_jack_configure.setIcon(getIcon("configure"))
  228. gGui.ui.b_jack_render.setIcon(getIcon("media-record"))
  229. if "transport" in modes:
  230. gGui.ui.act_transport_play.setIcon(getIcon("media-playback-start"))
  231. gGui.ui.act_transport_stop.setIcon(getIcon("media-playback-stop"))
  232. gGui.ui.act_transport_backwards.setIcon(getIcon("media-seek-backward"))
  233. gGui.ui.act_transport_forwards.setIcon(getIcon("media-seek-forward"))
  234. gGui.ui.b_transport_play.setIcon(getIcon("media-playback-start"))
  235. gGui.ui.b_transport_stop.setIcon(getIcon("media-playback-stop"))
  236. gGui.ui.b_transport_backwards.setIcon(getIcon("media-seek-backward"))
  237. gGui.ui.b_transport_forwards.setIcon(getIcon("media-seek-forward"))
  238. if "misc" in modes:
  239. gGui.ui.act_quit.setIcon(getIcon("application-exit"))
  240. gGui.ui.act_configure.setIcon(getIcon("configure"))