util.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # -*- coding: utf-8 -*-
  2. #
  3. # AWL simulator - GUI utility functions
  4. #
  5. # Copyright 2012-2015 Michael Buesch <m@bues.ch>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. from __future__ import division, absolute_import, print_function, unicode_literals
  22. from awlsim_loader.common import *
  23. from awlsim_loader.coreclient import *
  24. import awlsim_loader.cython_helper as cython_helper
  25. import sys
  26. import traceback
  27. import xml.sax.saxutils as saxutils
  28. if isPyPy or isJython:
  29. # PySide does not work on PyPy or Jython, yet.
  30. printError("Running awlsim-gui on the PyPy or Jython interpreter is not supported.")
  31. printError("Please use CPython 2.7 or CPython 3.x")
  32. sys.exit(1)
  33. if cython_helper.shouldUseCython():
  34. print("*** Using accelerated CYTHON core "
  35. "(AWLSIM_CYTHON environment variable is set)")
  36. from awlsim.gui.qt_bindings import *
  37. AWLSIM_HOME_URL = "https://awlsim.de"
  38. # Convert an integer to a dual-string
  39. def intToDualString(value, bitWidth):
  40. string = []
  41. for bitnr in range(bitWidth - 1, -1, -1):
  42. string.append('1' if ((value >> bitnr) & 1) else '0')
  43. if bitnr and bitnr % 4 == 0:
  44. string.append('_')
  45. return ''.join(string)
  46. # Get the default fixed font
  47. def getDefaultFixedFont(pointSize=11, bold=False):
  48. font = QFont()
  49. font.setStyleHint(QFont.Courier)
  50. font.setFamily("Courier")
  51. font.setPointSize(pointSize)
  52. font.setWeight(QFont.Normal)
  53. font.setBold(bold)
  54. return font
  55. # Color used for errors
  56. def getErrorColor():
  57. return QColor("#FFC0C0")
  58. def handleFatalException(parentWidget=None):
  59. text = str(traceback.format_exc())
  60. print("Fatal exception:\n", text)
  61. text = saxutils.escape(text)
  62. QMessageBox.critical(parentWidget,
  63. "A fatal exception occurred",
  64. "<pre>"
  65. "A fatal exception occurred:\n\n"
  66. "%s\n\n"
  67. "Awlsim will be terminated."
  68. "</pre>" % text)
  69. sys.exit(1)
  70. class MessageBox(QDialog):
  71. def __init__(self, parent, title, text,
  72. verboseText=None, icon=QMessageBox.Critical):
  73. QDialog.__init__(self, parent)
  74. self.setLayout(QGridLayout())
  75. self.setWindowTitle(title)
  76. self.text = "<pre>" + saxutils.escape(text) + "\n</pre>"
  77. self.verboseText = None
  78. if verboseText and verboseText.strip() != text.strip():
  79. self.verboseText = "<pre>" + verboseText + "\n</pre>"
  80. self.textBox = QLabel(self)
  81. self.textBox.setTextInteractionFlags(Qt.TextSelectableByMouse |\
  82. Qt.TextSelectableByKeyboard |\
  83. Qt.LinksAccessibleByMouse |\
  84. Qt.LinksAccessibleByKeyboard)
  85. self.layout().addWidget(self.textBox, 0, 0, 1, 3)
  86. if self.verboseText:
  87. self.verboseCheckBox = QCheckBox("Show verbose information", self)
  88. self.layout().addWidget(self.verboseCheckBox, 1, 0, 1, 3)
  89. else:
  90. self.verboseCheckBox = None
  91. self.okButton = QPushButton("&Ok", self)
  92. self.layout().addWidget(self.okButton, 2, 1)
  93. self.__updateText()
  94. self.okButton.released.connect(self.accept)
  95. if self.verboseCheckBox:
  96. self.verboseCheckBox.stateChanged.connect(self.__updateText)
  97. def __updateText(self):
  98. if self.verboseCheckBox and\
  99. self.verboseCheckBox.checkState() == Qt.Checked:
  100. self.textBox.setText(self.verboseText)
  101. else:
  102. self.textBox.setText(self.text)
  103. @classmethod
  104. def error(cls, parent, text, verboseText=None):
  105. dlg = cls(parent = parent,
  106. title = "Awlsim - Error",
  107. text = text,
  108. verboseText = verboseText,
  109. icon = QMessageBox.Critical)
  110. res = dlg.exec_()
  111. dlg.deleteLater()
  112. return res
  113. @classmethod
  114. def warning(cls, parent, text, verboseText=None):
  115. dlg = cls(parent = parent,
  116. title = "Awlsim - Warning",
  117. text = text,
  118. verboseText = verboseText,
  119. icon = QMessageBox.Warning)
  120. res = dlg.exec_()
  121. dlg.deleteLater()
  122. return res
  123. @classmethod
  124. def handleAwlSimError(cls, parent, description, exception):
  125. if exception.getSeenByUser():
  126. return cls.Accepted
  127. exception.setSeenByUser()
  128. def maketext(verbose):
  129. text = "An exception occurred:"
  130. if description:
  131. text += "\n"
  132. text += " " + description + "."
  133. text += "\n\n"
  134. text += exception.getReport(verbose)
  135. return text
  136. return cls.error(parent, maketext(False), maketext(True))
  137. @classmethod
  138. def handleAwlParserError(cls, parent, exception):
  139. return cls.handleAwlSimError(parent = parent,
  140. description = None,
  141. exception = exception)