def save_file(self, editor, force_dialog=False):
        """ Save the file from an editor object.

        :param editor: The editor for which the while should be saved.
        :param bool force_dialog: If True, a "Save as..." dialog will be
            shown even if a file name is associated with the editor.
        """
        if not editor:
            return

        if force_dialog or not editor.file_name:
            d = QFileDialog(
                self, 'Choose where to save file',
                self.tabs.currentWidget().file_name or self.default_path)
            d.setAcceptMode(QFileDialog.AcceptSave)
            d.setNameFilter("Python files (*.py)")
            d.setDefaultSuffix('py')
            if d.exec_():
                file_name = unicode(d.selectedFiles()[0])
            else:
                return False
        else:
            file_name = editor.file_name

        err = self.code_has_errors(editor)
        if err:
            if QMessageBox.warning(
                    self, 'Error saving "%s"' % editor.file_name,
                    'Compile error:\n' + err + '\n\nIf this file contains '
                    'a plugin, it will disappear from the plugin list.\n'
                    'Save anyway?',
                    QMessageBox.Yes | QMessageBox.No) == QMessageBox.No:
                return False

        try:
            f = open(file_name, 'w')
            f.write('\n'.join(self.code(editor)).encode('UTF-8'))
            f.close()
        except __HOLE__, e:
            QMessageBox.critical(
                self, 'Error saving "%s"' % editor.file_name, str(e))
            return False

        editor.file_name = file_name
        editor.file_was_changed = False
        fname = os.path.split(editor.file_name)[1]
        self.tabs.setTabText(self.tabs.indexOf(editor), fname)
        self.plugin_saved.emit(editor.file_name)
        return True
dataset/ETHPy150Open rproepp/spykeviewer/spykeviewer/ui/plugin_editor_dock.py/PluginEditorDock.save_file