Esempio n. 1
0
class TabBarPlus(QtGui.QTabBar):
    """Tab bar that has a plus button floating to the right of the tabs."""

    plusClicked = QtCore.Signal()

    def __init__(self):
        super(self.__class__, self).__init__()

        # Plus Button
        self.plusButton = QtGui.QPushButton("+")
        self.plusButton.setParent(self)
        # self.plusButton.setFixedSize(20, 20)  # Small Fixed size
        self.plusButton.setMaximumWidth(20)
        self.plusButton.clicked.connect(self.plusClicked.emit)
        self.movePlusButton()  # Move to the correct location

    # end Constructor

    def sizeHint(self):
        """Return the size of the TabBar with increased width for the plus button."""
        sizeHint = QtGui.QTabBar.sizeHint(self)
        width = sizeHint.width()
        height = sizeHint.height()
        return QtCore.QSize(width + 25, height)

    # end tabSizeHint

    def resizeEvent(self, event):
        """Resize the widget and make sure the plus button is in the correct location."""
        super(self.__class__, self).resizeEvent(event)

        self.movePlusButton()

    # end resizeEvent

    def tabLayoutChange(self):
        """This virtual handler is called whenever the tab layout changes.
        If anything changes make sure the plus button is in the correct location.
        """
        super(self.__class__, self).tabLayoutChange()

        self.movePlusButton()

    # end tabLayoutChange

    def movePlusButton(self):
        """Move the plus button to the correct location."""
        # Find the width of all of the tabs
        size = sum([self.tabRect(i).width() for i in range(self.count())])
        # size = 0
        # for i in range(self.count()):
        #     size += self.tabRect(i).width()

        # Set the plus button location in a visible area
        h = self.geometry().top()
        w = self.width()
        if size > w:  # Show just to the left of the scroll buttons
            self.plusButton.move(w - 54, h)
        else:
            self.plusButton.move(size, h)
Esempio n. 2
0
class mayaBatchClass(QtCore.QObject):

    progress_out = QtCore.Signal(object)

    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.batch_process = QtCore.QProcess(self)

        self.actions()

    def start_batch(self):
        self.batch_process.setProcessChannelMode(
            QtCore.QProcess.MergedChannels)

        self.batch_process.readyRead.connect(self.progress_output)

        self.batch_process.waitForReadyRead(True)

        self.batch_process.start(
            u'{0}/python3/App/Python/python.exe'.format(TACTIC_DIR),
            ['{0}/bin/startup_standalone.py'.format(TACTIC_DIR)])

    def progress_output(self):

        log_output = str(self.batch_process.readAllStandardOutput())

        self.progress_out.emit(log_output)

        self.write_log(log_output)

    def write_log(self, log_text):
        log_path = u'{0}/log_out.log'.format(TACTIC_DIR)

        if os.path.exists(gf.extract_dirname(log_path)):
            with codecs.open(log_path, 'a+', 'utf-8') as log_file:
                log_file.write(log_text)
        else:
            os.makedirs(gf.extract_dirname(log_path))
            with codecs.open(log_path, 'w+', 'utf-8') as log_file:
                log_file.write(log_text)

        log_file.close()

    def actions(self):
        self.batch_process.error.connect(self.error_handle)
        #self.batch_process.stateChanged.connect(self.state_changed_handle)
        #self.batch_process.readyRead.connect(self.progress_output)

    def error_handle(self, message=None):
        if message:
            print('Some errors', message)
Esempio n. 3
0
class SquareLabel(QtGui.QLabel):
    clicked = QtCore.Signal()

    def __init__(self, menu, action, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.menu = menu
        self.action = action

    def mousePressEvent(self, event):
        self.clicked.emit()
        event.accept()

    def enterEvent(self, event):
        self.setAutoFillBackground(False)
        self.menu.setActiveAction(self.action)

    def leaveEvent(self, event):
        self.setAutoFillBackground(True)
Esempio n. 4
0
class Output(QtCore.QObject):

    written = QtCore.Signal(unicode)
    flushed = QtCore.Signal()

    def __init__(self, std, parent_stream=None, parent=None):
        """
        Initialize default settings.
        """

        self.__parent_stream = parent_stream

        super(Output, self).__init__(parent)

        self.__std = std
        self.softspace = 0

    def readline(self, *args, **kwargs):
        """
        Read line method.
        """

        return self.__std.readline(*args, **kwargs)

    def stream(self):
        """
        Get parent stream.
        """

        return self.__parent_stream

    def write(self, text):
        """
        Write text message.
        """

        result = self.__std.write(text)
        # try:
        #     # text = unicode(text).encode('utf-8', errors='ignore')
        #     text = str(text)
        #
        # except UnicodeEncodeError or UnicodeDecodeError:
        #     text = u"Failed to encode error message..."

        self.written.emit(text)
        return result

    def writelines(self, line_list):
        """
        Write lines.
        """

        result = self.__std.writelines(line_list)
        for line in line_list:
            # try:
            #     line = unicode(line)
            #
            # except UnicodeEncodeError or UnicodeDecodeError:
            #     line = u"Failed to encode error message..."

            self.written.emit(line)

        return result

    def flush(self, *args, **kwargs):
        """
        Flush
        """

        result = self.__std.flush(*args, **kwargs)
        self.flushed.emit()
        return result
Esempio n. 5
0
class EditorWindow(QtGui.QPlainTextEdit):
    returnPressed = QtCore.Signal()
    closeRequested = QtCore.Signal()
    restoreLastClosedRequested = QtCore.Signal()
    reloadRequested = QtCore.Signal()
    openRequested = QtCore.Signal()
    saveRequested = QtCore.Signal()
    saveAsRequested = QtCore.Signal()
    saveAllRequested = QtCore.Signal()
    searchRequested = QtCore.Signal()
    newFileRequested = QtCore.Signal()

    SAVE_HISTORY = False
    DRAW_LINE_NUMBER = True
    INDENT_DRAW = True
    INDENT_SPACE_COUNT = 4
    INDENT_DRAW_WIDTH = 0.5
    INDENT_REPLACE_SPACE = True
    HIGHLIGHT_SELECTED_LINE = True

    COLOR_MAP = {
        "background": Qt4Gui.QColor("#A88627"),
        "line_number": QtCore.Qt.black,
        "line_number_background": Qt4Gui.QColor("#5C5C5C"),
        "indent": QtCore.Qt.white,
        "highlight_selected_line": Qt4Gui.QColor("#4D4225"),
        "highlight_selected": Qt4Gui.QColor("#665526"),
        "highlight_find_word": Qt4Gui.QColor(QtCore.Qt.gray).lighter(130),
        "highlight_similiar_word": Qt4Gui.QColor(QtCore.Qt.gray).lighter(130),
    }

    @staticmethod
    def GetColor(key):
        """
        Get color by given key.
        """

        if key in EditorWindow.COLOR_MAP:
            return EditorWindow.COLOR_MAP[key]
        else:
            return Qt4Gui.QColor("#black")

    @staticmethod
    def LineIndent(line):
        """
        Get line indent.
        """

        indent = 0
        sub_count = 0
        indent_end = 0
        for ch in line:
            if ch == "\t":
                indent += 1
                sub_count = 0
                indent_end += 1

            elif ch == " ":
                sub_count += 1
                indent_end += 1

                if sub_count == EditorWindow.INDENT_SPACE_COUNT:
                    sub_count = 0
                    indent += 1

            else:
                sub_count = 0
                break

        return indent

    @staticmethod
    def LineIndentInfo(line):
        """
        Get line indent info.
        """

        space_count = 0
        tab_count = 0
        for ch in line:
            if ch == "\t":
                tab_count += 1

            elif ch == " ":
                space_count += 1

            else:
                break

        indent_end = tab_count + space_count
        indent = tab_count + (space_count / EditorWindow.INDENT_SPACE_COUNT)
        real_indent_end = tab_count + (
            (space_count / EditorWindow.INDENT_SPACE_COUNT) *
            EditorWindow.INDENT_SPACE_COUNT)
        need_to_indent = indent_end - real_indent_end

        return indent, indent_end, real_indent_end, need_to_indent

    @staticmethod
    def GetIndentSymbol():
        """
        Get indent character.
        """

        indent_symbol = "\t"
        if EditorWindow.INDENT_REPLACE_SPACE:
            indent_symbol = " " * EditorWindow.INDENT_SPACE_COUNT

        return indent_symbol

    @staticmethod
    def LineWithoutIndent(line):
        """
        Get line without indnt.
        """

        result = ""
        breaked = False
        for ch in line:
            if ch != "\t":
                if ch != " ":
                    breaked = True

            if breaked:
                result += ch

        return result

    def __init__(self, parent=None):
        """
        Initialize default settings.
        """

        QtGui.QPlainTextEdit.__init__(self, parent)

        self._line_area = line_number_area.LineNumberArea(self)
        self.blockCountChanged.connect(self.updateLineNumberAreaWidth)
        self.updateRequest.connect(self.updateLineNumberArea)
        self.cursorPositionChanged.connect(self.highlightCurrentLine)
        self.setLineWrapMode(QtGui.QPlainTextEdit.NoWrap)
        self.setTabStopWidth(self.fontMetrics().width(
            " " * EditorWindow.INDENT_SPACE_COUNT))
        self.updateLineNumberAreaWidth(0)
        self.highlightCurrentLine()
        self._highlight_handle = syntax_highlighter.SyntaxHighlighter(
            self.document())

    def selectedText(self):
        """
        Get selected text.
        """

        cursor = self.textCursor()
        text = cursor.selectedText()
        text = text.replace(u"\u2029", "\n")
        text = text.replace(u"\u2028", "\n")
        # text = unicode(text)
        while text.startswith("\n"):
            text = text[1:]
        while text.endswith("\n"):
            text = text[:-1]
        return text

    def lineNumberAreaPaintEvent(self, event):
        """
        Line number area paint event.
        """

        if EditorWindow.DRAW_LINE_NUMBER:
            painter = Qt4Gui.QPainter(self._line_area)
            painter.setRenderHint(Qt4Gui.QPainter.Antialiasing)
            painter.fillRect(event.rect(),
                             EditorWindow.GetColor("line_number_background"))
            painter.setPen(EditorWindow.GetColor("line_number"))

            block = self.firstVisibleBlock()
            block_number = block.blockNumber()
            top = self.blockBoundingGeometry(block).translated(
                self.contentOffset()).top()
            bottom = top + self.blockBoundingRect(block).height()

            while block.isValid() and top <= event.rect().bottom():
                if block.isVisible() and bottom >= event.rect().top():
                    number = str(block_number + 1)
                    painter.drawText(0, top, self._line_area.width(),
                                     self.fontMetrics().height(),
                                     QtCore.Qt.AlignRight, number)

                block = block.next()
                top = bottom
                bottom = top + self.blockBoundingRect(block).height()
                block_number += 1

    def lineNumberAreaWidth(self):
        """
        Get line number area size.
        """

        digits = 1
        last = max(1, self.blockCount())
        while last >= 10:
            last /= 10
            digits += 1

        space = 3 + self.fontMetrics().width("9") * digits
        return space

    def resizeEvent(self, event):
        """
        Resize event.
        """

        QtGui.QPlainTextEdit.resizeEvent(self, event)
        content_rect = self.contentsRect()
        self._line_area.setGeometry(
            QtCore.QRect(content_rect.left(), content_rect.top(),
                         self.lineNumberAreaWidth(), content_rect.height()))

    def updateLineNumberAreaWidth(self, block_count):
        """
        Update line number area size.
        """

        self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)

    def highlightCurrentLine(self):
        """
        Highlight current line.
        """

        if EditorWindow.HIGHLIGHT_SELECTED_LINE:
            selection_list = []
            selection = QtGui.QTextEdit.ExtraSelection()
            line_color = EditorWindow.GetColor("highlight_selected_line")
            selection.format.setBackground(line_color)
            selection.format.setProperty(Qt4Gui.QTextFormat.FullWidthSelection,
                                         True)
            selection.cursor = self.textCursor()
            selection.cursor.clearSelection()
            selection_list.append(selection)
            self.setExtraSelections(selection_list)

    def updateLineNumberArea(self, rect, number):
        """
        Update line number area.
        """

        if number:
            self._line_area.scroll(0, number)
        else:
            self._line_area.update(0, rect.y(), self._line_area.width(),
                                   rect.height())

        if rect.contains(self.viewport().rect()):
            self.updateLineNumberAreaWidth(0)

    def search(self,
               text,
               matchCase=False,
               completeWord=False,
               regEnabled=False,
               up=False,
               wrap=False):
        """
        Search text.
        """

        flags = None
        if up:
            if not flags:
                flags = QtGui.QTextDocument.FindBackward
            else:
                flags |= QtGui.QTextDocument.FindBackward
        if matchCase:
            if not flags:
                flags = QtGui.QTextDocument.FindCaseSensitively
            else:
                flags |= QtGui.QTextDocument.FindCaseSensitively
        if completeWord:
            if not flags:
                flags = QtGui.QTextDocument.FindWholeWords
            else:
                flags |= QtGui.QTextDocument.FindWholeWords
        color = self.GetColor("highlight_find_word")
        cursor = self.textCursor()
        extraSelections = []
        if flags:
            _search = lambda _text: self.find(_text, flags)
        else:
            _search = lambda _text: self.find(_text)
        if wrap:
            self.moveCursor(Qt4Gui.QTextCursor.Start)
        count = 0
        first_occur = None
        while _search(text):
            extra = QtGui.QTextEdit.ExtraSelection()
            extra.format.setBackground(color)
            if first_occur is None:
                first_occur = self.textCursor()
            extra.cursor = self.textCursor()
            extraSelections.append(extra)
            count += 1

        self.setExtraSelections(extraSelections)
        if first_occur is not None:
            self.setTextCursor(first_occur)

    def enter(self):
        """
        Enter event.
        """

        indent_symbol = self.GetIndentSymbol()
        cursor = self.textCursor()
        position = cursor.position()
        if cursor.hasSelection():
            cursor.removeSelectedText()
        previous_pos = cursor.position()
        cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
        cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                            Qt4Gui.QTextCursor.KeepAnchor)
        offset_pos = cursor.position()
        line = cursor.selectedText()
        cursor.setPosition(previous_pos)
        offset = offset_pos - previous_pos
        if offset > 0:
            line = line[:-offset]
        if line:
            indent = self.LineIndent(line)
            if line[-1] == ":":
                cursor.insertText("\n" + (indent_symbol * (indent + 1)))
            else:
                cursor.insertText("\n" + (indent_symbol * (indent)))
        else:
            cursor.insertText("\n")
        self.setTextCursor(cursor)

    def updateIndent(self, value):
        """
        Update indent.
        """

        indent_symbol = self.GetIndentSymbol()
        cursor = self.textCursor()
        position = cursor.position()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        cursor.setPosition(start)
        cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
        cursor.setPosition(end, Qt4Gui.QTextCursor.KeepAnchor)
        cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                            Qt4Gui.QTextCursor.KeepAnchor)
        abs_start = cursor.selectionStart()
        abs_end = cursor.selectionEnd()
        text = cursor.selectedText()
        text = text.replace(u"\u2029", "\n")
        text = text.replace(u"\u2028", "\n")
        text = str(text)
        if text.count("\n") == 0 and (abs_start != start or abs_end != end
                                      or start == end):
            # Single selection add indent.
            indent, indent_end, real_indent_end, need_to_indent = self.LineIndentInfo(
                text)
            relative_position = start - abs_start
            indent_offset = self.INDENT_SPACE_COUNT - (
                (len(text[real_indent_end:relative_position]) %
                 self.INDENT_SPACE_COUNT))
            if relative_position > indent_end:
                less_offset = self.INDENT_SPACE_COUNT - indent_offset
                if less_offset == 0:
                    less_offset += self.INDENT_SPACE_COUNT
                less_position = position - less_offset
                if less_position < 0:
                    less_position = 0
                cursor.setPosition(less_position)
            else:
                if need_to_indent > 0 and value < 0:
                    indent += 1
                cursor.setPosition(abs_start)
                cursor.setPosition(abs_start + indent_end,
                                   Qt4Gui.QTextCursor.KeepAnchor)
                cursor.insertText(indent_symbol * (indent + value))
        else:
            # Muliline add indent.
            replace_text = []
            line_number = 0
            for line in text.splitlines():
                indent = self.LineIndent(line)
                line = self.LineWithoutIndent(line)
                replace_text.append(indent_symbol * (indent + value) + line)
                line_number += 1
            replace_text = "\n".join(replace_text)
            cursor.insertText(replace_text)
            cursor.setPosition(abs_start)
            cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine,
                                Qt4Gui.QTextCursor.MoveAnchor)
            for l in range(line_number - 1):
                cursor.movePosition(Qt4Gui.QTextCursor.Down,
                                    Qt4Gui.QTextCursor.KeepAnchor)
            cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                                Qt4Gui.QTextCursor.KeepAnchor)

        self.setTextCursor(cursor)

    def updateLinePosition(self, value):
        """
        Update line position.
        """

        cursor = self.textCursor()
        position = cursor.position()
        if cursor.hasSelection():
            start = cursor.selectionStart()
            end = cursor.selectionEnd()
        else:
            start = cursor.position()
            end = start

        # Get full line.
        cursor.setPosition(start)
        cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
        cursor.setPosition(end, Qt4Gui.QTextCursor.KeepAnchor)
        cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                            Qt4Gui.QTextCursor.KeepAnchor)

        # Get information about selection.
        source_start = cursor.selectionStart()
        source_end = cursor.selectionEnd()
        source_text = cursor.selectedText()

        previous_position = cursor.position()
        if value > 0:
            cursor.setPosition(end)
            cursor.movePosition(Qt4Gui.QTextCursor.Down)
        else:
            cursor.setPosition(start)
            cursor.movePosition(Qt4Gui.QTextCursor.Up)

        cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
        cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                            Qt4Gui.QTextCursor.KeepAnchor)
        target_position = cursor.position()
        if target_position == previous_position:
            if position < end:
                cursor.setPosition(end)
                cursor.setPosition(start, Qt4Gui.QTextCursor.KeepAnchor)
            else:
                cursor.setPosition(start)
                cursor.setPosition(end, Qt4Gui.QTextCursor.KeepAnchor)
        else:
            cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
            cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                                Qt4Gui.QTextCursor.KeepAnchor)
            target_start = cursor.selectionStart()
            target_end = cursor.selectionEnd()
            target_text = cursor.selectedText()

            cursor.beginEditBlock()

            # Replace selected lines to next line.
            cursor.setPosition(source_start)
            cursor.setPosition(source_end, Qt4Gui.QTextCursor.KeepAnchor)
            cursor.insertText(target_text)
            cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
            cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                                Qt4Gui.QTextCursor.KeepAnchor)
            current_start = cursor.selectionStart()
            current_end = cursor.selectionEnd()

            if value > 0:
                cursor.setPosition(current_end)
                cursor.movePosition(Qt4Gui.QTextCursor.Down)
            else:
                cursor.setPosition(current_start)
                cursor.movePosition(Qt4Gui.QTextCursor.Up)

            cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
            cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                                Qt4Gui.QTextCursor.KeepAnchor)
            selection_start_position = cursor.selectionStart()
            cursor.insertText(source_text)
            selection_end_position = selection_start_position + (source_end -
                                                                 source_start)
            cursor.setPosition(selection_start_position)
            cursor.movePosition(Qt4Gui.QTextCursor.StartOfLine)
            cursor.setPosition(selection_end_position,
                               Qt4Gui.QTextCursor.KeepAnchor)
            cursor.movePosition(Qt4Gui.QTextCursor.EndOfLine,
                                Qt4Gui.QTextCursor.KeepAnchor)
            cursor.endEditBlock()

        self.setTextCursor(cursor)

    def moveLineUp(self):
        """
        Move line up.
        """

        self.updateLinePosition(-1)

    def moveLineDowm(self):
        """
        Move line down.
        """

        self.updateLinePosition(1)

    def addIndent(self):
        """
        Add line indent.
        """

        self.updateIndent(1)

    def removeIndent(self):
        """
        Remove indent.
        """

        self.updateIndent(-1)

    def keyPressEvent(self, event):
        """
        Key press event.
        """

        if event.key(
        ) == QtCore.Qt.Key_Return and QtGui.QApplication.keyboardModifiers(
        ) == QtCore.Qt.ControlModifier:
            self.returnPressed.emit()
            event.accept()

        else:
            if event.key() == QtCore.Qt.Key_Return:
                self.enter()

            elif event.key() == QtCore.Qt.Key_Tab:
                self.addIndent()

            elif event.key() == QtCore.Qt.Key_Backtab:
                self.removeIndent()

            elif event.key(
            ) == QtCore.Qt.Key_Up and QtGui.QApplication.keyboardModifiers(
            ) == (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier):
                self.moveLineUp()

            elif event.key(
            ) == QtCore.Qt.Key_Down and QtGui.QApplication.keyboardModifiers(
            ) == (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier):
                self.moveLineDowm()

            elif event.key(
            ) == QtCore.Qt.Key_W and QtGui.QApplication.keyboardModifiers(
            ) == QtCore.Qt.ControlModifier:
                self.closeRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_T and QtGui.QApplication.keyboardModifiers(
            ) == (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier):
                self.restoreLastClosedRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_R and QtGui.QApplication.keyboardModifiers(
            ) == (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier):
                self.reloadRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_O and QtGui.QApplication.keyboardModifiers(
            ) == QtCore.Qt.ControlModifier:
                self.openRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_S and QtGui.QApplication.keyboardModifiers(
            ) == QtCore.Qt.ControlModifier:
                self.saveRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_S and QtGui.QApplication.keyboardModifiers(
            ) == QtCore.Qt.AltModifier:
                self.saveAsRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_S and QtGui.QApplication.keyboardModifiers(
            ) == (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier):
                self.saveAllRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_F and QtGui.QApplication.keyboardModifiers(
            ) == QtCore.Qt.ControlModifier:
                self.searchRequested.emit()

            elif event.key(
            ) == QtCore.Qt.Key_N and QtGui.QApplication.keyboardModifiers(
            ) == QtCore.Qt.ControlModifier:
                self.newFileRequested.emit()

            else:
                super(EditorWindow, self).keyPressEvent(event)
