<commit_before># -*- coding: utf-8 -*-
#
# Poio Tools for Linguists
#
# Copyright (C) 2009-2012 Poio Project
# Author: <NAME> <<EMAIL>>
# URL: <http://www.cidles.eu/ltll/poio>
# For license information, see LICENSE.TXT

from __future__ import unicode_literals
import re
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QFont, QApplication

class NoStructureTypeHandlerError(Exception): pass

class PoioGraidTextEdit(QtGui.QTextEdit):

    FIRST_DATA_COLUMN = 2
    ROW_NAMES_COLUMNS = 1
    NUMBERS_COLUMN = 0

    def __init__(self, parent):
        """
        Initializes the Text Edit
        """
        QtGui.QTextEdit.__init__(self, parent)
        self.setLineWrapMode(QtGui.QTextEdit.NoWrap)
        self.setAcceptRichText(False)
        self.setUndoRedoEnabled(True)
        self.setTabChangesFocus(True)
        self.structure_type_handler = None

        palette = self.palette()
        palette.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, QtGui.QColor("yellow"))
        self.setPalette(palette)

        #self.setStyleSheet(".match { color:green; }")

        cursor = self.textCursor()
        cursor.setPosition(0)
        self.setTextCursor(cursor)

        QtCore.QObject.connect(
            self, QtCore.SIGNAL("cursorPositionChanged()"),
            self.check_cursor_position)

    def keyPressEvent(self, event):
        """
        Event handler for "Return Key", "Enter Key" and "Tab Key"

        ...

        Parameters
        ----------
        event : QEvent
        """
        c = self.textCursor()
        t = c.currentTable()

        if not t or \
                c.charFormat().fontCapitalization() == QtGui.QFont.SmallCaps:
            event.accept()
            return

        if event.key() == QtCore.Qt.Key_Return or \
                event.key() == QtCore.Qt.Key_Enter or \
                event.key() == QtCore.Qt.Key_Tab:
            cell = t.cellAt(c)
            if cell.column() + cell.columnSpan() == t.columns():
                pass
            else:
                c.movePosition(QtGui.QTextCursor.NextCell)
            if c.charFormat().fontCapitalization() == QtGui.QFont.SmallCaps:
                c.movePosition(QtGui.QTextCursor.NextCell)

            self.setTextCursor(c)
            event.accept()
            return

        QtGui.QTextEdit.keyPressEvent(self, event)

    def insertFromMimeData(self, source):
        """
        Insert text from Mime Data

        ...

        Parameters
        ----------
        source : QMimeData
        """
        text = source.text()
        text = re.sub(r"[\r\n\a]", "", text)
        self.insertPlainText(text)
        #QtGui.QTextEdit.insertFromMimeData(self, source)
        
    def check_cursor_position(self):
        """
        Check the cursor position
        """
        c = self.textCursor()
        t = c.currentTable()

        if not t or \
                c.charFormat().fontCapitalization() == QtGui.QFont.SmallCaps:
            self.setCursorWidth(0)
        else:
            self.setCursorWidth(1)

    def insert_column_at_cursor(self, id, after):
        """
        Inserts column before or after the current cursor position.

        ...

        Parameters
        ----------
        id : int
        after : bool

        """
        if not self.structure_type_handler:
            raise NoStructureTypeHandlerError

        cursor = self.textCursor()
        table = cursor.currentTable()
        if table:
            cell = table.cellAt(cursor)
            r = cell.row()
            c = cell.column()
            c_span = cell.columnSpan()
            type = self.structure_type_handler.flat_data_hierarchy[r]

            # check if the cursor is in utterance or an annotation of the
            # same level
            for s in self.structure_type_handler.get_siblings_of_type(
                    "utterance"):
                if r == self.structure_type_handler.flat_data_hierarchy.\
                        index(s):
                    return id

            if r >  0 and c > 0:
                new_column_pos = c
                if after:
                    new_column_pos = c + c_span
                else:
                    c += 1
                table.splitCell(0,0,1,1)
                table.insertColumns(new_column_pos, 1)
                table.mergeCells(0,0,8,1)
                # set text format to normal text and add id
                for row in range(table.rows()):
                    new_cell = table.cellAt(row, new_column_pos)
                    f = new_cell.format()
                    f.setFontCapitalization(QtGui.QFont.MixedCase)
                    f.setForeground(QtGui.QBrush("black"))
                    f.setAnchorNames([str(id)])
                    new_cell.setFormat(f)
                    id += 1

                for p in self.structure_type_handler.get_parents_of_type(type):
                    r_parent = self.structure_type_handler.\
                        flat_data_hierarchy.index(p)
                    cell_parent = table.cellAt(r_parent, c)
                    c_parent = cell_parent.column()
                    c_span_parent = cell_parent.columnSpan()
                    # if this cell was appended after the parent cell
                    # then merge in parent row
                    if after:
                        if (c_parent + c_span_parent) == c + c_span:
                            table.mergeCells(r_parent,
                                c_parent, 1, c_span_parent + 1)
                    # if this cell was inserted before parent then merge
                    # parent now
                    else:
                        if c_parent == c:
                            table.mergeCells(r_parent,
                                c_parent - 1, 1, c_span_parent + 1)
        return id

    def delete_column_at_cursor(self):
        """
        Removes the column with the current cursor.
        """
        cursor = self.textCursor()
        table = cursor.currentTable()
        if table:
            cell = table.cellAt(cursor)
            if cell.row() >= PoioGraidTextEdit.FIRST_DATA_COLUMN \
                and cell.column() >= PoioGraidTextEdit.FIRST_DATA_COLUMN:
                #print cell.column()
                #print cell.columnSpan()
                for i in range(cell.columnSpan()):
                    table.removeColumns(cell.column(), 1)
                #table.removeColumns(cell.column(), cell.columnSpan() + 1)
                #print unicode(table.document().toPlainText()).encode("utf-8")

    def delete_current_cell(self, merge_cells = False):
        """
        Removes the cell with the current cursor.
        """
        cursor = self.textCursor()
        table = cursor.currentTable()
        if table:
            cell = table.cellAt(cursor)
            r = cell.row()
            c = cell.column()
            c_span = cell.columnSpan()
            if r > 0:
                parent_cell = table.cellAt(r - 1, c)
                # do not delete if this cell already spans all columns of parent<commit_msg>Bug fix: deleting all columns leaves no column for editing<commit_after># -*- coding: utf-8 -*-
