def get_file_type(path): """ Detects file type. If the file contains 'PROCEDURE DIVISION USING', then it is considered as a module else it is considered as an executable. :param path: file path :return: FileType """ encoding = _get_encoding(path) _logger().debug('detecting file type: %s - %s', path, encoding) try: from .settings import Settings ftype = Settings().get_file_type(path) except KeyError: ftype = FileType.EXECUTABLE with open(path, 'r', encoding=encoding) as f: content = f.read().upper() if re.match(r'.*PROCEDURE[\s\n]+DIVISION[\s\n]+USING', content, re.DOTALL): ftype = FileType.MODULE _logger().debug('file type: %r', ftype) return ftype
def get_version(include_all=True): """ Returns the GnuCOBOL compiler version as a string """ compiler = Settings().compiler_path cmd = compiler, '--version' if not compiler: return 'compiler not found' _logger().debug('getting cobc version: %s' % ' '.join(cmd)) status, output = run_command(cmd[0], [cmd[1]]) if status == 0 and output: if include_all: return output else: _logger().debug('parsing version line: %s' % output) m = re.match(r'cobc\s\([\w\s]*\).*$', output, re.MULTILINE) if m: return m.group(0) else: return "failed to extract version from output" else: return output
def setup_process_environment(): env = QtCore.QProcessEnvironment() for k, v in os.environ.items(): env.insert(k, v) s = Settings() PATH = '' if s.path_enabled: PATH = s.path if not s.vcvarsall: PATH = PATH + os.pathsep + os.environ['PATH'] else: for k, v in msvc.get_vc_vars(s.vcvarsall, s.vcvarsall_arch).items(): if k == 'PATH': PATH = PATH + os.pathsep + v else: env.insert(k, v) env.insert('PATH', PATH) _logger().debug('PATH=%s', PATH) if s.cob_config_dir_enabled and s.cob_config_dir: env.insert('COB_CONFIG_DIR', s.cob_config_dir) if s.cob_copy_dir_enabled and s.cob_copy_dir: env.insert('COB_COPY_DIR', s.cob_copy_dir) if s.cob_include_path_enabled and s.cob_copy_dir: env.insert('COB_INCLUDE_PATH', s.cob_include_path) if s.cob_lib_path and s.cob_copy_dir: env.insert('COB_LIB_PATH', s.cob_lib_path) return env
def get_version(): """ Returns the GnuCOBOL compiler version as a string """ cmd = [Settings().compiler_path, '--version'] try: _logger().debug('getting cobc version: %s' % ' '.join(cmd)) if sys.platform == 'win32': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW p = subprocess.Popen(cmd, shell=False, startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) else: p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except (OSError, TypeError): _logger().exception('GnuCOBOL compiler not found (command: %s)' % cmd) return 'Not installed' else: stdout, stderr = p.communicate() try: stdout = str(stdout.decode(locale.getpreferredencoding())) except UnicodeDecodeError: stdout = None lversion = 'Failed to parse cobc output' else: lversion = stdout.splitlines()[0] lversion = lversion.replace('cobc (', '').replace(')', '') _logger().debug('parsing version line: %s' % lversion) return lversion
def _run_in_external_terminal(self, program, wd, file_type): """ Runs a program in an external terminal. :param program: program to run :param wd: working directory """ self.ui.consoleOutput.append("Launched in external terminal") pyqode_console = system.which('pyqode-console') if file_type == FileType.MODULE: program = QtCore.QFileInfo(program).baseName() if system.windows: cmd = [pyqode_console, program] if file_type == FileType.MODULE: cmd.insert(1, system.which('cobcrun')) subprocess.Popen(cmd, cwd=wd, creationflags=subprocess.CREATE_NEW_CONSOLE) elif system.darwin: cmd = ['open', program] if file_type == FileType.MODULE: cmd.insert(1, system.which('cobcrun')) subprocess.Popen(cmd, cwd=wd) else: if file_type == FileType.EXECUTABLE: cmd = ['"%s %s"' % (pyqode_console, program)] else: cmd = [ '"%s %s %s"' % (pyqode_console, system.which('cobcrun'), program) ] cmd = (Settings().external_terminal_command.strip().split(' ') + cmd) subprocess.Popen(' '.join(cmd), cwd=wd, shell=True) _logger().info('running program in external terminal: %s', ' '.join(cmd))
def get_dependencies(cls, filename, recursive=True): """ Gets the dependencies of a cobol program/module. :param filename: path of the file to analyse. :param recursive: True to perform recursive analysis (analyses dependencies of dependencies recursively). :return: The set of dependencies that needs to be compiled to compile and use the requested program/module. """ encoding = _get_encoding(filename) directory = os.path.dirname(filename) dependencies = [] prog = re.compile(r'(^(\s|\d|\w)*CALL[\s\n]*.*".*")', re.MULTILINE) with open(filename, 'r', encoding=encoding) as f: content = f.read() for m in prog.findall(content): for m in m: try: module_base_name = re.findall('"(.*)"', m)[0] except IndexError: continue # try to see if the module can be found in the current # directory for ext in Settings().all_extensions: pth = os.path.join(directory, module_base_name + ext) if os.path.exists(pth) and \ pth.lower() not in dependencies: if filename != pth: dependencies.append(os.path.normpath(pth)) if recursive: dependencies += cls.get_dependencies(pth) dependencies = list(set(dependencies)) _logger().debug('dependencies of %s: %r', filename, dependencies) return dependencies
def update_editor_settings(editor): from open_cobol_ide.settings import Settings settings = Settings() # general settings for all editors editor.tab_length = settings.tab_len editor.font_name = settings.font editor.font_size = settings.font_size editor.show_whitespaces = settings.show_whitespaces editor.syntax_highlighter.color_scheme = ColorScheme(settings.color_scheme) editor.panels.get('FoldingPanel').native_look = not settings.dark_style try: # cobol editor specific settings editor.backspace_mode.enabled = settings.enable_smart_backspace editor.comment_indicator = settings.comment_indicator editor.free_format = settings.free_format editor.caret_line_mode.enabled = settings.highlight_caret editor.auto_indent_mode.enabled = settings.enable_autoindent editor.code_completion_mode.trigger_length = \ settings.code_completion_trigger_len editor.line_nbr_panel.enabled = settings.display_lines editor.line_nbr_panel.setVisible(settings.display_lines) editor.linter_mode.enabled = settings.show_errors except AttributeError: editor.syntax_highlighter.pygments_style = settings.color_scheme
def _generate_param_file(self, source_path): """ Generate the bin/EXECUTABLE.param file based on the settings defined in the preferences dialog. :param source_path: path of the .scb file. """ name = os.path.splitext(os.path.split(source_path)[1])[0] + '.param' content = PARAM_FILE_CONTENT % { 'host': Settings().dbhost, 'user': Settings().dbuser, 'pswd': Settings().dbpasswd, 'dbname': Settings().dbname, 'port': Settings().dbport, 'socket': Settings().dbsocket } output_dir = Settings().output_directory if not os.path.isabs(output_dir): output_dir = os.path.abspath(os.path.join(source_path, output_dir)) path = os.path.join(output_dir, name) if not os.path.exists(path): _logger().info('creating %s', name) with open(path, 'w') as f: f.write(content)
def toggle_fullscreen(self): if self.ui.actionFullscreen.isChecked(): self.main_window.showFullScreen() else: self.main_window.showNormal() Settings().fullscreen = self.ui.actionFullscreen.isChecked()
def _run_in_external_terminal(self, program, wd, file_type): """ Runs a program in an external terminal. :param program: program to run :param wd: working directory """ pyqode_console = system.which('pyqode-console') cobc_run_insert_pos = 1 if pyqode_console is None: from pyqode.core.tools import console pyqode_console = [sys.executable, console.__file__] cobc_run_insert_pos = 2 else: pyqode_console = [pyqode_console] env = os.environ.copy() for k, v in list(Settings().run_environemnt.items()): env[k] = v if 'PATH' not in list(Settings().run_environemnt.keys()): env['PATH'] = GnuCobolCompiler.setup_process_environment().value( 'PATH') if file_type == FileType.MODULE: program = QtCore.QFileInfo(program).baseName() if system.windows: cmd = pyqode_console + [program] if file_type == FileType.MODULE: cmd.insert(cobc_run_insert_pos, system.which('cobcrun')) try: _logger().debug( "running program in external terminal: %r, %r, %r" % (cmd, wd, env)) subprocess.Popen(cmd, cwd=wd, creationflags=subprocess.CREATE_NEW_CONSOLE, env=env) except (OSError, subprocess.CalledProcessError): msg = "Failed to launch program in external terminal (cmd=%s) " % ' '.join( cmd) _logger().exception(msg) self.ui.consoleOutput.appendPlainText(msg) return elif system.darwin: if file_type == FileType.MODULE: create_script(PATH_RUN_MODULE_SCRIPT, RUN_MODULE_SCRIPT, (wd, system.which('cobcrun'), program)) cmd = [ 'open', '-n', '-a', 'Terminal', '--args', PATH_RUN_MODULE_SCRIPT ] else: create_script(PATH_RUN_PROGRAM_SCRIPT, RUN_PROGRAM_SCRIPT, (wd, program)) cmd = [ 'open', '-n', '-a', 'Terminal', '--args', PATH_RUN_PROGRAM_SCRIPT ] try: subprocess.Popen(cmd, cwd=wd, env=env) except (OSError, subprocess.CalledProcessError): msg = "Failed to launch program in external terminal (cmd=%s) " % ' '.join( cmd) _logger().exception(msg) self.ui.consoleOutput.appendPlainText(msg) return else: if file_type == FileType.EXECUTABLE: cmd = ['"%s %s"' % (' '.join(pyqode_console), program)] else: cmd = [ '"%s %s %s"' % (' '.join(pyqode_console), system.which('cobcrun'), program) ] cmd = system.shell_split( Settings().external_terminal_command.strip()) + cmd try: subprocess.Popen(' '.join(cmd), cwd=wd, shell=True, env=env) except (OSError, subprocess.CalledProcessError): msg = "Failed to launch program in external terminal (cmd=%s) " % ' '.join( cmd) _logger().exception(msg) self.ui.consoleOutput.appendPlainText(msg) return _logger().info('running program in external terminal: %s', ' '.join(cmd)) self.ui.consoleOutput.appendPlainText( "Launched in external terminal: %s" % ' '.join(cmd))
def __init__(self): super().__init__() self.esqloc_path = os.path.join(Settings().esqloc, 'esqlOC.exe')
def save_state(dlg): s = Settings() s.preferences_width = dlg.width() s.preferences_height = dlg.height()
def __init__(self, dbpre_path=None): super().__init__() if dbpre_path is None: dbpre_path = Settings().dbpre self.dbpre_path = dbpre_path
def restore_defaults(self): settings = Settings() index = self.tabWidget.currentIndex() # Editor if index == 0: settings.show_cursor_pos_in_bytes = False settings.show_error = True settings.display_lines = True settings.highlight_caret = True settings.show_whitespaces = False settings.tab_len = 4 settings.enable_autoindent = True settings.code_completion_trigger_len = 1 settings.comment_indicator = '*> ' settings.enable_smart_backspace = False settings.lower_case_keywords = False settings.autodetect_eol = True settings.preferred_eol = 0 settings.code_completion_trigger_len = 1 settings.margin_positions = [7, 11, 72, 79] settings.margin_colors = ['red'] * 4 # Style elif index == 1: settings.dark_style = False settings.icon_theme = '' settings.font = 'Source Code Pro' settings.font_size = 11 settings.colorScheme = 'qt' # run elif index == 3: settings.external_terminal = False settings.external_terminal_command = None settings.run_environemnt = {} settings.working_dir = '' # compiler elif index == 2: settings.autodetect_submodules = True settings.output_directory = 'bin' settings.copy_runtime_dlls = False settings.free_format = False settings.cobol_standard = GnuCobolStandard.default settings.compiler_path = 'cobc.exe' if system.windows else 'cobc' settings.compiler_flags = ['-debug', '-Wall'] settings.copybook_paths = '' settings.library_search_path = '' settings.libraries = '' settings.cobc_extensions = ['.cob', '.cbl', '.pco', '.lst'] if system.windows: settings.vcvarsall = '' settings.vcvarsall_arch = 'x86' settings.path = settings.default_path() settings.path_enabled = True settings.cob_config_dir = settings.default_config_dir() settings.cob_config_dir_enabled = system.windows settings.cob_copy_dir = settings.default_copy_dir() settings.cob_copy_dir_enabled = system.windows settings.cob_include_path = settings.default_include_dir() settings.cob_include_path_enabled = system.windows settings.cob_lib_path = settings.default_lib_path() settings.cob_lib_path_enabled = system.windows elif index == 4: settings.dbpre = '' settings.dbpre_extensions = ['.scb'] settings.dbpre_framework = '' settings.cobmysqlapi = '' settings.dbhost = 'localhost' settings.dbuser = '' settings.dbpasswd = '' settings.dbname = '' settings.dbport = '03306' settings.dbsocket = 'null' settings.esqloc = '' settings.esqloc_extensions = ['.sqb'] self.reset()
def restore_state(dlg): s = Settings() dlg.resize(s.preferences_width, s.preferences_height) dlg.tabWidget.setCurrentIndex(s.preferences_index)
def file_type(self, ftype): Settings().set_file_type(self.file.path, ftype)
def reset(self, all_tabs=False): settings = Settings() # Editor if self.tabWidget.currentIndex() == 0 or all_tabs: self.cb_cursor_pos_in_bytes.setChecked( settings.show_cursor_pos_in_bytes) self.checkBoxShowErrors.setChecked(settings.show_errors) self.checkBoxViewLineNumber.setChecked(settings.display_lines) self.checkBoxHighlightCurrentLine.setChecked( settings.highlight_caret) self.checkBoxHighlightWhitespaces.setChecked( settings.show_whitespaces) self.spinBoxEditorTabLen.setValue(settings.tab_len) self.checkBoxEditorAutoIndent.setChecked( settings.enable_autoindent) self.spinBoxEditorCCTriggerLen.setValue( settings.code_completion_trigger_len) self.rbLowerCaseKwds.setChecked(settings.lower_case_keywords) self.rbUpperCaseKwds.setChecked(not settings.lower_case_keywords) self.lineEditCommentIndicator.setText(settings.comment_indicator) self.checkBoxSmartBackspace.setChecked( settings.enable_smart_backspace) self.checkBoxAutodetectEOL.setChecked(settings.autodetect_eol) self.comboBoxPreferredEOL.setCurrentIndex(settings.preferred_eol) self.comboCcFilterMode.setCurrentIndex( settings.completion_filter_mode) for pos, spin_box, color, picker in zip( settings.margin_positions, self._margin_spin_boxes, settings.margin_colors, self._margin_color_pickers): spin_box.setValue(pos + 1) picker.color = QtGui.QColor(color) # Style if self.tabWidget.currentIndex() == 1 or all_tabs: rb = (self.radioButtonColorDark if settings.dark_style else self.radioButtonColorWhite) rb.setChecked(True) index = self.comboBoxIconTheme.findText(QtGui.QIcon.themeName()) if index != -1: self.comboBoxIconTheme.setCurrentIndex(index) self.fontComboBox.setCurrentFont(QtGui.QFont(settings.font)) self.spinBoxFontSize.setValue(settings.font_size) self.listWidgetColorSchemes.clear() current_index = None self.listWidgetColorSchemes.clear() for style in PYGMENTS_STYLES: self.listWidgetColorSchemes.addItem(style) if style == settings.color_scheme: current_index = self.listWidgetColorSchemes.count() - 1 if current_index: self.listWidgetColorSchemes.setCurrentRow(current_index) # Run if self.tabWidget.currentIndex() == 3 or all_tabs: self.checkBoxRunExtTerm.setChecked(settings.external_terminal) self.lineEditRunTerm.setVisible(sys.platform != 'win32') self.lbl_external_terminal_command.setVisible( sys.platform != 'win32') self.lineEditRunTerm.setEnabled(settings.external_terminal) self.lineEditRunTerm.setText(settings.external_terminal_command) self.tw_run_env.clearContents() self.tw_run_env.setRowCount(0) for key, value in Settings().run_environemnt.items(): index = self.tw_run_env.rowCount() self.tw_run_env.insertRow(index) self.tw_run_env.setItem(index, 0, QtWidgets.QTableWidgetItem(key)) self.tw_run_env.setItem(index, 1, QtWidgets.QTableWidgetItem(value)) self.edit_working_dir.setText(settings.working_dir) # compiler if self.tabWidget.currentIndex() == 2 or all_tabs: self.cbAutoDetectSublmodules.setChecked( Settings().autodetect_submodules) self.cb_copy_runtime_dlls.setVisible(sys.platform == 'win32') self.cb_copy_runtime_dlls.setChecked(Settings().copy_runtime_dlls) self.lineEditOutputDirectory.setText(Settings().output_directory) self.lineEditCobcExts.setText(';'.join(Settings().cobc_extensions)) self.checkBoxFreeFormat.setChecked(settings.free_format) self.comboBoxStandard.setCurrentIndex(int(settings.cobol_standard)) self.lineEditCompilerPath.setText(settings.compiler_path) flags = Settings().compiler_flags self.cb_debugging_line.setChecked( self.cb_debugging_line.text() in flags) self.cb_ftrace.setChecked( self.cb_ftrace.text().replace('&', '') in flags) self.cb_ftraceall.setChecked( self.cb_ftraceall.text().replace('&', '') in flags) self.cb_g.setChecked(self.cb_g.text().replace('&', '') in flags) self.cb_static.setChecked( self.cb_static.text().replace('&', '') in flags) self.cb_debug.setChecked( self.cb_debug.text().replace('&', '') in flags) self.cb_w.setChecked(self.cb_w.text().replace('&', '') in flags) self.cb_wall.setChecked( self.cb_wall.text().replace('&', '') in flags) for v in self.flags_in_checkbox: try: flags.remove(v) except ValueError: pass self.lineEditLibs.setText(settings.libraries) self.listWidgetLibPaths.addItems([ pth for pth in settings.library_search_path.split(';') if pth ]) self.listWidgetCopyPaths.addItems( [pth for pth in settings.copybook_paths.split(';') if pth]) self.le_compiler_flags.setText(' '.join(flags)) if system.windows: self.lineEditVCVARS.setText(settings.vcvarsall) self.combo_arch.setCurrentIndex(1 if settings.vcvarsall_arch == 'x64' else 0) self.PATH.setText(settings.path) self.cbPATH.setChecked(settings.path_enabled) self.COB_CONFIG_DIR.setText(settings.cob_config_dir) self.cbCOB_CONFIG_DIR.setChecked(settings.cob_config_dir_enabled) self.COB_COPY_DIR.setText(settings.cob_copy_dir) self.cbCOB_COPY_DIR.setChecked(settings.cob_copy_dir_enabled) self.COB_INCLUDE_PATH.setText(settings.cob_include_path) self.cbCOB_INCLUDE_PATH.setChecked( settings.cob_include_path_enabled) self.COB_LIB_PATH.setText(settings.cob_lib_path) self.cbCOB_LIB_PATH.setChecked(settings.cob_lib_path_enabled) # SQL Cobol if self.tabWidget.currentIndex() == 4 or all_tabs: self.lineEditDbpreExts.setText(';'.join( Settings().dbpre_extensions)) self.lineEditDbpre.setText(settings.dbpre) self.lineEditDbpreFramework.setText(settings.dbpre_framework) self.lineEditCobmysqlapi.setText(settings.cobmysqlapi) self.lineEditDBHOST.setText(settings.dbhost) self.lineEditDBUSER.setText(settings.dbuser) self.lineEditDBPASSWD.setText(settings.dbpasswd) self.lineEditDBNAME.setText(settings.dbname) self.lineEditDBPORT.setText(settings.dbport) self.lineEditDBSOCKET.setText(settings.dbsocket) self.labelDbpreVersion.setText(compilers.DbpreCompiler( ).get_version() if Settings().dbpre != '' else '') self.lineEditESQLOC.setText(settings.esqloc) self.lineEditesqlOcExts.setText(';'.join( Settings().esqloc_extensions))
def generate(cls): print(cls.path()) with open(cls.path(), 'w') as f: f.write( cls.CODE_TEMPLATE.format(os.path.dirname(Settings().vcvars32), Settings().compiler_path))
def compile(self, file_path, file_type, object_files=None, additional_options=None, output_dir=None): """ Compiles a file. This is a blocking function, it returns only when the compiler process finished. :param file_path: Path of the file to compile. :param file_type: File type (exe or dll) :param output_dir: Output directory, if None, the directory set in the application directory will be used. :return: status, list of checker messages """ _logger().info('compiling %s' % file_path) path, filename = os.path.split(file_path) if output_dir is None: output_dir = Settings().output_directory original_output_dir = output_dir if not os.path.isabs(output_dir): output_dir = os.path.abspath(os.path.join(path, output_dir)) if object_files: inputs = [filename] + object_files else: inputs = [filename] # ensure bin dir exists output_full_path = os.path.join( output_dir, self.get_output_filename(inputs, file_type)) if os.path.exists(output_full_path) and \ os.path.getmtime(file_path) <= \ os.path.getmtime(output_full_path): desc = 'compilation skipped, up to date...' self.output_available.emit('%s: %s' % (file_path, desc)) msg = (desc, CheckerMessages.INFO, -1, 0, None, None, file_path) _logger().info(desc) return 0, [msg] self.prepare_bin_dir(output_dir, output_full_path) pgm, options = self.make_command(inputs, file_type, original_output_dir, additional_options) self.started.emit(' '.join([pgm] + options)) status, output = run_command(pgm, options, working_dir=path) self.output_available.emit(output) messages = self.parse_output(output, path) binary_created = os.path.exists(output_full_path) _logger().info('binary file %r created: %r', output_full_path, binary_created) if not len(messages) and (status != 0 or not binary_created): # compilation failed but the parser failed to extract COBOL related # messages, there might be an issue at the C level or at the # linker level messages.append( (output, CheckerMessages.ERROR, -1, 0, None, None, file_path)) _logger().info('compile results: %r - %r', status, messages) return status, messages
def __init__(self, parse_args=True): super().__init__() if system.darwin: Application._osx_init() self._reported_tracebacks = [] self._old_except_hook = sys.excepthook sys.excepthook = self._except_hook self._report_exception_requested.connect(self._report_exception) if hasattr(sys, 'frozen') and sys.platform == 'win32': sys.stdout = open( os.path.join(system.get_cache_directory(), 'ocide_stdout.log'), 'w') sys.stderr = open( os.path.join(system.get_cache_directory(), 'ocide_stderr.log'), 'w') self.app = QtWidgets.QApplication(sys.argv) if parse_args and not system.darwin: args = self.parse_args() verbose = args.verbose files = args.files else: verbose = False files = [] logger.setup_logging(__version__, debug=verbose or Settings().verbose) self.name = 'OpenCobolIDE' self.version = __version__ self.title = '%s %s' % (self.name, self.version) self.apply_mimetypes_preferences() self.win = MainWindow() self.win.setWindowTitle(self.title) self.file = FileController(self) self.view = ViewController(self) self.home = HomeController(self) self.edit = EditController(self) self.cobol = CobolController(self) self.help = HelpController(self) self.view.show_perspective(Settings().perspective) self.view.show_home_page() self.update_app_style() try: check_compiler() except CompilerNotFound: msg = 'Failed to find a working GnuCOBOL compiler!\n' \ "The IDE will continue to work but you won't be able to " \ 'compile...' if system.windows: msg += '\n\nTip: Ensure that there is no additional ' \ 'installation of MinGW in %s:\MinGW' % sys.executable[0] QtWidgets.QMessageBox.warning( self.win, 'COBOL compiler not found or not working', msg) else: _logger().info('GnuCOBOL version: %s', GnuCobolCompiler.get_version()) # open specified files for f in files: self.file.open_file(f)
def toggle_perspective(self): self.show_perspective( 'minimal' if Settings().perspective == 'default' else 'default')
def setPlainText(self, txt, mime_type, encoding): super().setPlainText(txt, mime_type, encoding) self.control_panel.setVisible(Settings().perspective == 'minimal')
def show_main_menu_as_context_menu(self, pos): if Settings().perspective == 'minimal': self.make_main_menu().exec_( self.ui.tabWidgetEditors.mapToGlobal(pos))
def restore_state(dlg): s = Settings() dlg.resize(s.preferences_width, s.preferences_height)
def __init__(self, parent): super().__init__( parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) self.setupUi(self) self._help_dlg = None themes = system.icon_themes() if themes: self.comboBoxIconTheme.addItems(themes) else: self.comboBoxIconTheme.hide() self.lblIconTheme.hide() self.tabWidget.setTabIcon( 0, QtGui.QIcon.fromTheme( 'accessories-text-editor', QtGui.QIcon(':/ide-icons/rc/cobol-mimetype.png'))) theme = 'application-x-executable' if QtGui.QIcon.hasThemeIcon('run-build'): theme = 'run-build' self.tabWidget.setTabIcon( 2, QtGui.QIcon.fromTheme( theme, QtGui.QIcon(':/ide-icons/rc/application-x-executable.png'))) self.tabWidget.setTabIcon( 1, QtGui.QIcon.fromTheme( 'applications-graphics', QtGui.QIcon(':/ide-icons/rc/applications-graphics.png'))) self.tabWidget.setTabIcon( 3, QtGui.QIcon.fromTheme( 'media-playback-start', QtGui.QIcon(':/ide-icons/rc/media-playback-start.png'))) icon_add = QtGui.QIcon.fromTheme( 'list-add', QtGui.QIcon(':/ide-icons/rc/list-add.png')) icon_remove = QtGui.QIcon.fromTheme( 'list-remove', QtGui.QIcon(':/ide-icons/rc/list-remove.png')) icon_open_folder = QtGui.QIcon.fromTheme( 'folder-open', QtGui.QIcon(':/ide-icons/rc/document-open.png')) icon_clear = QtGui.QIcon.fromTheme( 'edit-clear', QtGui.QIcon(':/ide-icons/rc/edit-clear.png')) self.bt_add_run_env.setIcon(icon_add) self.bt_rm_run_env.setIcon(icon_remove) self.bt_clear_run_env.setIcon(icon_clear) self.btAddAbsoluteCopyPath.setIcon(icon_open_folder) self.btAddRelativeCopyPath.setIcon(icon_add) self.btRemoveCopyPath.setIcon(icon_remove) self.toolButtonAddLibPath.setIcon(icon_open_folder) self.toolButtonAddRelativeLibPath.setIcon(icon_add) self.toolButtonRemoveLibPath.setIcon(icon_remove) self.toolButtonCheckCompiler.setIcon( QtGui.QIcon.fromTheme( 'emblem-checked', QtGui.QIcon(':/ide-icons/rc/emblem-checked.png'))) self.buttonBox.button(self.buttonBox.Reset).clicked.connect(self.reset) self.buttonBox.button(self.buttonBox.RestoreDefaults).clicked.connect( self.restore_defaults) self.checkBoxRunExtTerm.toggled.connect( self.lineEditRunTerm.setEnabled) self.listWidgetColorSchemes.currentItemChanged.connect( self.update_color_scheme_preview) self.plainTextEdit.setPlainText(DEFAULT_TEMPLATE, '', '') self.lineEditDbpre.setReadOnly(True) self.lineEditDbpreFramework.setReadOnly(True) self.lineEditCobmysqlapi.setReadOnly(True) self.toolButtonDbpre.clicked.connect(self._select_dbpre) self.toolButtonDbpreFramework.clicked.connect( self._select_dbpre_framework) self.toolButtonCobMySqlApiPath.clicked.connect( self._select_cobmysqlapi) self.checkBoxShowDbPass.stateChanged.connect( self._on_show_pass_state_changed) self.toolButtonVCVARS.clicked.connect(self._select_vcvarsall) self.toolButtonCustomCompilerPath.clicked.connect( self._select_custom_compiler_path) self.toolButtonAddLibPath.clicked.connect(self._add_lib_path) self.toolButtonAddRelativeLibPath.clicked.connect( self._add_rel_lib_path) self.toolButtonRemoveLibPath.clicked.connect(self._rm_lib_path) self.btAddAbsoluteCopyPath.clicked.connect(self._add_copy_path) self.btAddRelativeCopyPath.clicked.connect(self._add_rel_copy_path) self.btRemoveCopyPath.clicked.connect(self._rm_copy_path) self.toolButtonESQLOC.clicked.connect(self._select_esqloc) self.btCompilerFlagsHelp.clicked.connect(self._show_gnu_cobol_help) if not system.windows: self.labelVCVARS.hide() self.lineEditVCVARS.hide() self.toolButtonVCVARS.hide() self.combo_arch.hide() self.stackedWidgetSQL.setCurrentIndex(0) else: self.stackedWidgetSQL.setCurrentIndex(1) self.toolButtonCheckCompiler.clicked.connect(self._check_compiler) self.cbPATH.stateChanged.connect(self.PATH.setEnabled) self.cbCOB_CONFIG_DIR.stateChanged.connect( self.COB_CONFIG_DIR.setEnabled) self.cbCOB_COPY_DIR.stateChanged.connect(self.COB_COPY_DIR.setEnabled) self.cbCOB_INCLUDE_PATH.stateChanged.connect( self.COB_INCLUDE_PATH.setEnabled) self.cbCOB_LIB_PATH.stateChanged.connect(self.COB_LIB_PATH.setEnabled) self.PATH.setEnabled(self.cbPATH.isChecked()) self.COB_CONFIG_DIR.setEnabled(self.cbCOB_CONFIG_DIR.isChecked()) self.COB_COPY_DIR.setEnabled(self.cbCOB_COPY_DIR.isChecked()) self.COB_INCLUDE_PATH.setEnabled(self.cbCOB_INCLUDE_PATH.isChecked()) self.COB_LIB_PATH.setEnabled(self.cbCOB_LIB_PATH.isChecked()) self.bt_add_run_env.clicked.connect(self._add_run_env_variable) self.bt_rm_run_env.clicked.connect(self._rm_run_env_variable) self.bt_clear_run_env.clicked.connect(self._clear_run_env) self._margin_spin_boxes = [ self.spin_box_margin_1, self.spin_box_margin_2, self.spin_box_margin_3, self.spin_box_margin_4 ] self._margin_color_pickers = [ self.color_picker_1, self.color_picker_2, self.color_picker_3, self.color_picker_4 ] self.bt_working_dir.clicked.connect(self._select_working_dir) self.initial_settings = Settings().export_to_dict() self.reset(all_tabs=True)
def apply_mimetypes_preferences(self): for ext in Settings().all_extensions: mimetypes.add_type('text/x-cobol', ext) mimetypes.add_type('text/x-cobol', ext.upper())
def apply(self): # force next check (otherwise the cached result will be used) compilers.GnuCobolCompiler.check_compiler.reset() settings = Settings() settings.show_cursor_pos_in_bytes = \ self.cb_cursor_pos_in_bytes.isChecked() settings.display_lines = self.checkBoxViewLineNumber.isChecked() settings.highlight_caret = self.checkBoxHighlightCurrentLine.isChecked( ) settings.show_whitespaces = \ self.checkBoxHighlightWhitespaces.isChecked() settings.tab_len = self.spinBoxEditorTabLen.value() settings.enable_autoindent = self.checkBoxEditorAutoIndent.isChecked() settings.code_completion_trigger_len = \ self.spinBoxEditorCCTriggerLen.value() settings.preferred_eol = self.comboBoxPreferredEOL.currentIndex() settings.autodetect_eol = self.checkBoxAutodetectEOL.isChecked() settings.dark_style = self.radioButtonColorDark.isChecked() settings.font = self.fontComboBox.currentFont().family() settings.font_size = self.spinBoxFontSize.value() settings.color_scheme = self.listWidgetColorSchemes.currentItem().text( ) settings.external_terminal = self.checkBoxRunExtTerm.isChecked() settings.external_terminal_command = self.lineEditRunTerm.text() settings.lower_case_keywords = self.rbLowerCaseKwds.isChecked() settings.compiler_path = self.lineEditCompilerPath.text() settings.vcvarsall = self.lineEditVCVARS.text() settings.vcvarsall_arch = self.combo_arch.currentText() settings.path = self.PATH.text() settings.path_enabled = self.cbPATH.isChecked() settings.cob_config_dir = self.COB_CONFIG_DIR.text() settings.cob_config_dir_enabled = self.cbCOB_CONFIG_DIR.isChecked() settings.cob_copy_dir = self.COB_COPY_DIR.text() settings.cob_copy_dir_enabled = self.cbCOB_COPY_DIR.isChecked() settings.cob_include_path = self.COB_INCLUDE_PATH.text() settings.cob_include_path_enabled = self.cbCOB_INCLUDE_PATH.isChecked() settings.cob_lib_path = self.COB_LIB_PATH.text() settings.cob_lib_path_enabled = self.cbCOB_LIB_PATH.isChecked() settings.free_format = self.checkBoxFreeFormat.isChecked() settings.comment_indicator = self.lineEditCommentIndicator.text() settings.autodetect_submodules = \ self.cbAutoDetectSublmodules.isChecked() settings.cobol_standard = GnuCobolStandard( self.comboBoxStandard.currentIndex()) settings.icon_theme = self.comboBoxIconTheme.currentText() settings.show_errors = self.checkBoxShowErrors.isChecked() settings.enable_smart_backspace = \ self.checkBoxSmartBackspace.isChecked() paths = [] for i in range(self.listWidgetLibPaths.count()): paths.append(self.listWidgetLibPaths.item(i).text()) settings.library_search_path = ';'.join(paths) paths = [] for i in range(self.listWidgetCopyPaths.count()): paths.append(self.listWidgetCopyPaths.item(i).text()) settings.copybook_paths = ';'.join(paths) settings.libraries = self.lineEditLibs.text() settings.output_directory = self.lineEditOutputDirectory.text() settings.copy_runtime_dlls = self.cb_copy_runtime_dlls.isChecked() cb_flags = [ self.cb_g, self.cb_ftrace, self.cb_ftraceall, self.cb_debugging_line, self.cb_static, self.cb_debug, self.cb_w, self.cb_wall ] flags = [cb.text() for cb in cb_flags if cb.isChecked()] flags += system.shell_split(self.le_compiler_flags.text()) settings.compiler_flags = flags # sql settings.dbpre = self.lineEditDbpre.text() settings.dbpre_framework = self.lineEditDbpreFramework.text() settings.cobmysqlapi = self.lineEditCobmysqlapi.text() settings.dbhost = self.lineEditDBHOST.text() settings.dbuser = self.lineEditDBUSER.text() settings.dbpasswd = self.lineEditDBPASSWD.text() settings.dbname = self.lineEditDBNAME.text() settings.dbport = self.lineEditDBPORT.text() settings.dbsocket = self.lineEditDBSOCKET.text() settings.esqloc = self.lineEditESQLOC.text() settings.completion_filter_mode = \ self.comboCcFilterMode.currentIndex() settings.cobc_extensions = [ ext.lower() for ext in self.lineEditCobcExts.text().split(';') if ext ] settings.dbpre_extensions = [ ext.lower() for ext in self.lineEditDbpreExts.text().split(';') if ext ] settings.esqloc_extensions = [ ext for ext in self.lineEditesqlOcExts.text().split(';') if ext ] colors = [] positions = [] for spin_box, picker in zip(self._margin_spin_boxes, self._margin_color_pickers): positions.append(spin_box.value() - 1) colors.append(picker.color.name()) settings.margin_positions = positions settings.margin_colors = colors env = {} for i in range(self.tw_run_env.rowCount()): env[self.tw_run_env.item(i, 0).text()] = self.tw_run_env.item( i, 1).text() settings.run_environemnt = env settings.working_dir = self.edit_working_dir.text()
def which(cmd, mode=os.F_OK | os.X_OK, path=None, include_settings_path=True): """Given a command, mode, and a PATH string, return the path which conforms to the given mode on the PATH, or None if there is no such file. `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result of os.environ.get("PATH"), or can be overridden with a custom search path. TAKEN from the shutil module (cause it is not available on python <= 3.3) """ from open_cobol_ide.settings import Settings # Check that a given file can be accessed with the correct mode. # Additionally check that `file` is not a directory, as on Windows # directories pass the os.access check. def _access_check(fn, mode): return (os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn)) # If we're given a path with a directory part, look it up directly rather # than referring to PATH directories. This includes checking relative to the # current directory, e.g. ./script if os.path.dirname(cmd): if _access_check(cmd, mode): return cmd return None if path is None: path = os.environ.get("PATH", os.defpath) if not path: return None path = path.split(os.pathsep) if include_settings_path and Settings().path: path = Settings().path.split(os.pathsep) + path if sys.platform == "win32": # The current directory takes precedence on Windows. if not os.curdir in path: path.insert(0, os.curdir) # PATHEXT is necessary to check on Windows. pathext = os.environ.get("PATHEXT", "").split(os.pathsep) # See if the given file matches any of the expected path extensions. # This will allow us to short circuit when given "python.exe". # If it does match, only test that one, otherwise we have to try # others. if any(cmd.lower().endswith(ext.lower()) for ext in pathext): files = [cmd] else: files = [cmd + ext for ext in pathext] else: # On other platforms you don't have things like PATHEXT to tell you # what file suffixes are executable, so just pass on cmd as-is. files = [cmd] seen = set() for dir in path: normdir = os.path.normcase(dir) if not normdir in seen: seen.add(normdir) for thefile in files: name = os.path.join(dir, thefile) if _access_check(name, mode): return name return None
def save_state(dlg): s = Settings() s.preferences_width = dlg.width() s.preferences_height = dlg.height() s.preferences_index = dlg.tabWidget.currentIndex()
def compile(self, file_path, file_type, object_files=None, additional_options=None, output_dir=None): """ Compiles a file. This is a blocking function, it returns only when the compiler process finished. :param file_path: Path of the file to compile. :param file_type: File type (exe or dll) :param output_dir: Output directory, if None, the directory set in the application directory will be used. :return: status, list of checker messages """ _logger().info('compiling %s' % file_path) path, filename = os.path.split(file_path) if output_dir is None: output_dir = Settings().output_directory if not os.path.isabs(output_dir): output_dir = os.path.abspath(os.path.join(path, output_dir)) # run command using qt process api, this is blocking. if object_files: inputs = [filename] + object_files else: inputs = [filename] # ensure bin dir exists output_full_path = os.path.join( output_dir, self._get_output_filename(inputs, file_type)) if os.path.exists(output_full_path) and \ os.path.getmtime(file_path) <= \ os.path.getmtime(output_full_path): desc = 'compilation skipped, up to date...' self.output_available.emit('%s: %s' % (file_path, desc)) msg = (desc, CheckerMessages.INFO, -1, 0, None, None, file_path) return 0, [msg] self.prepare_bin_dir(output_dir, output_full_path) pgm, options = self.make_command(inputs, file_type, output_dir, additional_options) process = QtCore.QProcess() process.setWorkingDirectory(path) process.setProcessChannelMode(QtCore.QProcess.MergedChannels) process.setProcessEnvironment(self.setup_process_environment()) cmd = '%s %s' % (pgm, ' '.join(options)) _logger().info('command: %s', cmd) _logger().debug('working directory: %s', path) _logger().debug('system environment: %s', process.systemEnvironment()) process.start(pgm, options) self.started.emit(cmd) process.waitForFinished() if process.exitStatus() != process.Crashed: status = process.exitCode() else: status = 139 raw_output = process.readAllStandardOutput().data() try: output = raw_output.decode( locale.getpreferredencoding()).replace('\r', '\n') except UnicodeDecodeError: output = 'Failed to decode compiler output with encoding %s' % \ locale.getpreferredencoding() _logger().exception('failed to decode compiler output: %r' % raw_output) self.output_available.emit(output) messages = self.parse_output(output, process.workingDirectory()) binary_created = os.path.exists(output_full_path) _logger().info('compiler process exit code: %d', status) _logger().info('compiler process output: %s', output) _logger().info('binary file (%s) created: %r', output_full_path, binary_created) if not len(messages) and (status != 0 or not binary_created): # compilation failed but the parser failed to extract COBOL related # messages, there might be an issue at the C level or at the # linker level messages.append((output, CheckerMessages.ERROR, - 1, 0, None, None, file_path)) _logger().debug('compile results: %r - %r', status, messages) return status, messages