class Ui_repositoryEditorWidget(QtGui.QDialog):
    saved_signal = QtCore.Signal(object, object)
    edited_signal = QtCore.Signal(object, object)

    def __init__(self, sobject_item, mode='create', parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.sobject_item = sobject_item
        self.mode = mode
        self.saved = False
        self.exclude_repo_list = self.get_exclude_repo_list()

        self.create_ui()

    def create_ui(self):
        if self.mode == 'create':
            self.setWindowTitle('Choose Repositories to Watch')
        else:
            self.setWindowTitle('Editing Watch Folders')

        self.resize(600, 420)
        self.setSizeGripEnabled(True)

        self.creat_layout()
        self.create_repo_path_line_edit()
        self.create_repo_combo_box()
        self.create_repos_tree_widget()
        self.create_buttons()

        if self.mode == 'edit':
            self.fill_repo_combo_box(self.exclude_repo_list)
            self.fill_repo_tree_widget(self.exclude_repo_list)
        else:
            self.fill_repo_combo_box()
            self.fill_repo_tree_widget()

        self.check_save_ability()

        self.controls_actions()

    def controls_actions(self):

        self.add_new_button.clicked.connect(self.add_new_repo)
        self.remove_button.clicked.connect(self.delete_selected_repo)
        self.save_button.clicked.connect(self.save_and_close)
        self.close_button.clicked.connect(self.close)

    def creat_layout(self):

        self.main_layout = QtGui.QGridLayout()
        self.main_layout.setContentsMargins(9, 9, 9, 9)
        self.main_layout.setColumnStretch(0, 1)
        self.setLayout(self.main_layout)

    def create_repos_tree_widget(self):

        self.repos_tree_widget = QtGui.QTreeWidget()
        self.repos_tree_widget.setSelectionMode(
            QtGui.QAbstractItemView.ExtendedSelection)
        self.repos_tree_widget.setEditTriggers(
            QtGui.QAbstractItemView.NoEditTriggers)
        self.repos_tree_widget.setRootIsDecorated(False)
        self.repos_tree_widget.setHeaderHidden(True)
        self.repos_tree_widget.setObjectName('repos_tree_widget')

        self.main_layout.addWidget(self.repos_tree_widget, 2, 0, 2, 1)

    def create_repo_path_line_edit(self):
        self.repo_path_line_edit_layout = QtGui.QHBoxLayout()
        self.repo_path_line_edit_layout.addWidget(
            QtGui.QLabel('Relative Watch Path:'))

        self.repo_path_line_edit = QtGui.QLineEdit()
        self.repo_path_line_edit_layout.addWidget(self.repo_path_line_edit)
        if self.mode == 'create':
            paths = tc.get_dirs_with_naming(self.sobject_item.get_search_key(),
                                            process_list=['watch_folder'])
            self.repo_path_line_edit.setText(paths['versionless'][0])
        elif self.mode == 'edit':
            self.repo_path_line_edit.setText(
                self.sobject_item.get_watch_folder_path())

        self.main_layout.addLayout(self.repo_path_line_edit_layout, 0, 0, 1, 2)

    def create_repo_combo_box(self):
        self.repo_combo_box = QtGui.QComboBox()

        self.main_layout.addWidget(self.repo_combo_box, 1, 0, 1, 1)

    def check_save_ability(self):
        if self.repos_tree_widget.topLevelItemCount() < 1:
            self.save_button.setEnabled(False)
        else:
            self.save_button.setEnabled(True)

    def get_exclude_repo_list(self):
        watch_folder_ui = env_inst.watch_folders.get(
            self.sobject_item.project.get_code())
        watch_dict = watch_folder_ui.get_watch_dict_by_skey(
            self.sobject_item.get_search_key())
        if watch_dict:
            return watch_dict['rep']
        else:
            return []

    def fill_repo_combo_box(self, exlude_list=None):

        self.repo_combo_box.clear()

        if not exlude_list:
            exlude_list = []

        base_dirs = env_tactic.get_all_base_dirs()

        # Default repo states
        for key, val in base_dirs:
            if val['value'][4] and val['value'][3] not in exlude_list:
                self.repo_combo_box.addItem(val['value'][1])
                self.repo_combo_box.setItemData(
                    self.repo_combo_box.count() - 1, val)

        self.repo_combo_box.addItem('All Repos')

        current_repo = gf.get_value_from_config(cfg_controls.get_checkin(),
                                                'repositoryComboBox')

        if current_repo:
            self.repo_combo_box.setCurrentIndex(current_repo)

    def fill_repo_tree_widget(self, exlude_list=None):

        self.repos_tree_widget.clear()

        if not exlude_list:
            exlude_list = []

        base_dirs = env_tactic.get_all_base_dirs()

        # Default repo states
        for key, val in base_dirs:
            if val['value'][4] and val['value'][3] in exlude_list:
                root_item = QtGui.QTreeWidgetItem()
                root_item.setText(0, val['value'][1])
                root_item.setData(0, QtCore.Qt.UserRole, val)

                self.repos_tree_widget.addTopLevelItem(root_item)

    def create_buttons(self):

        self.add_new_button = QtGui.QPushButton('Add')
        self.add_new_button.setMinimumWidth(90)
        self.remove_button = QtGui.QPushButton('Remove')
        self.remove_button.setMinimumWidth(90)
        self.save_button = QtGui.QPushButton('Save and Close')
        self.save_button.setMinimumWidth(90)
        self.close_button = QtGui.QPushButton('Cancel')
        self.close_button.setMinimumWidth(90)

        self.main_layout.addWidget(self.add_new_button, 1, 1, 1, 1)
        self.main_layout.addWidget(self.remove_button, 2, 1, 1, 1)
        self.main_layout.addWidget(self.save_button, 4, 0, 1, 1)
        self.main_layout.addWidget(self.close_button, 4, 1, 1, 1)

        spacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Minimum,
                                   QtGui.QSizePolicy.Expanding)
        self.main_layout.addItem(spacer, 3, 1, 1, 1)

    def add_new_repo(self):
        current_repo_index = self.repo_combo_box.currentIndex()

        current_repo = self.repo_combo_box.itemData(current_repo_index)
        if current_repo:
            self.repo_combo_box.removeItem(current_repo_index)

            root_item = QtGui.QTreeWidgetItem()
            root_item.setText(0, current_repo['value'][1])
            root_item.setData(0, QtCore.Qt.UserRole, current_repo)

            self.exclude_repo_list.append(current_repo['value'][3])

            self.repos_tree_widget.addTopLevelItem(root_item)
        else:
            for i in range(self.repo_combo_box.count() - 1):
                current_repo = self.repo_combo_box.itemData(i)

                root_item = QtGui.QTreeWidgetItem()
                root_item.setText(0, current_repo['value'][1])
                root_item.setData(0, QtCore.Qt.UserRole, current_repo)

                self.exclude_repo_list.append(current_repo['value'][3])

                self.repos_tree_widget.addTopLevelItem(root_item)

        self.fill_repo_combo_box(self.exclude_repo_list)

        self.check_save_ability()

    def delete_selected_repo(self):
        current_repo_item = self.repos_tree_widget.currentItem()
        if current_repo_item:
            current_repo = current_repo_item.data(0, QtCore.Qt.UserRole)
            self.exclude_repo_list.remove(current_repo['value'][3])

            self.repos_tree_widget.takeTopLevelItem(
                self.repos_tree_widget.currentIndex().row())
            self.fill_repo_combo_box(self.exclude_repo_list)

        self.check_save_ability()

    def set_saved(self):
        self.saved = True

    def save_and_close(self):
        self.set_saved()
        params = (self.get_repos_list(), self.sobject_item)
        self.sobject_item.set_watch_folder_path(
            str(self.repo_path_line_edit.text()))

        if self.mode == 'create':
            self.saved_signal.emit(*params)

        if self.mode == 'edit':
            self.edited_signal.emit(*params)

        self.close()

    def get_repos_list(self):

        repos_list = []

        for i in range(self.repos_tree_widget.topLevelItemCount()):
            top_item = self.repos_tree_widget.topLevelItem(i)
            repo_dict = top_item.data(0, QtCore.Qt.UserRole)
            repos_list.append(repo_dict['value'][3])

        return repos_list
