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.

299 lines
9.3KB

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