#
# Poio Tools for Linguists
#
# Copyright (C) 2009-2012 Poio Project
# Author: <NAME> <<EMAIL>>
# URL: <http://www.cidles.eu/ltll/poio>
# For license information, see LICENSE.TXT

from __future__ import unicode_literals
import re
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QFont, QApplication

class NoStructureTypeHandlerError(Exception): pass

class PoioGraidTextEdit(QtGui.QTextEdit):

    FIRST_DATA_COLUMN = 2
    ROW_NAMES_COLUMNS = 1
    NUMBERS_COLUMN = 0

    def __init__(self, parent):
        """
        Initializes the Text Edit
        """
        QtGui.QTextEdit.__init__(self, parent)
        self.setLineWrapMode(QtGui.QTextEdit.NoWrap)
        self.setAcceptRichText(False)
        self.setUndoRedoEnabled(True)
        self.setTabChangesFocus(True)
        self.structure_type_handler = None

        palette = self.palette()
        palette.setColor(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, QtGui.QColor("yellow"))
        self.setPalette(palette)

        #self.setStyleSheet(".match { color:green; }")

        cursor = self.textCursor()
        cursor.setPosition(0)
        self.setTextCursor(cursor)

        QtCore.QObject.connect(
            self, QtCore.SIGNAL("cursorPositionChanged()"),
            self.check_cursor_position)

    def keyPressEvent(self, event):
        """
        Event handler for "Return Key", "Enter Key" and "Tab Key"

        ...

        Parameters
        ----------
        event : QEvent
        """
        c = self.textCursor()
        t = c.currentTable()

        if not t or \
                c.charFormat().fontCapitalization() == QtGui.QFont.SmallCaps:
            event.accept()
            return

        if event.key() == QtCore.Qt.Key_Return or \
                event.key() == QtCore.Qt.Key_Enter or \
                event.key() == QtCore.Qt.Key_Tab:
            cell = t.cellAt(c)
            if cell.column() + cell.columnSpan() == t.columns():
                pass
            else:
                c.movePosition(QtGui.QTextCursor.NextCell)
            if c.charFormat().fontCapitalization() == QtGui.QFont.SmallCaps:
                c.movePosition(QtGui.QTextCursor.NextCell)

            self.setTextCursor(c)
            event.accept()
            return

        QtGui.QTextEdit.keyPressEvent(self, event)

    def insertFromMimeData(self, source):
        """
        Insert text from Mime Data

        ...

        Parameters
        ----------
        source : QMimeData
        """
        text = source.text()
        text = re.sub(r"[\r\n\a]", "", text)
        self.insertPlainText(text)
        #QtGui.QTextEdit.insertFromMimeData(self, source)
        
    def check_cursor_position(self):
        """
        Check the cursor position
        """
        c = self.textCursor()
        t = c.currentTable()

        if not t or \
                c.charFormat().fontCapitalization() == QtGui.QFont.SmallCaps:
            self.setCursorWidth(0)
        else:
            self.setCursorWidth(1)

    def insert_column_at_cursor(self, id, after):
        """
        Inserts column before or after the current cursor position.

        ...

        Parameters
        ----------
        id : int
        after : bool

        """
        if not self.structure_type_handler:
            raise NoStructureTypeHandlerError

        cursor = self.textCursor()
        table = cursor.currentTable()
        if table:
            cell = table.cellAt(cursor)
            r = cell.row()
            c = cell.column()
            c_span = cell.columnSpan()
            type = self.structure_type_handler.flat_data_hierarchy[r]

            # check if the cursor is in utterance or an annotation of the
            # same level
            for s in self.structure_type_handler.get_siblings_of_type(
                    "utterance"):
                if r == self.structure_type_handler.flat_data_hierarchy.\
                        index(s):
                    return id

            if r >  0 and c > 0:
                new_column_pos = c
                if after:
                    new_column_pos = c + c_span
                else:
                    c += 1
                table.splitCell(0,0,1,1)
                table.insertColumns(new_column_pos, 1)
                table.mergeCells(0,0,8,1)
                # set text format to normal text and add id
                for row in range(table.rows()):
                    new_cell = table.cellAt(row, new_column_pos)
                    f = new_cell.format()
                    f.setFontCapitalization(QtGui.QFont.MixedCase)
                    f.setForeground(QtGui.QBrush("black"))
                    f.setAnchorNames([str(id)])
                    new_cell.setFormat(f)
                    id += 1

                for p in self.structure_type_handler.get_parents_of_type(type):
                    r_parent = self.structure_type_handler.\
                        flat_data_hierarchy.index(p)
                    cell_parent = table.cellAt(r_parent, c)
                    c_parent = cell_parent.column()
                    c_span_parent = cell_parent.columnSpan()
                    # if this cell was appended after the parent cell
                    # then merge in parent row
                    if after:
                        if (c_parent + c_span_parent) == c + c_span:
                            table.mergeCells(r_parent,
                                c_parent, 1, c_span_parent + 1)
                    # if this cell was inserted before parent then merge
                    # parent now
                    else:
                        if c_parent == c:
                            table.mergeCells(r_parent,
                                c_parent - 1, 1, c_span_parent + 1)
        return id

    def delete_column_at_cursor(self):
        """
        Removes the column with the current cursor.
        """
        cursor = self.textCursor()
        table = cursor.currentTable()
        if table:
            cell = table.cellAt(cursor)
            if cell.row() >= PoioGraidTextEdit.FIRST_DATA_COLUMN \
                and cell.column() > PoioGraidTextEdit.FIRST_DATA_COLUMN:
                #print cell.column()
                #print cell.columnSpan()
                for i in range(cell.columnSpan()):
                    table.removeColumns(cell.column(), 1)
                #table.removeColumns(cell.column(), cell.columnSpan() + 1)
                #print unicode(table.document().toPlainText()).encode("utf-8")

    def delete_current_cell(self, merge_cells = False):
        """
        Removes the cell with the current cursor.
        """
        cursor = self.textCursor()
        table = cursor.currentTable()
        if table:
            cell = table.cellAt(cursor)
            r = cell.row()
            c = cell.column()
            c_span = cell.columnSpan()
            if r > 0:
                parent_cell = table.cellAt(r - 1, c)
                # do not delete if this cell already spans all columns of parent
{'fraction_non_alphanumeric': 0.09695603156708005, 'fraction_numerical': 0.005636978579481398, 'mean_word_length': 1.5155973059198866, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7567442', 'n_tokens_mistral': 4093, 'n_tokens_neox': 3860, 'n_words': 860}