Esempio n. 7
0
class Ui_tacticSidebarWidget(QtGui.QWidget):
    clicked = QtCore.Signal(object)

    def __init__(self, project, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.project = project

        self.checkin_out_config_projects = cfg_controls.get_checkin_out_projects(
        )
        self.checkin_out_config = cfg_controls.get_checkin_out()

        self.create_ui()

    def create_ui(self):
        self.main_layout = QtGui.QVBoxLayout()
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)
        self.setLayout(self.main_layout)

        self.tree_widget = Ui_extendedTreeWidget(self)
        self.tree_widget.setMaximumSize(QtCore.QSize(0, 16777215))
        self.tree_widget.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)
        self.tree_widget.setEditTriggers(
            QtGui.QAbstractItemView.NoEditTriggers)
        self.tree_widget.setIndentation(0)
        self.tree_widget.setSelectionBehavior(
            QtGui.QAbstractItemView.SelectRows)
        self.tree_widget.setTabKeyNavigation(True)
        self.tree_widget.setVerticalScrollMode(
            QtGui.QAbstractItemView.ScrollPerPixel)
        self.tree_widget.setAllColumnsShowFocus(True)
        self.tree_widget.setRootIsDecorated(False)
        self.tree_widget.setHeaderHidden(True)
        self.tree_widget.setExpandsOnDoubleClick(False)
        self.tree_widget.setObjectName('sidebar_widget')
        self.tree_widget.setMinimumHeight(400)
        self.tree_widget.setMinimumWidth(250)
        self.tree_widget.setFocusPolicy(QtCore.Qt.NoFocus)

        self.tree_widget.setStyleSheet(gf.get_qtreeview_style(True))

        self.main_layout.addWidget(self.tree_widget)

        self.controls_actions()

    def controls_actions(self):

        self.tree_widget.itemClicked.connect(self.tree_widget_item_click)

    def tree_widget_item_click(self, item):

        item_widget = self.tree_widget.itemWidget(item, 0)
        self.clicked.emit(item_widget)

    def get_ignore_stypes_list(self):
        ignore_tabs_list = []
        if self.checkin_out_config and self.checkin_out_config_projects and self.checkin_out_config_projects.get(
                self.project.get_code()):
            if not gf.get_value_from_config(self.checkin_out_config,
                                            'processTabsFilterGroupBox'):
                ignore_tabs_list = []
            else:
                ignore_tabs_list = self.checkin_out_config_projects[
                    self.project.get_code()]['stypes_list']
                if not ignore_tabs_list:
                    ignore_tabs_list = []

        return ignore_tabs_list

    def initial_fill(self):

        self.tree_widget.clear()

        sidebar = self.project.get_config_views()
        current_login = env_inst.get_current_login_object()
        project_code = self.project.get_code()

        if sidebar.has_definition():

            project_definition = sidebar.get_view('SideBarWdg')
            # making sure if there is *special TH* definition
            tactic_handler_definition = sidebar.get_view(
                'SideBarWdg', 'tactic_handler')

            if not tactic_handler_definition:
                tactic_handler_definition = sidebar.get_view(
                    'SideBarWdg', 'project_view')

            tactic_handler_sidebar = []
            for th_def in tactic_handler_definition:
                th_def_name = th_def['name']
                for prj_def in project_definition:
                    if prj_def['name'] == th_def_name:
                        tactic_handler_sidebar.append(prj_def)

            for sidebar_item in tactic_handler_sidebar:
                access = current_login.check_security(
                    group='link',
                    path='element:{0}'.format(sidebar_item.get('name')),
                    project=project_code)

                if access == 'allow':

                    stype_code = None
                    view_definition = None
                    sub_definitions = []
                    layout = 'default'

                    if sidebar_item.search_type:
                        stype_code = sidebar_item.search_type.string

                    if sidebar_item.layout:
                        layout = sidebar_item.layout.string

                    if sidebar_item.view:
                        view_definition = sidebar.get_view(
                            'SideBarWdg', sidebar_item.view.string)

                        for sub_def in view_definition:
                            sub_def_name = sub_def['name']

                            for sub_prj_def in project_definition:
                                if sub_prj_def['name'] == sub_def_name:
                                    sub_definitions.append(sub_prj_def)

                    if stype_code and stype_code.startswith('sthpw'):
                        stype = env_inst.get_stype_by_code(stype_code)
                    else:
                        stype = self.project.stypes.get(stype_code)

                    item_info = {
                        'title': sidebar_item.get('title'),
                        'name': sidebar_item.get('name'),
                        'display_class': sidebar_item.display.get('class'),
                        'search_type': stype_code,
                        'layout': layout,
                        'view_definition': view_definition,
                        'sub_definitions': sub_definitions,
                        'item': sidebar_item,
                    }

                    gf.add_sidebar_item(
                        tree_widget=self.tree_widget,
                        stype=stype,
                        project=self.project,
                        item_info=item_info,
                    )
                    self.tree_widget.resizeColumnToContents(0)
