# -*- coding: utf-8 -*-
# Copyright (c) 2013 by Pablo Martín <goinnn@gmail.com>
#
# This software is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this software.  If not, see <http://www.gnu.org/licenses/>.
# This core originally was in this repository:
# <https://github.com/goinnn/Kate-plugins/blob/master/kate_plugins/pyte_plugins/check_plugins/commons.py>
import kate
import sys
from PyKDE4.kdecore import i18n
from PyKDE4.ktexteditor import KTextEditor
[docs]class PythonVersionException(Exception):
    pass
 
[docs]def needs_python_version(major, minor=None, micro=None, text=''):
    if major != sys.version_info.major:
        raise PythonVersionException(text)
    elif minor and minor != sys.version_info.minor:
        raise PythonVersionException(text)
    elif micro and micro != sys.version_info.micro:
        raise PythonVersionException(text)
 
[docs]def needs_packages(packages):
    msg = i18n("You need install the following packages:\n")
    import_error = False
    for package, version in packages.items():
        try:
            __import__(package)
        except ImportError:
            import_error = True
            if '==' in version:
                package = version.split('==')[0]
                version = version.split('==')[1]
            msg += i18n("\t%1. Use easy_install (or pip install) %1==%2", package, version)
    if import_error:
        raise ImportError(msg)
 
[docs]def clearMarksOfError(doc, mark_iface):
    for line in range(doc.lines()):
        if mark_iface.mark(line) == mark_iface.Error:
            mark_iface.removeMark(line, mark_iface.Error)
 
[docs]def showErrors(message, errors, key_mark, doc, time=10, icon='dialog-warning',
               key_line='line', key_column='column',
               max_errors=3, show_popup=True, move_cursor=False):
    mark_iface = doc.markInterface()
    messages = {}
    view = kate.activeView()
    pos = view.cursorPosition()
    current_line = pos.line() + 1
    current_column = pos.column() + 1
    for error in errors:
        header = False
        line = error[key_line]
        column = error.get(key_column, 0)
        pos = _compress_key(line, column)
        if not messages.get(line, None):
            header = True
            messages[pos] = []
        error_message = _generateErrorMessage(error, key_line, key_column, header)
        messages[pos].append(error_message)
        mark_iface.setMark(line - 1, mark_iface.Error)
    messages_items = list(messages.items())  # Python 3 compatible
    messages_items.sort()
    if move_cursor:
        first_error, messages_show = _getErrorMessagesOrder(messages_items,
                                                            max_errors,
                                                            current_line,
                                                            current_column)
        line_to_move, column_to_move = _uncompress_key(messages_items[first_error][0])
        _moveCursorTFirstError(line_to_move, column_to_move)
    else:
        first_error, messages_show = _getErrorMessagesOrder(messages_items, max_errors)
    if show_popup:
        message = '%s\n%s' % (message, '\n'.join(messages_show))
        if len(messages_show) < len(errors):
            message += i18n('\n\nAnd other errors')
        showError(message, time, icon, minTextWidth=300)
 
[docs]def showError(message="error", time=10, icon="dialog-warning", minTextWidth=300):
    kate.gui.popup(message, time, icon, minTextWidth=300)
 
[docs]def showOk(message="Ok", time=3, icon='dialog-ok'):
    kate.gui.popup(message, time, icon='dialog-ok', minTextWidth=200)
 
def _compress_key(line, column):
    doc = kate.activeDocument()
    cipher = len('%s' % doc.lines())
    key_template = '%%%sd' % cipher
    key_template += '__%3d'
    return key_template % (line, column)
def _uncompress_key(key):
    line, column = key.split('__')
    return (int(line), int(column))
def _generateErrorMessage(error, key_line='line', key_column='column', header=True):
    message = ''
    exclude_keys = [key_line, key_column, 'filename']
    line = error[key_line]
    column = error.get(key_column, None)
    if header or column:
        column = error.get(key_column, None)
        if column:
            message = i18n('~*~ Position: (%1, %2)', line, column)
        else:
            message = i18n('~*~ Line: %1', line)
        message += ' ~*~'
    for key, value in error.items():
        if value and key not in exclude_keys:
            if key != 'message':
                message = '%s\n     * %s: %s' % (message, key, value)
            else:
                message = '%s\n     %s' % (message, value)
    return message
def _getErrorMessagesOrder(messages_items, max_errors, current_line=None, current_column=None):
    messages_order = []
    first_error = None
    num_messages = 0
    if not current_line:
        for line, message in messages_items:
            messages_order.extend(message)
            num_messages += 1
            if num_messages >= max_errors:
                break
        return (0, messages_order)
    for i, error in enumerate(messages_items):
        line, column = _uncompress_key(error[0])
        message = error[1]
        if line > current_line or (line == current_line and column > current_column):
            if first_error is None:
                first_error = i
            num_messages += 1
            messages_order.extend(message)
        if num_messages >= max_errors:
            break
    if len(messages_order) == max_errors:
        return (first_error, messages_order)
    for i, error in enumerate(messages_items):
        line, column = _uncompress_key(error[0])
        message = error[1]
        if line <= current_line:
            if first_error is None:
                first_error = i
            num_messages += 1
            messages_order.extend(message)
        else:
            break
        if num_messages >= max_errors:
            break
    return (first_error, messages_order)
def _moveCursorTFirstError(line, column=None):
    try:
        column = column or 0
        cursor = KTextEditor.Cursor(line - 1, column - 1)
        view = kate.activeView()
        view.setCursorPosition(cursor)
    except KeyError:
        pass