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.

279 lines
9.1KB

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