Esempio n. 8
0
class Stream(QtCore.QObject):

    __stdout = None
    __stderr = None
    __excepthook = None
    __stream = None

    __original__stdout = sys.stdout
    __original__stdin = sys.stdin
    __original__stderr = sys.stderr
    __original__excepthook = sys.excepthook

    exceptedWritten = QtCore.Signal(unicode)
    outputWritten = QtCore.Signal(unicode)
    errorWritten = QtCore.Signal(unicode)
    inputWritten = QtCore.Signal(unicode)

    @staticmethod
    def get_stream():
        """
        Get current stream.
        """

        return Stream.__stream

    def __new__(cls, *args):
        """
        Get python stream instance.
        """

        if Stream.__stream is None:
            result = super(Stream, cls).__new__(cls, *args)
        else:
            result = Stream.__stream
        return result

    def __init__(self, *args):
        """
        Initialize default settings.
        """

        super(Stream, self).__init__(*args)

        if Stream.__stream is None:
            Stream.__stream = self
            from . import OutputCls, ExceptionHook

            self.out = OutputCls(Stream.__original__stdout, self)
            Stream.__stdout = self.out
            self.out.written.connect(self.writeOutput)

            self.inp = OutputCls(Stream.__original__stdin, self)
            Stream.__stdin = self.inp
            self.inp.written.connect(self.writeInput)

            self.err = OutputCls(Stream.__original__stderr, self)
            Stream.__stderr = self.err
            self.err.written.connect(self.writeError)

            self.excepthandler = ExceptionHook(Stream.__original__excepthook)
            Stream.__excepthook = self.excepthandler.excepthook

            sys.stdin = Stream.__stdin
            sys.stdout = Stream.__stdout
            sys.stderr = Stream.__stderr
            sys.excepthook = self.excepthandler.excepthook

            self.excepthandler.excepted.connect(self.writeExcepted)
            self.excepthandler.excepted.connect(self.writeErrorToStream)

            self.err_count = 0
            self.out_count = 0
            self.in_count = 0

    def writeErrorToStream(self, text):
        """
        Write string to error output.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        Stream.__stderr.write(text)
        self.exceptedWritten.emit(text)

    def writeOutputToStream(self, text):
        """
        Write string to output.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        Stream.__stdout.write(text)

    def writeInputToStream(self, text):
        """
        Write string to input output.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        Stream.__stdin.write(text)

    def input(self, text):
        """
        Write input text.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        self.writeInput(text)
        self.writeInput("\n")

    def writeInput(self, text):
        """
        Handle input text.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        self.inputWritten.emit(text)

        if self.in_count < sys.maxint:
            self.in_count += 1

    def writeError(self, text):
        """
        Write error text.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        self.errorWritten.emit(text)

        if self.err_count < sys.maxint:
            self.err_count += 1

    def writeOutput(self, text):
        """
        Write output text.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        self.outputWritten.emit(text)

        if self.out_count < sys.maxint:
            self.out_count += 1

    def writeExcepted(self, text):
        """
        Write excepted.
        """

        # try:
        #     text = unicode(text)
        #
        # except UnicodeDecodeError or UnicodeEncodeError:
        #     text = u"Failed to encode error message..."

        self.exceptedWritten.emit(text)

        if self.err_count < sys.maxint:
            self.err_count += 1
Esempio n. 9
0
class AppClient(QtCore.QObject):

    connected = QtCore.Signal()
    disconnected = QtCore.Signal()
    received = QtCore.Signal(QtCore.QByteArray)

    def __init__(self, port, host="127.0.0.1", parent=None):

        super(AppClient, self).__init__(parent)

        self.__port = port
        self.__host = host

        self.__key = None

        # temp = os.path.abspath(os.environ.get("TEMP", os.path.expanduser("~/temp"))).replace("\\", "/").rstrip("/") + "/AppConnection"
        # if not os.path.exists(temp):
        #     os.makedirs(temp)
        #
        # logging.basicConfig(filename=temp + "/AppClient_{0}.{1}.log".format(host, port), level=logging.INFO, format="%(asctime)s - %(message)s")
        # self.__logger = logging.getLogger("AppClient_{0}.{1}.log".format(host, port))

        self.__blocksize = 0
        self.__blockdata = None
        self.__blockstream = None

        self.__keep_connection = 0
        self.__connection = 0

        self.__connection_timer = QtCore.QTimer(self)
        self.__connection_attempt = 0

        self.__client = None

    def reset(self):

        self.__blocksize = 0
        self.__blockdata = None
        self.__blockstream = None

    def isConnected(self):

        if self.__client:
            state = self.__client.state()
            if state == QtNetwork.QAbstractSocket.UnconnectedState or state == QtNetwork.QAbstractSocket.ClosingState:
                return False

            return True

        return False

    def waitForReadyRead(self):

        return self.__client.waitForReadyRead()

    def waitForConnected(self):

        return self.__client.waitForConnected()

    def run(self):

        # self.__logger.info("connect to server  [{0}]".format(self.__key))
        self.__connection = 1

        if self.__client is None:
            self.__client = QtNetwork.QTcpSocket(self)
            self.__client.connected.connect(self.__connected)
            self.__client.disconnected.connect(self.__disconnected)
            self.__client.readyRead.connect(self.__received)
            self.__client.error.connect(self.__error)

        self.__client.blockSignals(False)
        self.__run()

        self.__connection_timer.timeout.connect(self.__run)
        self.__connection_timer.start(3000)

    def __run(self):

        # self.__logger.info("connect to server  [{0}]".format(self.__key))

        if self.__connection:
            state = self.__client.state()
            if state == QtNetwork.QAbstractSocket.UnconnectedState or state == QtNetwork.QAbstractSocket.ClosingState:
                self.__connection_attempt += 1
                if state == QtNetwork.QAbstractSocket.ConnectedState:
                    self.__connection_timer.stop()
                    self.__connection_attempt = 0

                elif self.__connection_attempt > 10 and not self.__keep_connection:
                    self.__client.abort()
                    self.__connection_timer.stop()
                    self.__connection_attempt = 0

                elif state == QtNetwork.QAbstractSocket.UnconnectedState or state == QtNetwork.QAbstractSocket.HostLookupState:
                    self.__client.connectToHost(
                        QtNetwork.QHostAddress(self.__host), self.__port)

        elif self.__connection_timer.isActive():
            self.__connection_timer.stop()

    def stop(self):

        # self.__logger.info("disconnect from server [{0}]".format(self.__key))
        self.__connection = 0
        if self.__connection_timer.isActive():
            self.__connection_timer.stop()

        if self.__client:
            self.__client.blockSignals(True)
            self.__client.close()
            self.__client.deleteLater()
            del self.__client
            self.__client = None

        self.reset()

        self.blockSignals(True)
        self.deleteLater()

    def __connected(self):

        # self.__logger.info("connected to server [{0}]".format(self.__key))
        if self.__connection_timer.isActive():
            self.__connection_timer.stop()

        self.connected.emit()

    def __disconnected(self):

        # self.__logger.info("disconnected from server [{0}]".format(self.__key))

        if self.__client:
            self.__client.blockSignals(True)
            self.__client.close()
            self.__client.deleteLater()
            del self.__client
            self.__client = None

        self.reset()

        self.disconnected.emit()

        if self.__connection_timer.isActive():
            self.__connection_timer.stop()

        if self.__keep_connection and self.__connection:
            self.run()

    def __received(self):

        # self.__logger.info("receive message from server [{0}]".format(self.__key))
        if self.__client:
            stream = QtCore.QDataStream(self.__client)
            stream.setVersion(QtCore.QDataStream.Qt_4_7)

            while True:
                if not self.__client:
                    break

                if not self.__blocksize:
                    if self.__client.bytesAvailable() < ctypes.sizeof(
                            ctypes.c_long):
                        break

                    self.__blocksize = stream.readUInt64()

                if self.__client.bytesAvailable() < self.__blocksize:
                    break

                if self.__blocksize and self.__blockdata is None:
                    self.__blockdata = QtCore.QByteArray()
                    self.__blockstream = QtCore.QDataStream(
                        self.__blockdata, QtCore.QIODevice.ReadWrite)
                    self.__blockstream.setVersion(QtCore.QDataStream.Qt_4_7)
                    self.__blockstream.writeUInt64(self.__blocksize)

                data = QtCore.QByteArray()
                stream >> data

                if self.__blocksize:
                    self.__blockstream << data
                    if self.__blockdata.size() - ctypes.sizeof(
                            ctypes.c_long) == self.__blocksize:
                        self.__blockstream.device().seek(0)
                        size = self.__blockstream.readUInt64()
                        message = QtCore.QByteArray()
                        self.__blockstream >> message

                        self.__blockdata = None
                        self.__blocksize = 0
                        self.__blockstream = 0

                        # system = 0
                        if message[:7] == "system:":
                            # system = 1
                            if message[:11] == "system:key:" and message.size(
                            ) == 47:
                                self.__key = None
                                try:
                                    self.__key = uuid.UUID(str(message[11:]))

                                except:
                                    self.stop()

                            elif self.__key is None:
                                self.stop()

                            elif message == "system:stop":
                                self.stop()

                        # if system:
                        # self.__logger.info("received system message from server with size " + repr(size) + " [{0}]".format(self.__key))

                        else:
                            # self.__logger.info("received message from server with size " + repr(size) + " [{0}]".format(self.__key))
                            self.received.emit(message)

        # else:
        # self.__logger.warning("can`t receive message from server [{0}]".format(self.__key))

    def send(self, data):

        if self.isConnected():
            # self.__logger.info("send message to server  [{0}]".format(self.__key))
            block = QtCore.QByteArray()

            stream = QtCore.QDataStream(block, QtCore.QIODevice.WriteOnly)
            stream.setVersion(QtCore.QDataStream.Qt_4_7)
            stream.writeUInt64(0)
            stream << QtCore.QByteArray(data)
            stream.device().seek(0)
            stream.writeUInt64(block.size() - ctypes.sizeof(ctypes.c_long))
            stream.device().seek(block.size())
            stream.writeUInt64(0)

            s = 0
            while s < block.size():
                if self.__client.state(
                ) != QtNetwork.QAbstractSocket.ConnectedState:
                    # self.__logger.warning("is not connected to server [{0}]".format(self.__key))
                    break

                w = self.__client.write(block)
                s += w

        # else:
        #     self.__logger.warning("is not connected to server [{0}]".format(self.__key))

    def __error(self):

        # self.__logger.warning("error  [{0}]".format(self.__key))
        if self.__client.state() == QtNetwork.QAbstractSocket.UnconnectedState:
            restore = True

        else:
            self.__client.abort()
            restore = True

        if restore and self.__keep_connection and self.__connection:
            self.reset()
            # self.__connection_timer.timeout.connect(self.__run)
            self.__connection_timer.start(3000)
        elif self.__connection_timer.isActive():
            self.__connection_timer.stop()

    def setKeepConnection(self, value):

        if value:
            self.__keep_connection = 1

        else:
            self.__keep_connection = 0

    def keepConnection(self):

        if self.__keep_connection:
            return True

        return False
Esempio n. 10
0
class ThreadsPool(QtCore.QThread):
    # TODO add wake-up timer

    finished = QtCore.Signal()
    started = QtCore.Signal()

    def __init__(self, max_threads=1, parent=None):
        super(ThreadsPool, self).__init__(parent=parent)

        self.max_threads = max_threads
        self.poll_time = 10

        self._op_queue = []
        self._threads = []
        self._thread_free = 0
        self._started = False

    def reset_poll_timer(self):
        self.poll_time = self.idle_poll_time

    @property
    def is_started(self):
        return self._started

    @property
    def is_stopped(self):
        return not self._started

    def add_task(self, func, *args, **kwargs):

        if self._started:
            op = OperationWorker(func, *args, **kwargs)
            self._op_queue.append(op)
            return op

    def start(self):
        self._started = True

        self._threads = []
        for i in range(self.max_threads):
            self._threads.append(OperationThread(self))
            self._threads[i].start()
            self._thread_free += 1

        super(ThreadsPool, self).start()

    def exit(self):
        # frees ops queue and waits while queued threads running
        # stops polling
        self._started = False
        self._op_queue = []
        self._thread_free = 0

        for op_thread in self._threads:
            op_thread.stop_tasks()
            op_thread.exit()
            op_thread.wait()

        self._threads = []

        super(ThreadsPool, self).exit()

    def run(self):
        self.started.emit()
        while self._started:
            self.msleep(self.poll_time)
            for op_thread in self._threads:
                if op_thread.is_free:
                    if self._op_queue:
                        op = self._op_queue.pop(0)
                        op_thread.add(op)

                        self._thread_free -= 1
                    else:
                        self._thread_free += 1
                else:
                    self.finished.emit()
Esempio n. 11
0
class Ui_topBarWidget(QtGui.QWidget):
    hamburger_clicked = QtCore.Signal()

    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.current_project = None
        self.shown = False
        self.hamburger_connected_method = None

        self.create_ui()

    def create_ui(self):

        self.create_layout()

        self.create_hamburger_button()

        self.create_project_icon_widget()
        self.create_projects_combo()

        self.create_spacer()

        self.create_info_label()

        self.create_user_icon_widget()
        self.create_config_button()

        self.fill_config_menu()
        # self.fill_projects_menu()

    def create_layout(self):
        self.main_layout = QtGui.QHBoxLayout()
        self.setLayout(self.main_layout)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)

    def create_info_label(self):
        self.info_label = QtGui.QLabel()
        self.info_label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
        self.info_label.setText('')
        self.loading_tool_button = QtGui.QToolButton()
        self.loading_tool_button.setStyleSheet('QToolButton {border: 0px;background: transparent;}')
        self.loading_tool_button.setIcon(gf.get_icon('loading', icons_set='mdi', scale_factor=1, spin=[self.loading_tool_button, 30, 45]))

        self.main_layout.addWidget(self.info_label)
        self.main_layout.addWidget(self.loading_tool_button)

    def set_current_project(self, project=None):

        self.current_project = project

        if self.current_project:
            self.hamburger_tab_button.setHidden(False)
            self.projects_chooser_button.setText(self.current_project.info.get('title'))
            self.fill_project_icon()
            self.fill_user_icon()
        else:
            self.hamburger_tab_button.setHidden(True)
            self.projects_chooser_button.setText('Projects')
            self.fill_project_icon()
            self.fill_user_icon()

    def set_info_status_text(self, status_text=''):
        self.info_label.setText(status_text)
        if status_text == '':
            self.loading_tool_button.setHidden(True)
        else:
            self.loading_tool_button.setHidden(False)

    def create_hamburger_button(self):

        self.hamburger_tab_button = StyledToolButton(shadow_enabled=True, size='small', square_type=True)
        self.hamburger_tab_button.setIcon(gf.get_icon('menu', icons_set='mdi', scale_factor=1.2))
        self.hamburger_tab_button.clicked.connect(self.hamburger_tab_button_click)
        self.hamburger_tab_button.setHidden(True)

        self.left_buttons_layout = QtGui.QHBoxLayout()
        self.left_buttons_layout.setContentsMargins(0, 0, 0, 0)
        self.left_buttons_layout.setSpacing(0)

        self.left_buttons_widget = QtGui.QWidget(self)
        self.left_buttons_widget.setLayout(self.left_buttons_layout)
        self.left_buttons_widget.setMinimumSize(60, 36)

        self.left_buttons_layout.addWidget(self.hamburger_tab_button)

        self.main_layout.addWidget(self.left_buttons_widget)

    def hamburger_tab_button_click(self):
        self.hamburger_clicked.emit()

    def connect_hamburger(self, method):
        if self.hamburger_connected_method:
            self.hamburger_clicked.disconnect(self.hamburger_connected_method)

        self.hamburger_connected_method = method
        self.hamburger_clicked.connect(self.hamburger_connected_method)

    def create_project_icon_widget(self):
        self.project_icon_widget = Ui_projectIconWidget()

        effect = QtGui.QGraphicsOpacityEffect(self)
        effect.setOpacity(0.7)
        self.project_icon_widget.setGraphicsEffect(effect)

        self.main_layout.addWidget(self.project_icon_widget)

    def fill_project_icon(self):

        self.project_icon_widget.set_project(self.current_project)
        self.project_icon_widget.fill_info()

    def fill_user_icon(self):

        self.user_icon_widget.set_login(env_inst.get_current_login_object())

    def create_spacer(self):
        spacer_item = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Ignored)
        self.main_layout.addItem(spacer_item)

    def create_config_button(self):
        self.config_button = StyledToolButton()
        self.config_button.setPopupMode(QtGui.QToolButton.InstantPopup)
        self.config_button.setArrowType(QtCore.Qt.NoArrow)

        self.config_button.setIcon(gf.get_icon('settings', icons_set='mdi'))

        self.main_layout.addWidget(self.config_button)

    def create_user_icon_widget(self):
        self.user_icon_widget = Ui_userIconWidget()

        self.main_layout.addWidget(self.user_icon_widget)

    def create_projects_combo(self):
        self.projects_chooser_button = StyledChooserToolButton()
        self.projects_chooser_button.setText('Projects')

        self.main_layout.addWidget(self.projects_chooser_button)

    def fill_projects_menu(self):
        pass
        # self.menuProject = self.projects_chooser_button.get_menu()
        # self.menuProject.setObjectName("menuProject")
        # self.menuProject.setTitle(u"Projects")

        # self.projects_chooser_button.setMenu(self.menuProject)

    def fill_config_menu(self):

        self.menuConfig = QtGui.QMenu(self.config_button)
        self.menuConfig.setObjectName("menuConfig")
        self.menuConfig.setTitle(u"Menu")

        self.actionConfiguration = QtGui.QAction(self)
        self.actionConfiguration.setObjectName("actionConfiguration")
        self.actionUpdate = QtGui.QAction(self)
        self.actionUpdate.setObjectName("actionUpdate")
        self.actionExit = QtGui.QAction(self)
        self.actionExit.setObjectName("actionExit")
        self.actionApply_to_all_Tabs = QtGui.QAction(self)
        self.actionApply_to_all_Tabs.setObjectName("actionApply_to_all_Tabs")
        self.actionScriptEditor = QtGui.QAction(self)
        self.actionScriptEditor.setObjectName("actionScriptEditor")
        self.actionDock_undock = QtGui.QAction(self)
        self.actionDock_undock.setObjectName("actionDock_undock")
        self.actionDebug_Log = QtGui.QAction(self)
        self.actionDebug_Log.setObjectName("actionDebug_Log")
        self.actionSave_Preferences = QtGui.QAction(self)
        self.actionSave_Preferences.setObjectName("actionSave_Preferences")
        self.actionReloadCache = QtGui.QAction(self)
        self.actionReloadCache.setObjectName("actionReloadCache")

        self.menuConfig.addAction(self.actionConfiguration)
        self.menuConfig.addAction(self.actionSave_Preferences)
        self.menuConfig.addAction(self.actionReloadCache)
        self.menuConfig.addAction(self.actionApply_to_all_Tabs)
        self.menuConfig.addAction(self.actionDock_undock)
        self.menuConfig.addSeparator()
        self.menuConfig.addAction(self.actionScriptEditor)
        self.menuConfig.addAction(self.actionDebug_Log)
        self.menuConfig.addSeparator()
        self.menuConfig.addAction(self.actionUpdate)
        self.menuConfig.addSeparator()
        self.menuConfig.addSeparator()
        self.menuConfig.addAction(self.actionExit)

        self.actionConfiguration.setText(u"Configuration")
        self.actionUpdate.setText(u"Update")
        self.actionExit.setText(u"Exit")
        self.actionApply_to_all_Tabs.setText(u"Current view to All Tabs")
        self.actionScriptEditor.setText(u"Script Editor")
        self.actionDock_undock.setText(u"Dock/undock")
        self.actionDebug_Log.setText(u"Debug Log")
        self.actionSave_Preferences.setText(u"Save Preferences")
        self.actionReloadCache.setText(u"Reload Cache")

        self.actionExit.setIcon(gf.get_icon('window-close', icons_set='mdi'))
        self.actionConfiguration.setIcon(gf.get_icon('settings', icons_set='mdi'))
        self.actionSave_Preferences.setIcon(gf.get_icon('content-save', icons_set='mdi'))
        self.actionReloadCache.setIcon(gf.get_icon('reload', icons_set='mdi'))
        self.actionApply_to_all_Tabs.setIcon(gf.get_icon('hexagon-multiple', icons_set='mdi'))
        self.actionScriptEditor.setIcon(gf.get_icon('script', icons_set='mdi'))
        self.actionDebug_Log.setIcon(gf.get_icon('bug', icons_set='mdi'))
        self.actionUpdate.setIcon(gf.get_icon('update', icons_set='mdi'))

        if env_mode.get_mode() == 'standalone':
            self.actionDock_undock.setVisible(False)

        self.config_button.setMenu(self.menuConfig)
        self.config_button.setPopupMode(QtGui.QToolButton.InstantPopup)

    def paintEvent(self, event):
        # Don't know why on maya there goes different events
        if event.type() == QtCore.QEvent.Paint:
            super(Ui_topBarWidget, self).paintEvent(event)
            painter = Qt4Gui.QPainter()
            painter.begin(self)
            rect = self.rect()
            painter.fillRect(rect.x(), rect.y(), rect.width(), rect.height(), Qt4Gui.QColor(48, 48, 48))
class Ui_repoSyncDialog(QtGui.QDialog):
    downloads_finished = QtCore.Signal()
    file_download_done = QtCore.Signal(object)

    def __init__(self, stype, sobject, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.stype = stype
        self.sobject = sobject
        self.togglers = [False, False, False, False]
        self.repo_sync_items = []
        self.sync_tasks = 0
        self.sync_in_progress = False
        self.interrupted = False
        self.auto_close = False

        self.get_all_presets_from_server()

        self.create_ui()

    def create_ui(self):
        if self.sobject:
            self.setWindowTitle('Sync Repo for: {0}'.format(self.sobject.get_title()))
        else:
            self.setWindowTitle('Sync Repo for: {0}'.format(self.stype.get_pretty_name()))
        self.setSizeGripEnabled(True)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)

        self.create_tree_widget()
        self.fill_presets_combo_box()
        self.fill_tree_widget()
        self.fit_to_content_tree_widget()
        self.create_controls()
        self.controls_actions()

        self.create_download_queue()

        self.resize(650, 550)

        self.readSettings()

    def controls_actions(self):

        self.none_button.clicked.connect(lambda: self.switch_items('none'))
        self.all_process_button.clicked.connect(lambda: self.switch_items('process'))
        self.all_with_builtins_button.clicked.connect(lambda: self.switch_items('builtins'))
        self.all_children_button.clicked.connect(lambda: self.switch_items('children'))

        self.tree_widget.itemChanged.connect(self.check_tree_items)
        self.presets_combo_box.currentIndexChanged.connect(self.apply_repo_sync_preset)

        self.start_sync_button.clicked.connect(self.start_sync_ui)

    def create_download_queue(self):
        self.download_queue = Ui_repoSyncQueueWidget(embedded=True)

        self.download_queue.downloads_finished.connect(self.files_downloads_finished)
        self.download_queue.file_download_done.connect(self.file_download_finished)

        self.grid.addWidget(self.download_queue, 0, 2, 4, 2)

    def files_downloads_finished(self):

        self.sync_in_progress = False

        if not self.interrupted:
            self.downloads_finished.emit()

        if self.auto_close:
            self.close()

        self.downloads_progress_bar.setVisible(False)
        self.toggle_ui(True)

    def file_download_finished(self, fl):
        if not self.interrupted:
            self.file_download_done.emit(fl)

            progress = self.downloads_progress_bar.value()
            self.downloads_progress_bar.setValue(progress + 1)
            self.downloads_progress_bar.setFormat(u'%v / %m {}'.format(fl.get_filename_with_ext()))

    def check_tree_items(self, changed_item):
        if len(self.tree_widget.selectedItems()) > 1:
            for item in self.tree_widget.selectedItems():
                item.setCheckState(0, changed_item.checkState(0))

    def switch_items(self, item_type='none'):
        preset_dict = self.get_current_preset_dict()

        if preset_dict:

            if item_type == 'process':
                gf.set_tree_widget_checked_state(
                    self.tree_widget, preset_dict, only_types_tuple=(':{pr}'), state=self.togglers[0]
                )
                self.togglers[0] = not self.togglers[0]

            elif item_type == 'builtins':
                gf.set_tree_widget_checked_state(
                    self.tree_widget, preset_dict, only_types_tuple=(':{b}'), state=self.togglers[1]
                )
                self.togglers[1] = not self.togglers[1]

            elif item_type == 'children':
                gf.set_tree_widget_checked_state(
                    self.tree_widget, preset_dict, only_types_tuple=(':{s}'), state=self.togglers[2]
                )
                self.togglers[2] = not self.togglers[2]

            elif item_type == 'none':
                gf.set_tree_widget_checked_state(
                    self.tree_widget, preset_dict, only_types_tuple=(':{s}', ':{pr}', ':{b}'), state=self.togglers[3]
                )
                self.togglers[3] = not self.togglers[3]

    def create_controls(self):

        self.versionChooserHorizontalLayout = QtGui.QHBoxLayout()
        self.versionChooserHorizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.versionChooserHorizontalLayout.setObjectName("versionChooserHorizontalLayout")

        self.versionlessSyncRadioButton = QtGui.QRadioButton()
        self.versionlessSyncRadioButton.setChecked(True)
        self.versionlessSyncRadioButton.setObjectName("versionlessSyncRadioButton")
        self.versionlessSyncRadioButton.setText('Versionless Sync')

        self.fullSyncRadioButton = QtGui.QRadioButton()
        self.fullSyncRadioButton.setObjectName("fullSyncRadioButton")
        self.fullSyncRadioButton.setText('Full Sync')

        self.versionChooserHorizontalLayout.addWidget(self.versionlessSyncRadioButton)
        self.versionChooserHorizontalLayout.addWidget(self.fullSyncRadioButton)

        self.none_button = QtGui.QPushButton('Toggle All')
        self.none_button.setIcon(gf.get_icon('checkbox-multiple-marked-outline', icons_set='mdi', scale_factor=1))
        self.none_button.setFlat(True)

        self.all_process_button = QtGui.QPushButton('Toggle Process')
        self.all_process_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6))
        self.all_process_button.setFlat(True)

        self.all_with_builtins_button = QtGui.QPushButton('Toggle Builtin Processes')
        self.all_with_builtins_button.setIcon(gf.get_icon('checkbox-blank-circle', icons_set='mdi', scale_factor=0.6))
        self.all_with_builtins_button.setFlat(True)

        self.all_children_button = QtGui.QPushButton('Toggle Children')
        self.all_children_button.setIcon(gf.get_icon('view-sequential', icons_set='mdi', scale_factor=1))
        self.all_children_button.setFlat(True)

        self.togglers_widget = QtGui.QWidget()
        self.togglers_layout = QtGui.QGridLayout()
        self.togglers_layout.setContentsMargins(0, 0, 0, 0)
        self.togglers_layout.setSpacing(6)
        self.togglers_widget.setLayout(self.togglers_layout)

        self.togglers_layout.addWidget(self.none_button, 0, 0, 1, 1)
        self.togglers_layout.addWidget(self.all_process_button, 0, 1, 1, 1)
        self.togglers_layout.addWidget(self.all_with_builtins_button, 1, 0, 1, 1)
        self.togglers_layout.addWidget(self.all_children_button, 1, 1, 1, 1)

        self.togglers_layout.addLayout(self.versionChooserHorizontalLayout, 2, 0, 1, 2)

        # Creating collapsable
        self.controls_collapsable = Ui_collapsableWidget(state=True)
        layout_colapsable = QtGui.QVBoxLayout()
        self.controls_collapsable.setLayout(layout_colapsable)
        self.controls_collapsable.setText('Hide Togglers')
        self.controls_collapsable.setCollapsedText('Show Togglers')
        layout_colapsable.addWidget(self.togglers_widget)

        self.controls_collapsable.collapsed.connect(self.toggle_presets_edit_buttons)

        self.start_sync_button = QtGui.QPushButton('Begin Repo Sync')
        self.start_sync_button.setFlat(True)

        start_sync_color = Qt4Gui.QColor(16, 160, 16)
        start_sync_color_active = Qt4Gui.QColor(16, 220, 16)

        self.start_sync_button.setIcon(gf.get_icon('sync', color=start_sync_color, color_active=start_sync_color_active, icons_set='mdi', scale_factor=1))

        self.progress_bar = QtGui.QProgressBar()
        self.progress_bar.setMaximum(100)
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setHidden(True)

        self.downloads_progress_bar = QtGui.QProgressBar()
        self.downloads_progress_bar.setMaximum(100)
        self.downloads_progress_bar.setTextVisible(True)
        self.downloads_progress_bar.setHidden(True)

        self.grid.addWidget(self.controls_collapsable, 2, 0, 1, 2)
        self.grid.addWidget(self.start_sync_button, 3, 0, 1, 2)
        self.grid.addWidget(self.progress_bar, 4, 0, 1, 4)
        self.grid.addWidget(self.downloads_progress_bar, 5, 0, 1, 4)

    def toggle_presets_edit_buttons(self, state):

        if state:
            self.add_new_preset_button.setHidden(True)
            self.save_new_preset_button.setHidden(True)
            self.remove_preset_button.setHidden(True)
        else:
            self.add_new_preset_button.setHidden(False)
            self.save_new_preset_button.setHidden(False)
            self.remove_preset_button.setHidden(False)

    def set_auto_close(self, auto_close):
        self.auto_close = auto_close

    def create_tree_widget(self):

        self.grid = QtGui.QGridLayout()
        self.grid.setContentsMargins(9, 9, 9, 9)
        self.grid.setSpacing(6)
        self.setLayout(self.grid)

        self.create_presets_combo_box()

        self.tree_widget = QtGui.QTreeWidget(self)
        self.tree_widget.setTabKeyNavigation(True)
        self.tree_widget.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
        self.tree_widget.setAllColumnsShowFocus(True)
        self.tree_widget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.tree_widget.setHeaderHidden(True)
        self.tree_widget.setObjectName('tree_widget')
        self.tree_widget.setAlternatingRowColors(True)
        self.tree_widget.setStyleSheet(gf.get_qtreeview_style())
        self.tree_widget.setRootIsDecorated(True)

        self.grid.addWidget(self.tree_widget, 1, 0, 1, 2)
        self.grid.setRowStretch(1, 1)

    def create_presets_combo_box(self):
        self.grid_presets = QtGui.QGridLayout()

        self.presets_combo_box = QtGui.QComboBox()

        self.add_new_preset_button = QtGui.QToolButton()
        self.add_new_preset_button.setAutoRaise(True)
        self.add_new_preset_button.setIcon(gf.get_icon('plus-box', icons_set='mdi', scale_factor=1.2))
        self.add_new_preset_button.clicked.connect(self.add_new_preset)
        self.add_new_preset_button.setToolTip('Create new Preset and Save (from current state)')
        self.add_new_preset_button.setHidden(True)

        self.save_new_preset_button = QtGui.QToolButton()
        self.save_new_preset_button.setAutoRaise(True)
        self.save_new_preset_button.setIcon(gf.get_icon('content-save', icons_set='mdi', scale_factor=1))
        self.save_new_preset_button.clicked.connect(self.save_preset_to_server)
        self.save_new_preset_button.setToolTip('Save Current Preset Changes')
        self.save_new_preset_button.setHidden(True)

        self.remove_preset_button = QtGui.QToolButton()
        self.remove_preset_button.setAutoRaise(True)
        self.remove_preset_button.setIcon(gf.get_icon('delete', icons_set='mdi', scale_factor=1))
        self.remove_preset_button.clicked.connect(self.delete_preset_from_server)
        self.remove_preset_button.setToolTip('Remove Current Preset')
        self.remove_preset_button.setHidden(True)

        self.grid_presets.addWidget(self.remove_preset_button, 0, 0, 1, 1)
        self.grid_presets.addWidget(self.presets_combo_box, 0, 1, 1, 1)
        self.grid_presets.addWidget(self.save_new_preset_button, 0, 2, 1, 1)
        self.grid_presets.addWidget(self.add_new_preset_button, 0, 3, 1, 1)

        self.grid_presets.setColumnStretch(1, 0)

        self.grid.addLayout(self.grid_presets, 0, 0, 1, 2)

    def fill_presets_combo_box(self, current_preset=None):
        self.presets_combo_box.clear()

        current_idx = 0

        for i, preset in enumerate(self.presets_list):
            self.presets_combo_box.addItem(preset['pretty_preset_name'])
            self.presets_combo_box.setItemData(i, preset['preset_name'])
            if preset['preset_name'] == current_preset:
                current_idx = i

        self.presets_combo_box.setCurrentIndex(current_idx)

    def fill_tree_widget(self):

        self.fill_builtin_processes()
        self.fill_stype_pipeline(self.stype)

        self.fill_children_pipelines_and_processes(self.stype)

    def fill_builtin_processes(self, parent_tree_item=None):
        if not parent_tree_item:
            parent_tree_item_add = self.tree_widget.addTopLevelItem
        else:
            parent_tree_item_add = parent_tree_item.addChild

        # Builtin processes
        for key in ['publish', 'attachment', 'icon']:
            top_item = QtGui.QTreeWidgetItem()
            top_item.setText(0, key.capitalize() + ' (builtin)')
            top_item.setCheckState(0, QtCore.Qt.Checked)
            top_item.setData(1, 0, '{0}:{1}'.format(key, '{b}'))
            parent_tree_item_add(top_item)

    def fill_stype_pipeline(self, stype=None, parent_tree_item=None):
        if not parent_tree_item:
            parent_tree_item_add = self.tree_widget.addTopLevelItem
        else:
            parent_tree_item_add = parent_tree_item.addChild

        if stype.pipeline:
            for stype_pipeline in stype.pipeline.values():
                top_item = QtGui.QTreeWidgetItem()
                title = stype_pipeline.info.get('name')
                if not title:
                    title = stype_pipeline.info.get('code')
                top_item.setText(0, title)
                top_item.setData(1, 0, '{0}:{1}'.format(stype_pipeline.info.get('code'), '{pp}'))
                parent_tree_item_add(top_item)

                for key, val in stype_pipeline.pipeline.items():
                    child_item = QtGui.QTreeWidgetItem()
                    child_item.setText(0, key.capitalize())
                    child_item.setCheckState(0, QtCore.Qt.Unchecked)
                    child_item.setData(1, 0, '{0}:{1}'.format(key, '{pr}'))

                    item_color = Qt4Gui.QColor(200, 200, 200)
                    process = stype_pipeline.get_pipeline_process(key)
                    if process:
                        hex_color = process.get('color')
                        color = None
                        if hex_color:
                            color = gf.hex_to_rgb(hex_color, tuple=True)
                        if color:
                            item_color = Qt4Gui.QColor(*color)
                    child_item.setIcon(0, gf.get_icon('circle', color=item_color, scale_factor=0.55))

                    top_item.addChild(child_item)
                    top_item.setExpanded(True)

    def fill_children_pipelines_and_processes(self, stype=None, parent_tree_item=None):
        if not parent_tree_item:
            parent_tree_item_add = self.tree_widget.addTopLevelItem
        else:
            parent_tree_item_add = parent_tree_item.addChild

        project = self.stype.get_project()
        # Children process
        if stype.schema:
            for child in stype.schema.children:

                child_stype = project.stypes.get(child['from'])
                relationship_type = child.get('type')

                if child_stype:
                    ignored = False
                    if child_stype and relationship_type not in ['many_to_many']:

                        # Breaking recursion
                        # Similar logic in items: check_for_child_recursion()
                        if parent_tree_item:
                            parent = parent_tree_item.parent()

                            # we storing ignore dicts in parent stypes, and checking it, so we break recursion
                            # and also getting as deep as needed when syncing assets
                            if parent:
                                ignore_dict = parent.data(2, QtCore.Qt.UserRole)
                                parent_stype = parent.data(3, QtCore.Qt.UserRole)
                                ignore_dict.setdefault('children', []).append(parent_stype.info['code'])
                            else:
                                ignore_dict = {}
                        else:
                            ignore_dict = {}

                        # Already added stypes per child tree
                        if ignore_dict:
                            if ignore_dict.get('children'):
                                if child_stype.info['code'] in ignore_dict['children']:
                                    ignored = True

                        if not ignored:
                            top_item = QtGui.QTreeWidgetItem()
                            top_item.setText(0, child_stype.get_pretty_name() + ' (child)')
                            # Making items unchecked by default, because someone can sync all repo in chain
                            top_item.setCheckState(0, QtCore.Qt.Unchecked)
                            top_item.setData(1, 0, '{0}:{1}'.format(child_stype.get_code(), '{s}'))

                            # setting ignore dicts and stype for top item
                            top_item.setData(2, QtCore.Qt.UserRole, ignore_dict)
                            top_item.setData(3, QtCore.Qt.UserRole, child_stype)

                            clr = child_stype.get_stype_color(tuple=True)
                            stype_color = None
                            if clr:
                                stype_color = Qt4Gui.QColor(clr[0], clr[1], clr[2], 255)
                            top_item.setIcon(0, gf.get_icon('view-sequential', color=stype_color, icons_set='mdi',
                                                            scale_factor=1.1))

                            self.fill_builtin_processes(top_item)
                            self.fill_stype_pipeline(child_stype, top_item)

                            parent_tree_item_add(top_item)

                            self.fill_children_pipelines_and_processes(child_stype, top_item)

    def fit_to_content_tree_widget(self):

        items_count = 0
        for item in QtGui.QTreeWidgetItemIterator(self.tree_widget):
            if item.value().isExpanded():
                items_count += 1

        row_height = items_count * self.tree_widget.sizeHintForRow(0) + 500
        mouse_pos = Qt4Gui.QCursor.pos()
        self.setGeometry(mouse_pos.x(), mouse_pos.y(), 450, row_height)

    def add_new_preset(self):

        add_preset_dialog = QtGui.QDialog(self)
        add_preset_dialog.setWindowTitle('Save as new Preset {}'.format(self.stype.get_pretty_name()))
        add_preset_dialog.setMinimumSize(320, 80)
        add_preset_dialog.setMaximumSize(450, 80)

        add_preset_dialog_layout = QtGui.QVBoxLayout()
        add_preset_dialog.setLayout(add_preset_dialog_layout)

        add_preset_dialog_line_edit = QtGui.QLineEdit('New Preset')

        add_preset_dialog_button = QtGui.QPushButton('Create and Save')

        add_preset_dialog_layout.addWidget(add_preset_dialog_line_edit)
        add_preset_dialog_layout.addWidget(add_preset_dialog_button)

        add_preset_dialog_button.clicked.connect(lambda: self.save_preset_to_server(
            preset_name=add_preset_dialog_line_edit.text().lower().replace(' ', '_'),
            pretty_preset_name=add_preset_dialog_line_edit.text()
        ))
        add_preset_dialog_button.clicked.connect(add_preset_dialog.close)

        add_preset_dialog.exec_()
        # self.fill_presets_combo_box()

    def get_current_preset_name(self):
        current_index = self.presets_combo_box.currentIndex()
        return self.presets_combo_box.itemData(current_index)

    def get_current_preset_dict(self):
        preset_dict = self.get_preset_config(self.get_current_preset_name(), json=False)
        return preset_dict['data']

    def get_preset_dict_by_type(self, type='pipeline', preset_dict=None, only_enabled=False):
        result_preset_dict = {}

        if type == 'pipeline':
            for name, preset in preset_dict.items():
                if name.endswith(':{pp}'):
                    result_preset_dict[name.replace(':{pp}', '')] = preset

        if type == 'builtin':
            for name, preset in preset_dict.items():
                if name.endswith(':{b}'):
                    if only_enabled:
                        if preset['state']:
                            result_preset_dict[name.replace(':{b}', '')] = preset
                    else:
                        result_preset_dict[name.replace(':{b}', '')] = preset

        if type == 'process':
            for name, preset in preset_dict.items():
                if name.endswith(':{pr}'):
                    if only_enabled:
                        if preset['state']:
                            result_preset_dict[name.replace(':{pr}', '')] = preset
                    else:
                        result_preset_dict[name.replace(':{pr}', '')] = preset

        if type == 'child':
            for name, preset in preset_dict.items():
                if name.endswith(':{s}'):
                    if only_enabled:
                        if preset['state']:
                            result_preset_dict[name.replace(':{s}', '')] = preset
                    else:
                        result_preset_dict[name.replace(':{s}', '')] = preset

        return result_preset_dict

    def apply_repo_sync_preset(self, current_index=None, preset_name=None):

        if not preset_name:
            preset_name = self.presets_combo_box.itemData(current_index)

        preset_dict = self.get_preset_by_name(preset_name)

        if preset_dict:
            # Pipeline items should not have check state, filter it with {pp} tag
            gf.set_tree_widget_checked_state(self.tree_widget, preset_dict, ignore_types_tuple=(':{pp}'))

            if preset_dict.get('get_versions'):
                if preset_dict['get_versions']:
                    self.fullSyncRadioButton.setChecked(True)
                else:
                    self.versionlessSyncRadioButton.setChecked(True)
            else:
                self.versionlessSyncRadioButton.setChecked(True)

    def get_preset_by_name(self, preset_name):
        # Only used on initial items filling
        if self.presets_list:
            for preset in self.presets_list:
                if preset['preset_name'] == preset_name:
                    return preset

    def get_all_presets_from_server(self):

        server = tc.server_start()

        key = 'search_type:{0}'.format(self.stype.get_code())

        search_type = 'sthpw/wdg_settings'

        project_code = self.stype.get_project().get_code()

        filters = [('key', 'like', '{0}%'.format(key)), ('project_code', project_code)]
        columns = ['data']

        presets = server.query(search_type, filters, columns)

        if not presets:
            self.presets_list = [
                {
                    'pretty_preset_name': 'Default',
                    'preset_name': 'default',
                }
            ]
        else:

            new_presets_list = []
            for preset in presets:
                new_presets_list.append(gf.from_json(preset['data']))

            self.presets_list = new_presets_list

    def get_preset_config(self, preset_name=None, pretty_preset_name=None, json=True):

        if not preset_name:
            preset_name = 'default'

        if not pretty_preset_name:
            pretty_preset_name = preset_name.capitalize().replace('_', ' ')

        # Preparing preset data
        preset_dict = {
            'preset_name': preset_name,
            'pretty_preset_name': pretty_preset_name,
            'get_versions': self.fullSyncRadioButton.isChecked()
        }
        gf.get_tree_widget_checked_state(self.tree_widget, preset_dict)

        key = 'search_type:{0}:preset_name:{1}'.format(self.stype.get_code(), preset_name)

        if json:
            data_dict = gf.to_json(preset_dict)
        else:
            data_dict = preset_dict

        data = {
            'data': data_dict,
            'key': key,
            'login': '******',
            'project_code': self.stype.get_project().get_code(),
        }

        return data

    def add_file_objects_to_queue(self, files_objects_list):

        for file_object in files_objects_list:
            self.repo_sync_items.append(self.download_queue.schedule_file_object(file_object))

        self.download_queue.files_num_label.setText(
            str(self.download_queue.files_queue_tree_widget.topLevelItemCount())
        )

    def get_presets_list(self):
        return self.presets_list

    def download_files(self):

        self.downloads_progress_bar.setVisible(True)

        if not self.interrupted:
            for repo_sync_item in self.repo_sync_items:
                repo_sync_item.download()
                self.download_queue.files_num_label.setText(
                    str(self.download_queue.files_queue_tree_widget.topLevelItemCount())
                )

            self.downloads_progress_bar.setMaximum(len(self.repo_sync_items))

        if not self.repo_sync_items:
            self.files_downloads_finished()

    def clear_queue(self):
        self.download_queue.clear_queue()
        self.repo_sync_items = []

    def start_sync(self, preset_dict=None):
        self.sync_in_progress = True
        # it is recommended to use finished signal
        if not preset_dict:
            preset_dict = self.get_current_preset_dict()

        self.clear_queue()
        self.sobject.update_snapshots()

        self.sync_by_pipeline(self.sobject, preset_dict)
        self.sync_children(self.sobject, preset_dict)

        # self.download_files()

    def start_sync_ui(self, preset_dict=None):

        self.show()

        self.sync_in_progress = True

        self.progress_bar.setHidden(False)
        self.toggle_ui(False)

        self.clear_queue()
        if not preset_dict:
            preset_dict = self.get_current_preset_dict()

        if self.sobject:
            self.progress_bar.setValue(0)
            self.progress_bar.setFormat(u'Getting: {0}'.format(self.sobject.get_title()))

            self.update_sobject_snapshots_threaded(self.sobject, preset_dict)

            self.sync_children(self.sobject, preset_dict)
            self.save_last_sync_date()
        else:
            self.progress_bar.setValue(0)
            self.progress_bar.setFormat(u'Getting all: {0}'.format(self.stype.get_pretty_name()))

            self.update_sobjects_threaded(preset_dict)

        # self.download_files()
        # self.progress_bar.setHidden(True)
        # self.toggle_ui(True)

    def check_sync_tasks(self):
        if self.sync_tasks == 0:
            self.progress_bar.setHidden(True)
            self.download_files()

    def do_sync_all_sobjects(self, result):

        sobjects, query_info, preset_dict = result

        for sobject in sobjects.values():

            total = query_info['total_sobjects_query_count']
            self.progress_bar.setMaximum(total)
            progress = self.progress_bar.value()
            self.progress_bar.setValue(progress + 1)
            self.progress_bar.setFormat(u'%v / %m {}'.format(sobject.get_title()))

            self.update_sobject_snapshots_threaded(sobject, preset_dict)
            self.sync_children(sobject, preset_dict)

            self.save_last_sync_date(sobject)

        self.sync_tasks -= 1
        self.check_sync_tasks()

    def update_sobjects_threaded(self, preset_dict):
        worker = env_inst.server_pool.add_task(
            tc.get_sobjects,
            self.stype.get_code(),
            [],
            project_code=self.stype.project.get_code(),
            get_all_snapshots=True
        )

        worker.add_result_data(preset_dict)
        worker.result.connect(self.do_sync_all_sobjects)
        worker.error.connect(gf.error_handle)
        worker.start()

        self.sync_tasks += 1

    def update_sobject_snapshots_threaded(self, sobject, preset_dict):

        if preset_dict.get('only_updates'):
            worker = env_inst.server_pool.add_task(sobject.update_snapshots, filters=[('timestamp', 'is after', self.get_last_sync_date())])
        else:
            worker = env_inst.server_pool.add_task(sobject.update_snapshots)

        worker.finished.connect(partial(self.sync_by_pipeline, sobject, preset_dict))
        worker.error.connect(gf.error_handle)
        worker.start()

        self.sync_tasks += 1

    def interrupt_sync_process(self):
        self.interrupted = True

    def toggle_ui(self, enable=False):
        self.start_sync_button.setEnabled(enable)
        self.remove_preset_button.setEnabled(enable)
        self.add_new_preset_button.setEnabled(enable)
        self.save_new_preset_button.setEnabled(enable)
        self.controls_collapsable.setEnabled(enable)
        self.presets_combo_box.setEnabled(enable)
        self.download_queue.clear_queue_push_button.setEnabled(enable)

    def sync_by_pipeline(self, sobject=None, preset_dict=None):

        if not sobject:
            sobject = self.sobject

        if not preset_dict:
            preset_dict = self.get_current_preset_dict()

        current_pipeline_preset_dict = self.get_preset_dict_by_type('pipeline', preset_dict)
        current_builtin_preset_dict = self.get_preset_dict_by_type('builtin', preset_dict, True)

        if current_pipeline_preset_dict:
            for pipeline_name, preset in current_pipeline_preset_dict.items():
                self.sync_by_sobject(sobject, preset.get('sub'), current_builtin_preset_dict)
        elif current_builtin_preset_dict:
            self.sync_by_sobject(sobject, {}, current_builtin_preset_dict)

        self.sync_tasks -= 1
        self.check_sync_tasks()

    def sync_children(self, sobject=None, preset_dict=None):
        if not preset_dict:
            preset_dict = self.get_current_preset_dict()

        children_preset_dict = self.get_preset_dict_by_type('child', preset_dict, True)

        for child_code, children_preset in children_preset_dict.items():
            self.get_related_sobjects_threaded(sobject, child_code, children_preset)

    def get_related_sobjects_threaded(self, sobject, child_code, children_preset):

        stype = sobject.get_stype()
        project_obj = stype.get_project()

        worker = env_inst.server_pool.add_task(
            sobject.get_related_sobjects,
            child_stype=project_obj.stypes.get(child_code),
            parent_stype=stype,
            get_all_snapshots=True
        )

        worker.add_result_data(children_preset)
        worker.result.connect(self.do_get_related_sobjects)
        worker.error.connect(gf.error_handle)
        worker.start()

        self.sync_tasks += 1

    def do_get_related_sobjects(self, result):

        related_sobjects, query_info, children_preset = result

        if related_sobjects:
            for related_sobject in related_sobjects.values():
                self.update_sobject_snapshots_threaded(related_sobject, children_preset.get('sub'))
                self.sync_children(related_sobject, children_preset.get('sub'))

                total = query_info['total_sobjects_query_count']
                self.progress_bar.setMaximum(total)
                progress = self.progress_bar.value()
                self.progress_bar.setValue(progress + 1)
                self.progress_bar.setFormat(u'%v / %m {}'.format(related_sobject.get_title()))

        self.sync_tasks -= 1
        self.check_sync_tasks()

    def sync_by_sobject(self, sobject=None, sync_preset_dict=None, builtin_preset_dict=None):

        process_objects = sobject.get_all_processes()
        enabled_processes = self.get_preset_dict_by_type('process', sync_preset_dict, True)

        versionless_list = []
        versions_list = []

        versionless_only = self.versionlessSyncRadioButton.isChecked()

        if builtin_preset_dict:
            all_precesses = dict(tuple(enabled_processes.items()) + tuple(builtin_preset_dict.items()))
        else:
            all_precesses = enabled_processes

        self.progress_bar.setMaximum(len(process_objects.items()))

        for process_name, process_object in process_objects.items():

            progress = self.progress_bar.value()
            self.progress_bar.setValue(progress + 1)
            self.progress_bar.setFormat(u'%v / %m {}'.format('{0}: {1}'.format(sobject.get_title(), process_name)))

            if not self.interrupted:

                if process_name in list(all_precesses.keys()):
                    contexts = process_object.get_contexts()
                    for context, context_obj in contexts.items():

                        versionless_snapshots = context_obj.get_versionless()
                        for code, snapshot in versionless_snapshots.items():
                            versionless_list.extend(snapshot.get_files_objects())

                        if not versionless_only:
                            versions_snapshots = context_obj.get_versions()
                            for code, snapshot in versions_snapshots.items():
                                versions_list.extend(snapshot.get_files_objects())

        if versionless_only:
            self.add_file_objects_to_queue(versionless_list)
        else:
            self.add_file_objects_to_queue(versionless_list)
            self.add_file_objects_to_queue(versions_list)

    def delete_preset_from_server(self, preset_name=None):

        if not preset_name:
            idx = self.presets_combo_box.currentIndex()
            preset_name = self.presets_combo_box.itemData(idx)

        # ask before delete
        buttons = (('Yes', QtGui.QMessageBox.YesRole), ('Cancel', QtGui.QMessageBox.NoRole))

        reply = gf.show_message_predefined(
            'Removing preset from server',
            u'Are You sure want to remove <b>" {0} "</b> preset from Server?'.format(preset_name),
            buttons=buttons,
            message_type='question',
            parent=self
        )

        if reply == QtGui.QMessageBox.YesRole:

            server = tc.server_start()

            data = self.get_preset_config(preset_name)
            search_type = 'sthpw/wdg_settings'

            # Checking for existing key
            filters = [('key', data['key'])]
            columns = ['code', 'project']

            widget_settings = server.query(search_type, filters, columns, single=True)

            search_key = widget_settings['__search_key__']

            server.delete_sobject(search_key)

            self.get_all_presets_from_server()
            self.fill_presets_combo_box(preset_name)

    def save_preset_to_server(self, preset_name=None, pretty_preset_name=None):

        if not preset_name:
            idx = self.presets_combo_box.currentIndex()
            preset_name = self.presets_combo_box.itemData(idx)

        server = tc.server_start()

        data = self.get_preset_config(preset_name, pretty_preset_name)
        search_type = 'sthpw/wdg_settings'

        # Checking for existing key
        filters = [('key', data['key'])]
        columns = ['code', 'project']

        widget_settings = server.query(search_type, filters, columns, single=True)

        if widget_settings:
            code = widget_settings['code']
            project = widget_settings['project']
            search_key = server.build_search_key(search_type, code, project)

            server.insert_update(search_key, data, triggers=False)
        else:
            server.insert(search_type, data, triggers=False)

        self.get_all_presets_from_server()
        self.fill_presets_combo_box(preset_name)

    def get_settings_dict(self):
        settings_dict = {
            'presets_combo_box': self.presets_combo_box.currentIndex(),
        }
        return settings_dict

    def set_settings_from_dict(self, settings_dict=None):
        ref_settings_dict = {
            'presets_combo_box': 0,
        }

        settings = gf.check_config(ref_settings_dict, settings_dict)

        initial_index = self.presets_combo_box.currentIndex()

        self.presets_combo_box.setCurrentIndex(int(settings['presets_combo_box']))

        if initial_index == int(settings['presets_combo_box']):
            self.apply_repo_sync_preset(initial_index)

    def get_last_sync_date(self, sobject=None):

        if not sobject:
            sobject = self.sobject

        group_path = 'ui_search/{0}/{1}/{2}/sobjects_conf'.format(
            self.stype.project.info['type'],
            self.stype.project.info['code'],
            self.stype.get_code().split('/')[1]
        )

        return env_read_config(filename=sobject.get_code(),
            unique_id=group_path,
            long_abs_path=True
        )

    def save_last_sync_date(self, sobject=None):

        if not sobject:
            sobject = self.sobject

        group_path = 'ui_search/{0}/{1}/{2}/sobjects_conf'.format(
            self.stype.project.info['type'],
            self.stype.project.info['code'],
            self.stype.get_code().split('/')[1]
        )

        current_datetime = QtCore.QDateTime.currentDateTime()
        env_write_config(
            current_datetime.toString('yyyy.MM.dd hh:mm:ss'),
            filename=sobject.get_code(),
            unique_id=group_path,
            long_abs_path=True
        )

    def refresh_search_widget(self):

        checkin_out = env_inst.get_check_tree(self.stype.get_project().get_code(), 'checkin_out', self.stype.get_code())

        if checkin_out:
            checkin_out.refresh_current_results()

    def readSettings(self):
        group_path = 'ui_search/{0}/{1}/{2}'.format(
            self.stype.project.info['type'],
            self.stype.project.info['code'],
            self.stype.get_code().split('/')[1]
        )
        self.set_settings_from_dict(
            env_read_config(
                filename='repo_sync',
                unique_id=group_path,
                long_abs_path=True
            )
        )

    def writeSettings(self):
        group_path = 'ui_search/{0}/{1}/{2}'.format(
            self.stype.project.info['type'],
            self.stype.project.info['code'],
            self.stype.get_code().split('/')[1]
        )
        env_write_config(
            self.get_settings_dict(),
            filename='repo_sync',
            unique_id=group_path,
            long_abs_path=True
        )

    def closeEvent(self, event):
        if not self.sync_in_progress:
            self.writeSettings()
            self.deleteLater()
            self.refresh_search_widget()
            event.accept()
        else:
            buttons = (('Ok', QtGui.QMessageBox.NoRole), ('Interrupt', QtGui.QMessageBox.ActionRole))
            reply = gf.show_message_predefined(
                title='Download in Progress',
                message='Some files are not yet Downloaded.\nInterrupt the Sync Process?.',
                buttons=buttons,
                parent=self,
                message_type='question',
            )

            if reply == QtGui.QMessageBox.ActionRole:
                self.interrupt_sync_process()
                self.deleteLater()
                event.accept()
            else:
                event.ignore()
class Ui_repoSyncQueueWidget(QtGui.QMainWindow):
    downloads_finished = QtCore.Signal()
    file_download_done = QtCore.Signal(object)

    def __init__(self, embedded=False, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.embedded = embedded

        self.queue_dict = {}
        self.total_downloading_count = 0
        self.total_downloaded_count = 0
        self.network_manager = QtNetwork.QNetworkAccessManager(self)
        self.network_manager.finished.connect(self.network_manager_finished)

        if self.embedded:
            self.create_embedded_ui()
        else:
            self.create_ui()

    def create_ui(self):
        self.setWindowTitle('Repository Sync Queue')

        self.statusbar = QtGui.QStatusBar(self)
        self.statusbar.setObjectName('statusbar')
        self.setStatusBar(self.statusbar)

        self.setWindowFlags(QtCore.Qt.Window)
        self.resize(350, 700)

        self.create_main_layout()
        self.create_controls_layout()

        self.create_controls()
        self.create_tree_widget()

        self.controls_actions()

    def controls_actions(self):
        self.clear_queue_push_button.clicked.connect(self.clear_queue)

    def create_embedded_ui(self):

        self.create_main_layout()
        self.main_layout.setContentsMargins(3, 0, 3, 0)
        self.create_controls_layout()

        self.create_controls()
        self.create_tree_widget()
        self.controls_actions()

    def create_main_layout(self):
        self.central_widget = QtGui.QWidget(self)
        self.central_widget.setObjectName('central_widget')

        self.main_layout = QtGui.QGridLayout(self.central_widget)
        self.main_layout.setContentsMargins(9, 9, 9, 9)
        self.main_layout.setSpacing(0)
        self.main_layout.setObjectName('main_layout')

        self.central_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.central_widget)

    def create_controls_layout(self):
        self.controls_layout = QtGui.QGridLayout()
        self.controls_layout.setContentsMargins(0, 0, 0, 0)
        self.controls_layout.setSpacing(6)
        self.controls_layout.setObjectName('controls_layout')

        self.main_layout.addLayout(self.controls_layout, 0, 0, 1, 1)

    def create_controls(self):

        self.clear_queue_push_button = QtGui.QPushButton('Clear Queue')
        self.clear_queue_push_button.setMinimumSize(QtCore.QSize(120, 0))
        self.clear_queue_push_button.setObjectName('clear_queue_push_button')
        self.clear_queue_push_button.setIcon(gf.get_icon('delete', icons_set='mdi'))
        self.clear_queue_push_button.setFlat(True)

        self.files_count_label = QtGui.QLabel('Downloads in Queue: ')
        self.files_count_label.setObjectName('files_count_label')

        self.files_num_label = QtGui.QLabel('')
        self.files_num_label.setObjectName("files_num_label")

        self.controls_layout.addWidget(self.files_count_label, 0, 0)
        self.controls_layout.addWidget(self.files_num_label, 0, 1)
        self.controls_layout.addWidget(self.clear_queue_push_button, 0, 2)

    def create_tree_widget(self):
        self.files_queue_tree_widget = QtGui.QTreeWidget()
        self.files_queue_tree_widget.setMinimumSize(QtCore.QSize(300, 0))
        self.files_queue_tree_widget.setRootIsDecorated(False)
        self.files_queue_tree_widget.setHeaderHidden(True)
        self.files_queue_tree_widget.setObjectName('files_queue_tree_widget')
        self.files_queue_tree_widget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.files_queue_tree_widget.setStyleSheet(gf.get_qtreeview_style())
        self.main_layout.addWidget(self.files_queue_tree_widget)

    def create_progress_bar_widget(self):

        self.progress_bar_widget = QtGui.QProgressBar()
        self.progress_bar_widget.setTextVisible(True)
        self.progress_bar_widget.setVisible(True)
        self.progress_bar_widget.setHidden(True)
        self.statusbar.addPermanentWidget(self.progress_bar_widget)

    def set_progress_indicator_on(self):
        self.progress_bar_widget.setHidden(False)

    def set_progress_indicator_off(self):
        self.progress_bar_widget.setHidden(True)
        self.statusbar.showMessage('')

    def set_progress(self, progress, info_dict):
        self.progress_bar_widget.setMaximum(info_dict['total_count'])
        self.statusbar.showMessage(info_dict['status_text'])
        self.progress_bar_widget.setValue(progress + 1)
        if self.progress_bar_widget.maximum() == progress + 1:
            self.set_progress_indicator_off()

    def clear_queue(self):
        self.files_queue_tree_widget.clear()
        self.queue_dict = {}
        self.files_num_label.setText('')
        self.total_downloaded_count = 0
        self.total_downloading_count = 0

    def remove_item_from_queue(self, commit_item=None):

        self.queue_list.remove(commit_item)
        commit_item.close()
        commit_item.deleteLater()
        self.files_queue_tree_widget.takeTopLevelItem(self.files_queue_tree_widget.currentIndex().row())
        self.check_queue()

    def network_manager_finished(self, reply):
        file_object = reply.request().attribute(QtNetwork.QNetworkRequest.User)

        if reply.error() == QtNetwork.QNetworkReply.NoError:
            self.do_download_file_object(file_object, reply)
        else:
            repo_sync_item = self.queue_dict.get(file_object.get_unique_id())
            repo_sync_item.set_download_failed()

    def emit_if_all_downloads_done(self):
        if self.total_downloading_count == self.total_downloaded_count:
            self.downloads_finished.emit()

    def is_all_downloads_done(self):
        return self.total_downloading_count == self.total_downloaded_count

    def do_download_file_object(self, file_object, reply):

        # print(type(reply.readAll()))

        repo_sync_item = self.queue_dict.get(file_object.get_unique_id())

        info_dict = {
            'status_text': 'Downloading File',
            'total_count': 4
        }
        repo_sync_item.download_progress(3, info_dict)

        full_abs_path = file_object.prepare_repo()
        with open(full_abs_path, "wb") as downloaded_file:
            downloaded_file.write(bytearray(reply.readAll()))

        repo_sync_item.download_progress(4, info_dict)

        downloaded_file.close()
        repo_sync_item.set_download_finished()

        reply.deleteLater()

    def increment_downloaded(self, fl=None):
        self.total_downloaded_count += 1
        self.emit_if_all_downloads_done()

        self.file_download_done.emit(fl)

    def schedule_file_object(self, file_object):

        # If we already downloaded particular file object, make a new instance of it
        if file_object.get_unique_id() in list(self.queue_dict.keys()):
            file_object = copy.copy(file_object)

        self.total_downloading_count += 1
        repo_sync_item = gf.add_repo_sync_item(self.files_queue_tree_widget, file_object)
        self.queue_dict[file_object.get_unique_id()] = repo_sync_item
        repo_sync_item.set_network_manager(self.network_manager)
        self.files_queue_tree_widget.scrollToBottom()
        repo_sync_item.downloaded.connect(self.increment_downloaded)

        return repo_sync_item
Esempio n. 14
0
class ExceptionHook(QtCore.QObject):
    
    excepted = QtCore.Signal(object)
    instance = None
    
    def __init__(self, excepthook, parent=None):

        super(ExceptionHook, self).__init__(parent)

        ExceptionHook.instance = self
        self.__excepthook = excepthook  # Backup original excepthook object.
        
    @staticmethod
    def __get_excepthook(*args):

        exception_type, exception_value, exception_traceback = None, None, None
        for arg in args:
            if isinstance(arg, type):
                exception_type = arg

            elif isinstance(arg, BaseException):
                exception_value = arg

            elif isinstance(arg, types.TracebackType):
                exception_traceback = arg

        ZeroDivisionError
        exception_type_string = exception_type is not None and exception_type.__name__ or "UnknownError"
        exception_value_string = exception_value is not None and six.PY2 and (hasattr(exception_value, "message") and exception_value.message) or (hasattr(exception_value, "msg") and exception_value.msg) or "Unknown error handled"

        result = ""
        if exception_type is not None and exception_value is not None and exception_traceback is not None:
            python_traceback = Traceback.get_traceback(exception_traceback)
            result_temp = traceback.format_exception(exception_type, exception_value, python_traceback, limit=10)
            result = ""
            if result_temp:
                if isinstance(result_temp, (list, set, tuple)):
                    result_temp = list(result_temp)

                else:
                    result_temp = [result_temp]

                for result_temp_item in result_temp:
                    if six.PY2 and isinstance(result_temp_item, (basestring, unicode)) or not six.PY2 and isinstance(result_temp_item, str):
                        result += result_temp_item

                    else:
                        try:
                            result += result_temp_item.__repr__()

                        except UnicodeDecodeError or UnicodeEncodeError:
                            try:
                                result += str(result_temp_item)

                            except UnicodeDecodeError or UnicodeEncodeError:
                                result += "(Failed to decode Exception data)"
                    result += "\n"
        if not result:
            result = "Error: " + exception_value_string + "\n" + exception_type_string + ": " + exception_value_string

        return result
        
    def excepthook(self, *args):

        result = ExceptionHook.__get_excepthook(*args)
        self.excepted.emit(result)
        
    @staticmethod
    def request():

        exc_type, exc_value, exc_traceback = sys.exc_info()
        result = ExceptionHook.__get_excepthook(exc_type, exc_value, exc_traceback)
        if ExceptionHook.instance:
            ExceptionHook.instance.excepted.emit(result)
Esempio n. 15
0
class OutputCls(QtCore.QObject):

    written = QtCore.Signal(unicode)
    flushed = QtCore.Signal()

    encoding = locale.getpreferredencoding()

    def __init__(self, std, parent_stream=None, parent=None):
        """
        Initialize default settings.
        """
        # self.__io = open('D:/APS/OneDrive/MEGAsync/TACTIC-handler/stuff.txt', 'w')
        self.__parent_stream = parent_stream

        super(OutputCls, self).__init__(parent)

        self.__std = std
        self.softspace = 0

    def readline(self, *args, **kwargs):
        """
        Read line method.
        """

        return self.__std.readline(*args, **kwargs)

    def stream(self):
        """
        Get parent stream.
        """

        return self.__parent_stream

    def write(self, text):
        """
        Write text message.
        """

        # if text is not None:
        #     if isinstance(text, (str, unicode)):
        #         self.__std.write(text)
        #     else:
        #         self.__std.write(repr(text))

        try:
            self.__std.write(text)
            self.written.emit(text)
        except:
            pass
        finally:
            return text

        # try:
        #     # text = unicode(text).encode('utf-8', errors='ignore')
        #     text = str(text)
        #
        # except UnicodeEncodeError or UnicodeDecodeError:
        #     text = u"Failed to encode error message..."

        # self.written.emit(text)
        # return result

    def writelines(self, line_list):
        """
        Write lines.
        """

        result = self.__std.writelines(line_list)
        for line in line_list:
            # try:
            #     line = unicode(line)
            #
            # except UnicodeEncodeError or UnicodeDecodeError:
            #     line = u"Failed to encode error message..."

            self.written.emit(line)

        return result

    def flush(self, *args, **kwargs):
        """
        Flush
        """
        result = self.__std.flush(*args, **kwargs)
        self.flushed.emit()
        return result
class ExceptionHook(QtCore.QObject):

    excepted = QtCore.Signal(unicode)
    instance = None

    def __init__(self, excepthook, parent=None):

        super(ExceptionHook, self).__init__(parent)

        ExceptionHook.instance = self
        self.__excepthook = excepthook  # Backup original excepthook object.

    @staticmethod
    def __get_excepthook(*args):

        return ExceptionHook.get_traceback()

    def excepthook(self, *args):

        result = ExceptionHook.__get_excepthook(*args)
        self.excepted.emit(result)

    @staticmethod
    def request():

        exc_type, exc_value, exc_traceback = sys.exc_info()
        result = ExceptionHook.__get_excepthook(exc_type, exc_value,
                                                exc_traceback)
        if ExceptionHook.instance:
            ExceptionHook.instance.excepted.emit(result)

    @staticmethod
    def get_traceback():

        result = u""

        # Get information about latest traceback.
        exception_type, exception_value, exception_traceback = sys.exc_info()

        # Get exception as string.
        exception_type_string = exception_type is not None and exception_type.__name__ or u"UnknownError"
        exception_value_string = exception_value is not None and exception_value.message or u"Unknown error handled"

        # Get formatted traceback data.
        if hasattr(traceback, "format_exception"):
            format_traceback = traceback.format_exception(exception_type,
                                                          exception_value,
                                                          exception_traceback,
                                                          limit=100)

        else:
            format_traceback = None

        if format_traceback:
            # Create traceback data list.
            if isinstance(format_traceback, (list, set, tuple)):
                format_traceback_list = list(format_traceback)

            else:
                format_traceback_list = [format_traceback]

            # Create traceback string.
            for format_traceback in format_traceback_list:
                try_unicode = True
                if isinstance(format_traceback, (basestring, unicode)):
                    try:
                        result += format_traceback

                    except Exception as exception_data:
                        try_unicode = True

                else:
                    try:
                        result += format_traceback.__repr__()

                    except Exception as exception_data:
                        try_unicode = True

                if try_unicode:
                    try:
                        result += unicode(format_traceback)

                    except Exception as exception_data:
                        result += u"(Can`t decode Exception data)"

        # Get default traceback string.
        if not result:
            result = u"Error: " + exception_value_string + u"\n" + exception_type_string + u": " + exception_value_string

        # Return traceback string.
        return result
Esempio n. 17
0
class Ui_collapsableWidget(QtGui.QWidget, ui_collapsable.Ui_collapsableWidget):
    collapsed = QtCore.Signal(object)

    def __init__(self, text=None, state=False, parent=None):
        super(self.__class__, self).__init__(parent=parent)

        self.setupUi(self)

        self.collapse_state = False
        self.__collapsedTex = ''
        self.__text = ''

        self.setText(text)
        self.setCollapsed(state)

        self.create_ui()

    def create_ui(self):
        self.collapseToolButton.setMaximumHeight(26)

        self.controls_actions()

        self.custom_style_sheet()

    def custom_style_sheet(self):
        self.collapseToolButton.setStyleSheet(
            'QToolButton {'
            'background: rgba(96, 96, 96, 32);'
            'border: 0px; border-radius: 3px; padding: 0px 0px;'
            'border-left: 2px solid rgb(128, 128, 128); border-right: 2px solid rgb(128, 128, 128);}'
            'QToolButton:pressed {'
            'background: rgba(128, 128, 128, 32)}'
        )

    def controls_actions(self):
        self.collapseToolButton.toggled.connect(self.__toggleCollapseState)

    def setText(self, text):
        self.__text = text
        self.collapseToolButton.setText(self.__text)

    def setCollapsedText(self, text):
        self.__collapsedTex = text
        self.collapseToolButton.setText(self.__collapsedTex)

    def setLayout(self, layout):
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        self.widget.setLayout(layout)

    def setCollapsed(self, state):
        if state:
            self.collapse_state = True
            self.collapseToolButton.setIcon(gf.get_icon('angle-right'))
            self.widget.setHidden(True)
            self.collapseToolButton.setChecked(False)
            if self.__collapsedTex:
                self.setCollapsedText(self.__collapsedTex)
        else:
            self.collapse_state = False
            self.collapseToolButton.setIcon(gf.get_icon('angle-down'))
            self.widget.setHidden(False)
            self.collapseToolButton.setChecked(True)
            self.setText(self.__text)

    def setCollapseState(self, state):
        if state:
            self.collapseToolButton.toggle()

    def __toggleCollapseState(self):
        if self.collapse_state:
            self.setCollapsed(False)
            self.collapsed.emit(False)
        else:
            self.setCollapsed(True)
            self.collapsed.emit(True)

    def isCollapsed(self):
        if self.collapse_state:
            return True
        else:
            return False
Esempio n. 18
0
class OperationWorker(QtCore.QObject):

    started = QtCore.Signal()
    finished = QtCore.Signal()
    error = QtCore.Signal(object)
    result = QtCore.Signal(object)
    progress = QtCore.Signal(object)
    stop = QtCore.Signal(object)

    def __init__(self, func, *args, **kwargs):
        super(OperationWorker, self).__init__()

        self._func = func
        self._args = args
        self._kwargs = kwargs
        self.signals_enabled = True
        self._started = False
        self._result = None
        self._data = None

    @property
    def is_started(self):
        return self._started

    def add_result_data(self, data):
        # will add another data into result output
        # only for tuple output
        self._data = data

    def connect_progress(self, func):
        # attaching progress signal to kwargs
        # func should have "progress_signal" kwarg
        self.progress.connect(func)
        self._kwargs['progress_signal'] = self.progress

    def get_result_data(self):
        return self._data

    def start(self):
        self._started = True

    def retry(self):
        print('This is dummy func, not implemented yet')

    def do_task(self):
        self.started.emit()

        try:
            if self.signals_enabled:

                self._result = self._func(*self._args, **self._kwargs)

                if self._data:
                    result = self._result + (self._data, )
                    self._result = result

                self.result.emit(self._result)
                self.finished.emit()

        except Exception as expected:
            if self.signals_enabled:
                traceback.print_exc(file=sys.stdout)

            stacktrace = traceback.format_exc()
            exception = {
                'exception': expected,
                'stacktrace': stacktrace,
            }
            self.error.emit((exception, self))

        self.deleteLater()
Esempio n. 19
0
class AppServer(QtCore.QObject):

    started = QtCore.Signal()
    finished = QtCore.Signal()
    accepted = QtCore.Signal(QtNetwork.QTcpSocket)
    connected = QtCore.Signal(QtNetwork.QTcpSocket)
    disconnected = QtCore.Signal(QtNetwork.QTcpSocket)
    received = QtCore.Signal(QtNetwork.QTcpSocket, QtCore.QByteArray)

    def __init__(self, port, host="127.0.0.1", parent=None):

        super(AppServer, self).__init__(parent)

        self.__port = port
        self.__host = host

        # temp = os.path.abspath(os.environ.get("TEMP", os.path.expanduser("~/temp"))).replace("\\", "/").rstrip("/") + "/AppConnection"
        # if not os.path.exists(temp):
        #     os.makedirs(temp)
        #
        # logging.basicConfig(filename=temp + "/AppServer_{0}.{1}.log".format(host, port), level=logging.INFO, format="%(asctime)s - %(message)s")
        # self.__logger = logging.getLogger("AppServer_{0}.{1}.log".format(host, port))

        self.__client_data = {}

        self.__server_timer = QtCore.QTimer(self)
        self.__server_timer.setSingleShot(True)
        self.__server_timer.timeout.connect(self.__run)
        self.__server_attempt = 0

        self.__server = None

    def run(self):

        self.__server_attempt = 0
        self.__run()

    def __run_request(self):

        self.__server_timer.start(1000)

    # def __del__(self):
    #
    #     self.stop()

    def __run(self):

        # self.__logger.info("run server")
        if self.__server is None:
            self.__server = QtNetwork.QTcpServer(self)
            self.__server.newConnection.connect(self.__accepted)

        if not self.__server.isListening():
            if self.__port != 0 and self.__host != "":
                port = self.__port
                host = QtNetwork.QHostAddress(self.__host)

                while True:
                    listen = self.__server.listen(host, port)
                    if not listen:
                        listen = self.__server.isListening()

                    if not listen:
                        self.__server_attempt += 1
                        if self.__server_attempt == 3:
                            s_client = AppClient(self.__port, self.__host)
                            s_client.setKeepConnection(False)
                            s_client.connected.connect(
                                lambda c=s_client: c.send("system:stop"))
                            s_client.run()
                            break

                        else:
                            self.__server.close()

                    else:
                        break

                if self.__server.isListening():
                    # self.__logger.info("server is running")
                    self.started.emit()

                elif self.__server_attempt < 3:
                    self.__server_timer.start(1000)

            else:
                # self.__logger.info("server is running")
                self.started.emit()

        else:
            # self.__logger.info("server is running")
            self.started.emit()

    def stop(self):

        # self.__logger.info("stop server")
        key_list = self.__client_data.keys()
        while key_list:
            key = key_list.pop()
            m_client = self.__client_data[key][0]
            self.send(m_client, "system:stop")
            m_client.close()
            m_client.deleteLater()
            del self.__client_data[key]

        self.finished.emit()
        if self.__server:
            self.__server.close()
            self.__server.deleteLater()
            del self.__server
            self.__server = None

    def isListening(self):

        return self.__server and self.__server.isListening() or False

    def broadcast(self, data):

        # self.__logger.info("broadcast message '%s'" % data)
        for key in self.__client_data:
            self.send(self.__client_data[key][0], data)

    def __accepted(self):

        key = uuid.uuid4()

        # self.__logger.info("accepted connection from client [{0}]".format(key))
        if self.__server:
            m_client = self.__server.nextPendingConnection()

            m_client.disconnected.connect(lambda c=m_client: self.__closed(c))
            m_client.connected.connect(lambda c=m_client: self.__connected(c))
            m_client.readyRead.connect(lambda c=m_client: self.__received(c))

            m_client.setProperty("key", key)
            self.__client_data[key] = [m_client, 0, None, None]

            # self.send(m_client, "system:key:" + str(key))

            self.accepted.emit(m_client)

        # else:
        #     self.__logger.info("can`t accept connection from client [{0}]".format(key))

    def __closed(self, m_client):

        # self.__logger.info("client closed")
        if isinstance(m_client, QtNetwork.QTcpSocket):
            self.disconnected.emit(m_client)
            key = m_client.property("key")
            del self.__client_data[key]

            m_client.deleteLater()

            # self.__logger.info("closed connection from client [{0}]".format(key))

    def __connected(self, m_client):

        # self.__logger.info("client connected")
        if isinstance(m_client, QtNetwork.QTcpSocket):
            self.connected.emit(m_client)

            # key = m_client.property("key")
            # self.__logger.info("connection from client [{0}]".format(key))

    def __received(self, m_client):

        key = m_client.property("key")

        # self.__logger.info("receive message from client  [{0}]".format(key))
        stream = QtCore.QDataStream(m_client)
        stream.setVersion(QtCore.QDataStream.Qt_4_7)

        if key in self.__client_data:
            while True:
                if not self.__client_data[key][1]:
                    if m_client.bytesAvailable() < ctypes.sizeof(
                            ctypes.c_long):
                        break

                    self.__client_data[key][1] = stream.readUInt64()

                if m_client.bytesAvailable() < self.__client_data[key][1]:
                    break

                if self.__client_data[key][2] is None:
                    self.__client_data[key][2] = QtCore.QByteArray()
                    self.__client_data[key][3] = QtCore.QDataStream(
                        self.__client_data[key][2], QtCore.QIODevice.ReadWrite)
                    self.__client_data[key][3].setVersion(
                        QtCore.QDataStream.Qt_4_7)
                    self.__client_data[key][3].writeUInt64(
                        self.__client_data[key][1])

                data = QtCore.QByteArray()
                stream >> data

                if self.__client_data[key][1]:
                    self.__client_data[key][3] << data
                    if self.__client_data[key][2].size() - ctypes.sizeof(
                            ctypes.c_long) == self.__client_data[key][1]:
                        self.__client_data[key][3].device().seek(0)
                        size = self.__client_data[key][3].readUInt64()
                        message = QtCore.QByteArray()
                        self.__client_data[key][3] >> message

                        self.__client_data[key][2] = None
                        self.__client_data[key][3] = None
                        self.__client_data[key][1] = 0

                        # system = 0
                        if message[:7] == "system:":
                            # system = 1

                            if message[:11] == "system:key:" and message.size(
                            ) == 47:
                                try:
                                    replace_key = uuid.UUID(str(message[11:]))

                                except:
                                    replace_key = key

                                if key != replace_key:
                                    # self.__logger.info("update client key from " + repr(key) + " to " + repr(replace_key))
                                    self.__client_data[
                                        replace_key] = self.__client_data[key]
                                    del self.__client_data[key]
                                    key = replace_key

                            elif message == "system:stop":
                                self.stop()

                        # if system:
                        #     self.__logger.info("received system message from client with size " + repr(size) + " [{0}]".format(key))

                        else:
                            # self.__logger.info("received message from client with size " + repr(size) + " [{0}]".format(key))
                            self.received.emit(m_client, message)

    def send(self, m_client, data):

        key = m_client.property("key")

        # self.__logger.info("send message to client [{0}]".format(key))
        block = QtCore.QByteArray()
        stream = QtCore.QDataStream(block, QtCore.QIODevice.WriteOnly)
        stream.setVersion(QtCore.QDataStream.Qt_4_7)
        stream.writeUInt64(0)
        stream << QtCore.QByteArray(data)
        stream.device().seek(0)
        stream.writeUInt64(block.size() - ctypes.sizeof(ctypes.c_long))
        stream.device().seek(block.size())
        stream.writeUInt64(0)

        s = 0
        while s < block.size():
            if m_client.state() != QtNetwork.QAbstractSocket.ConnectedState:
                m_client.warning(
                    "is not connected to server [{0}]".format(key))
                break

            w = m_client.write(block)
            s += w