예제 #1
0
class _MainContainer(QWidget):

###############################################################################
# MainContainer SIGNALS
###############################################################################
    """
    newFileOpened(QString)
    allTabClosed()
    runFile(QString)
    addToProject(QString)
    showFileInExplorer(QString)
    recentTabsModified()
    currentEditorChanged(QString)
    fileOpened(QString)
    ---------migrationAnalyzed()
    findOcurrences(QString)
    ---------updateFileMetadata()
    editorKeyPressEvent(QEvent)
    locateFunction(QString, QString, bool) [functionName, filePath, isVariable]
    updateLocator(QString)
    beforeFileSaved(QString)
    fileSaved(QString)
    openPreferences()
    --------openProject(QString)
    ---------dontOpenStartPage()
    """
    newFileOpened = pyqtSignal(str)
    allTabClosed = pyqtSignal()
    runFile = pyqtSignal(str)
    addToProject = pyqtSignal(str)
    showFileInExplorer = pyqtSignal(str)
    recentTabsModified = pyqtSignal()
    currentEditorChanged = pyqtSignal(str)
    fileOpened = pyqtSignal(str)
    migrationAnalyzed = pyqtSignal()#-----------
    findOcurrences = pyqtSignal(str)
    updateFileMetadata = pyqtSignal()#-----------
    editorKeyPressEvent = pyqtSignal('QEvent*')
    locateFunction = pyqtSignal(str, str, bool)
    updateLocator = pyqtSignal(str)
    beforeFileSaved = pyqtSignal(str)
    fileSaved = pyqtSignal(str)
    openPreferences = pyqtSignal()
    openProject = pyqtSignal(str)#-----------
    dontOpenStartPage = pyqtSignal()#-----------
    closeDialog = pyqtSignal('QObject*')
    allTabsClosed = pyqtSignal()
    splitEditor = pyqtSignal('QWidget*', 'QWidget*', bool)
    closeSplit = pyqtSignal(QWidget)
    toRemovePreview = pyqtSignal()

###############################################################################

    def __init__(self, parent=None):
        super(_MainContainer, self).__init__(parent)
        self._parent = parent
        self._vbox = QVBoxLayout(self)
        self._vbox.setContentsMargins(0, 0, 0, 0)
        self._vbox.setSpacing(0)
        self.stack = QStackedLayout()
        self.stack.setStackingMode(QStackedLayout.StackAll)
        self._vbox.addLayout(self.stack)

        self.splitter = dynamic_splitter.DynamicSplitter()
        self.setAcceptDrops(True)
        # self._files_handler = files_handler.FilesHandler(self)
        self._add_file_folder = add_file_folder.AddFileFolderWidget(self)

        self.tdir = None

        #documentation browser
        self.docPage = None
        #Code Navigation
        self._locator = locator.GoToDefinition()
        self.__codeBack = []
        self.__codeForward = []
        self.__bookmarksFile = ''
        self.__bookmarksPos = -1
        self.__breakpointsFile = ''
        self.__breakpointsPos = -1
        self.__operations = {
            0: self._navigate_code_jumps,
            1: self._navigate_bookmarks,
            2: self._navigate_breakpoints}

        self.locateFunction.connect(self.locate_function)

        IDE.register_service('main_container', self)

        #Register signals connections
        connections = (
            {'target': 'menu_file',
             'signal_name': 'openFile',#(QString)
             'slot': self.open_file},
            {'target': 'explorer_container',
             'signal_name': 'goToDefinition',#(int)
             'slot': self.editor_go_to_line},
            {'target': 'explorer_container',
             'signal_name': 'pep8Activated',#(bool)
             'slot': self.reset_pep8_warnings},
            {'target': 'explorer_container',
             'signal_name': 'lintActivated',#(bool)
             'slot': self.reset_lint_warnings},
            )

        IDE.register_signals('main_container', connections)

        self.selector = main_selector.MainSelector(self)
        self._opening_dialog = False
        self.add_widget(self.selector)

        if settings.SHOW_START_PAGE:
            self.show_start_page()

        self.selector.changeCurrent[int].connect(self._change_current_stack)
        self.selector.removeWidget[int].connect(self._remove_item_from_stack)
        self.selector.ready.connect(self._selector_ready)
        self.selector.closePreviewer.connect(self._selector_Close)
        self.selector.animationCompleted.connect(self._selector_animation_completed)

        self.closeDialog.connect(self.remove_widget)
        self.stack.widgetRemoved[int].connect(lambda i:print("widgetRemoved._-", i))

    def install(self):
        ide = IDE.getInstance()
        ide.place_me_on("main_container", self, "central", top=True)

        self.combo_area = combo_editor.ComboEditor(original=True)
        self.combo_area.allFilesClosed.connect(self._files_closed)
        self.splitter.add_widget(self.combo_area)
        self.add_widget(self.splitter)

        self.current_widget = self.combo_area

        ui_tools.install_shortcuts(self, actions.ACTIONS, ide)

    def add_status_bar(self, status):
        self._vbox.addWidget(status)

    @property
    def combo_header_size(self):
        return self.combo_area.bar.height()

    def add_widget(self, widget):
        i = self.stack.addWidget(widget)
        #if not isinstance(widget, start_page.StartPage):
        self.tryMakeImagePreview(i)

    def remove_widget(self, widget):
        #self.toRemovePreview.emit(self.stack.widget(widget))
        self.stack.removeWidget(widget)

    def _close_dialog(self, widget):
        self.closeDialog.emit(widget)
        widget.finished[int].disconnect()#lambda i: self._close_dialog(widget))

    def show_dialog(self, widget):
        print("\n\nshow_dialog", self.isVisible())
        self._opening_dialog = True
        widget.finished[int].connect(lambda i: self._close_dialog(widget))
        widget.setVisible(True)
        self.show_selector()

    def show_selector(self):
        print("\n\nshow_selector::", self.selector, self.stack.currentWidget())
        if self.selector != self.stack.currentWidget():
            _dir = self.Successful_Tmp()
            if not _dir:
                print("failed!")
                return

            # temp_dir = os.path.join(QDir.tempPath(), "ninja-ide")
            # if not os.path.exists(temp_dir):
            #     os.mkdir(temp_dir)
            collected_data = []
            current = self.stack.currentIndex()
            for index in range(self.stack.count()):
                widget = self.stack.widget(index)
                if widget == self.selector:
                    continue
                closable = True
                if widget == self.splitter:
                    closable = False
                # path = os.path.join(temp_dir, "screen%s.png" % index)
                #ff = QFile(_dir, "screen%s.png" % index)
                path = _dir.absolutePath()+"/screen%s.png" % index
                pixmap = widget.grab()#widget.rect())
                pixmap.save(path)
                #path = path.replace("\\", '/')
                #print("path::", path, QFileInfo(path).exists())
                path = "file:///"+path
                if index == current:
                    self.selector.set_preview(index, path)#QUrl(path)
                    collected_data.insert(0, (index, path, closable))
                else:
                    collected_data.append((index, path, closable))
            self.selector.set_model(collected_data)
            print("self.selector.set_model()", collected_data)
            self.stack.setCurrentWidget(self.selector)
        else:
            print("\n\n_selector_Close()")
            self._selector_Close()

    def Successful_Tmp(self):# CheckTmpDir, StateTmpDir
        failed = lambda: not self.tdir or not self.tdir.isValid()
        if failed():# not successfully
            self.tdir = QTemporaryDir()
            if failed():
                QMessageBox.critical(self, "Unexpected Failurer", "The application has detected a problem trying to\nCreate or Access a Temporary File!.")
                return None
            else:
                self.tdir.setAutoRemove(True)

        d = QDir(self.tdir.path())
        if not d.exists("ninja-ide"):
            if not d.mkdir("ninja-ide"):
                self.tdir = None
        d.cd("ninja-ide")
        return d

    def tryMakeImagePreview(self, index):
        return
        d = self.Successful_Tmp()
        if d:
            self.makeImagePreview(d, index)

    def makeImagePreview(self, _dir, index):
        return
        path = _dir.absolutePath()+"/screen%s.png" % index
        widget = self.stack.widget(index)
        pixmap = widget.grab()#widget.rect()
        pixmap.save(path)

    def _selector_ready(self):
        self.stack.setCurrentWidget(self.selector)
        self.selector.GoTo_GridPreviews()

    def _selector_Close(self):
        self.stack.setCurrentWidget(self.splitter)

    def _selector_animation_completed(self):
        if self._opening_dialog:
            # We choose the last one with -2, -1 (for last one) +
            # -1 for the hidden selector widget which is in the stacked too.
            self.selector.open_item(self.stack.count() - 2)
        self._opening_dialog = False

    def _change_current_stack(self, index):
        self.stack.setCurrentIndex(index)

    def _remove_item_from_stack(self, index):
        #self.toRemovePreview.emit(index)
        widget = self.stack.takeAt(index)
        del widget

    def show_editor_area(self):
        self.stack.setCurrentWidget(self.splitter)

    def _files_closed(self):
        if settings.SHOW_START_PAGE:
            self.show_start_page()

    def change_visibility(self):
        """Show/Hide the Main Container area."""
        print("change_visibility11")
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def expand_symbol_combo(self):
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_symbol()

    def expand_file_combo(self):
        print("expand_file_combo")
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_file()

    def locate_function(self, function, filePath, isVariable):
        """Move the cursor to the proper position in the navigate stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append((editorWidget.file_path,
                                   editorWidget.getCursorPosition()))
            self.__codeForward = []
        self._locator.navigate_to(function, filePath, isVariable)

    def run_file(self, path):
        self.runFile.emit(path)

    def _add_to_project(self, path):
        self.addToProject.emit(path)

    def _show_file_in_explorer(self, path):
        self.showFileInExplorer.emit(path)

    def paste_history(self):
        """Paste the text from the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            line, index = editorWidget.getCursorPosition()
            central = IDE.get_service('central_container')
            if central:
                editorWidget.insertAt(central.get_paste(), line, index)

    def copy_history(self):
        """Copy the selected text into the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            copy = editorWidget.selectedText()
            central = IDE.get_service('central_container')
            if central:
                central.add_copy(copy)

    def import_from_everywhere(self):
        """Insert an import line from any place in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            dialog = from_import_dialog.FromImportDialog(editorWidget, self)
            dialog.show()

    def add_back_item_navigation(self):
        """Add an item to the back stack and reset the forward stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append((editorWidget.file_path,
                                   editorWidget.getCursorPosition()))
            self.__codeForward = []

    def preview_in_browser(self):
        """Load the current html file in the default browser."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            if not editorWidget.file_path:
                self.save_file()
            ext = file_manager.get_file_extension(editorWidget.file_path)
            if ext in ('html', 'shpaml', 'handlebars', 'tpl'):
                webbrowser.open_new_tab(editorWidget.file_path)

    def add_bookmark_breakpoint(self):
        """Add a bookmark or breakpoint to the current file in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            if self.current_widget.bar.code_navigator.operation == 1:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.ControlModifier)
            elif self.current_widget.bar.code_navigator.operation == 2:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.NoModifier)

    def __navigate_with_keyboard(self, val):
        """Navigate between the positions in the jump history stack."""
        op = self.current_widget.bar.code_navigator.operation
        self.navigate_code_history(val, op)

    def navigate_code_history(self, val, op):
        """Navigate the code history."""
        self.__operations[op](val)

    def _navigate_code_jumps(self, val):
        """Navigate between the jump points."""
        node = None
        if not val and self.__codeBack:
            node = self.__codeBack.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeForward.append((editorWidget.file_path,
                                          editorWidget.getCursorPosition()))
        elif val and self.__codeForward:
            node = self.__codeForward.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeBack.append((editorWidget.file_path,
                                       editorWidget.getCursorPosition()))
        if node:
            filename = node[0]
            line, col = node[1]
            self.open_file(filename, line, col)

    def _navigate_breakpoints(self, val):
        """Navigate between the breakpoints."""
        #FIXME: put navigate breakpoints and bookmarks as one method.
        breakList = list(settings.BREAKPOINTS.keys())
        breakList.sort()
        if not breakList:
            return
        if self.__breakpointsFile not in breakList:
            self.__breakpointsFile = breakList[0]
        index = breakList.index(self.__breakpointsFile)
        breaks = settings.BREAKPOINTS.get(self.__breakpointsFile, [])
        lineNumber = 0
        #val == True: forward
        if val:
            if (len(breaks) - 1) > self.__breakpointsPos:
                self.__breakpointsPos += 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                if index < (len(breakList) - 1):
                    self.__breakpointsFile = breakList[index + 1]
                else:
                    self.__breakpointsFile = breakList[0]
                self.__breakpointsPos = 0
                lineNumber = settings.BREAKPOINTS[self.__breakpointsFile][0]
        else:
            if self.__breakpointsPos > 0:
                self.__breakpointsPos -= 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                self.__breakpointsFile = breakList[index - 1]
                breaks = settings.BREAKPOINTS[self.__breakpointsFile]
                self.__breakpointsPos = len(breaks) - 1
                lineNumber = breaks[self.__breakpointsPos]
        if file_manager.file_exists(self.__breakpointsFile):
            self.open_file(self.__breakpointsFile, lineNumber, None, True)
        else:
            settings.BREAKPOINTS.pop(self.__breakpointsFile)
            if settings.BREAKPOINTS:
                self._navigate_breakpoints(val)

    def _navigate_bookmarks(self, val):
        """Navigate between the bookmarks."""
        bookList = list(settings.BOOKMARKS.keys())
        bookList.sort()
        if not bookList:
            return
        if self.__bookmarksFile not in bookList:
            self.__bookmarksFile = bookList[0]
        index = bookList.index(self.__bookmarksFile)
        bookms = settings.BOOKMARKS.get(self.__bookmarksFile, [])
        lineNumber = 0
        #val == True: forward
        if val:
            if (len(bookms) - 1) > self.__bookmarksPos:
                self.__bookmarksPos += 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                if index < (len(bookList) - 1):
                    self.__bookmarksFile = bookList[index + 1]
                else:
                    self.__bookmarksFile = bookList[0]
                self.__bookmarksPos = 0
                lineNumber = settings.BOOKMARKS[self.__bookmarksFile][0]
        else:
            if self.__bookmarksPos > 0:
                self.__bookmarksPos -= 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                self.__bookmarksFile = bookList[index - 1]
                bookms = settings.BOOKMARKS[self.__bookmarksFile]
                self.__bookmarksPos = len(bookms) - 1
                lineNumber = bookms[self.__bookmarksPos]
        if file_manager.file_exists(self.__bookmarksFile):
            self.open_file(self.__bookmarksFile,
                           lineNumber, None, True)
        else:
            settings.BOOKMARKS.pop(self.__bookmarksFile)
            if settings.BOOKMARKS:
                self._navigate_bookmarks(val)

    def count_file_code_lines(self):
        """Count the lines of code in the current file."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            block_count = editorWidget.lines()
            blanks = re.findall('(^\n)|(^(\s+)?#)|(^( +)?($|\n))',
                                editorWidget.text(), re.M)
            blanks_count = len(blanks)
            resume = self.tr("Lines code: %s\n") % (block_count - blanks_count)
            resume += (self.tr("Blanks and commented lines: %s\n\n") %
                       blanks_count)
            resume += self.tr("Total lines: %s") % block_count
            msgBox = QMessageBox(QMessageBox.Information,
                                 self.tr("Summary of lines"), resume,
                                 QMessageBox.Ok, editorWidget)
            msgBox.exec_()

    def editor_cut(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.cut()

    def editor_copy(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.copy()

    def editor_paste(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.paste()

    def editor_upper(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_upper()

    def editor_lower(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_lower()

    def editor_title(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_title()

    def editor_go_to_definition(self):
        """Search the definition of the method or variable under the cursor.

        If more than one method or variable is found with the same name,
        shows a table with the results and let the user decide where to go."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.go_to_definition()

    def editor_redo(self):
        """Execute the redo action in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.redo()

    def editor_undo(self):
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.undo()

    def editor_indent_less(self):
        """Indent 1 position to the left for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_less()

    def editor_indent_more(self):
        """Indent 1 position to the right for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_more()

    def editor_insert_debugging_prints(self):
        """Insert a print statement in each selected line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_debugging_prints(editorWidget)

    def editor_insert_pdb(self):
        """Insert a pdb.set_trace() statement in tjhe current line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_pdb(editorWidget)

    def editor_comment(self):
        """Mark the current line or selection as a comment."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.comment(editorWidget)

    def editor_uncomment(self):
        """Uncomment the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.uncomment(editorWidget)

    def editor_insert_horizontal_line(self):
        """Insert an horizontal lines of comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_horizontal_line(editorWidget)

    def editor_insert_title_comment(self):
        """Insert a Title surrounded by comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_title_comment(editorWidget)

    def editor_remove_trailing_spaces(self):
        """Remove the trailing spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.remove_trailing_spaces(editorWidget)

    def editor_replace_tabs_with_spaces(self):
        """Replace the Tabs with Spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.replace_tabs_with_spaces(editorWidget)

    def editor_move_up(self):
        """Move the current line or selection one position up."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_up(editorWidget)

    def editor_move_down(self):
        """Move the current line or selection one position down."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_down(editorWidget)

    def editor_remove_line(self):
        """Remove the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.remove_line(editorWidget)

    def editor_duplicate(self):
        """Duplicate the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.duplicate(editorWidget)

    def editor_highlight_word(self):
        """Highlight the occurrences of the current word in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.highlight_selected_word()

    def editor_complete_declaration(self):
        """Do the opposite action that Complete Declaration expect."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.complete_declaration()

    def editor_go_to_line(self, line, select=False):#def editor_go_to_line(self, line):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        print("\nluego en segundo lugar por aca")
        if editorWidget:
            editorWidget.jump_to_line(line)#select

    def editor_go_to_symbol_line(self, line, sym= "", select=False):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        print("\nluego en segundo lugar por aca")
        if editorWidget:
            editorWidget.go_to_symbol(line, sym, select)#select

    def zoom_in_editor(self):
        """Increase the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom_in()

    def zoom_out_editor(self):
        """Decrease the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom_out()

    def recent_files_changed(self):
        self.recentTabsModified.emit()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        # file_path = event.mimeData().urls()[0].toLocalFile()
        # paths = [item.toLocalFile() for item in event.mimeData().urls()]
        self.open_files_fromUrlList(event.mimeData().urls())
        # print("\n\n dropEvent", paths)
        # self.open_file(file_path)

    def setFocus(self):
        widget = self.get_current_widget()
        if widget:
            widget.setFocus()

    def current_editor_changed(self, filename):
        """Notify the new filename of the current editor."""
        if filename is None:
            filename = translations.TR_NEW_DOCUMENT
        self.currentEditorChanged.emit(filename)

    def show_split(self, orientation_vertical=False):
        #IDE.select_current(self.current_widget.currentWidget())
        self.current_widget.split_editor(orientation_vertical)

    def add_editor(self, fileName=None, ignore_checkers=False):
        print("filename::", fileName)
        ninjaide = IDE.getInstance()
        editable = ninjaide.get_or_create_editable(fileName)
        if editable.editor:
            self.current_widget.set_current(editable)
            print("\n\nreturn")
            return self.current_widget.currentWidget()
        else:
            editable.ignore_checkers = ignore_checkers

        editorWidget = self.create_editor_from_editable(editable)

        #add the tab
        keep_index = (self.splitter.count() > 1 and
                      self.combo_area.stacked.count() > 0)
        self.combo_area.add_editor(editable, keep_index)

        #emit a signal about the file open
        self.fileOpened.emit(fileName)
        if keep_index:
            self.current_widget.set_current(editable)

        self.stack.setCurrentWidget(self.splitter)
        return editorWidget

    def create_editor_from_editable(self, editable):
        editorWidget = editor.create_editor(editable)

        #Connect signals
        editable.fileSaved.connect(self._editor_tab_was_saved)
        editorWidget.openDropFile.connect(self.open_file)
        editorWidget.addBackItemNavigation.connect(self.add_back_item_navigation)
        editorWidget.locateFunction.connect(self._editor_locate_function)
        editorWidget.findOcurrences.connect(self._find_occurrences)
        #keyPressEventSignal for plugins
        editorWidget.keyPressSignal.connect(self._editor_keyPressEvent)

        return editorWidget

    def reset_pep8_warnings(self, value):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #widget = self._tabMain.widget(i)
            #if type(widget) is editor.Editor:
                #if value:
                    #widget.syncDocErrorsSignal = True
                    #widget.pep8.check_style()
                #else:
                    #widget.hide_pep8_errors()

    def reset_lint_warnings(self, value):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #widget = self._tabMain.widget(i)
            #if type(widget) is editor.Editor:
                #if value:
                    #widget.syncDocErrorsSignal = True
                    #widget.errors.check_errors()
                #else:
                    #widget.hide_lint_errors()

    def _find_occurrences(self, word):
        self.findOcurrences.emit(word)

    def _editor_keyPressEvent(self, event):
        self.editorKeyPressEvent.emit(event)

    def _editor_locate_function(self, function, filePath, isVariable):
        self.locateFunction.emit(function, filePath, isVariable)

    def _editor_tab_was_saved(self, editable=None):
        self.updateLocator.emit(editable.file_path)

    def get_current_widget(self):
        return self.current_widget.currentWidget()

    def get_current_editor(self):
        """Return the Actual Editor or None

        Return an instance of Editor if the Current Tab contains
        an Editor or None if it is not an instance of Editor"""
        widget = self.current_widget.currentWidget()
        if isinstance(widget, editor.Editor):
            return widget
        return None

    def reload_file(self, editorWidget=None):
        if editorWidget is None:
            editorWidget = self.get_current_editor()
            if editorWidget is not None:
                editorWidget.neditable.reload_file()

    def add_tab(self, widget, tabName, tabIndex=None):
        pass
        #return self.tabs.add_tab(widget, tabName, index=tabIndex)

    def open_image(self, fileName):
        try:
            if not self.is_open(fileName):
                viewer = image_viewer.ImageViewer(fileName)
                self.add_tab(viewer, file_manager.get_basename(fileName))
                viewer.ID = fileName
            else:
                self.move_to_open(fileName)
        except Exception as reason:
            logger.error('open_image: %s', reason)
            QMessageBox.information(self, self.tr("Incorrect File"),
                                    self.tr("The image couldn\'t be open"))

    def open_files_fromList(self, lst):
        for f in lst:
            self.open_file(f)

    def open_files_fromUrlList(self, lst):
        for f in lst:
            self.open_file(f.toLocalFile())

    def open_file(self, filename='', line=-1, col=0, ignore_checkers=False):
        logger.debug("will try to open %s" % filename)
        if not filename:
            logger.debug("has nofilename")
            if settings.WORKSPACE:
                directory = settings.WORKSPACE
            else:
                directory = os.path.expanduser("~")
                editorWidget = self.get_current_editor()
                ninjaide = IDE.getInstance()
                if ninjaide:
                    current_project = ninjaide.get_current_project()
                    if current_project is not None:
                        directory = current_project
                    elif editorWidget is not None and editorWidget.file_path:
                        directory = file_manager.get_folder(
                            editorWidget.file_path)
            extensions = ';;'.join(
                ['{}(*{})'.format(e.upper()[1:], e)
                 for e in settings.SUPPORTED_EXTENSIONS + ['.*', '']])
            fileNames = QFileDialog.getOpenFileNames(self,
                             self.tr("Open File"), directory, extensions)[0]#list()
        else:
            logger.debug("has filename")
            fileNames = [filename]
        if not fileNames:
            return

        print("\n\nopen_file")
        othersFileNames = []
        image_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png')
        for filename in fileNames:
            print("nombre", filename)
            if QFileInfo(filename).isDir():
                othersFileNames.extend( QFileDialog.getOpenFileNames(None,
                    "Select files", filename, "Files (*.*)")[0] )
            elif file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col,
                                 ignore_checkers)

        for filename in othersFileNames:
            print("nombre", filename)
            if QFileInfo(filename).isDir():
                continue
            elif file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col,
                                 ignore_checkers)



    def __open_file(self, fileName='', line=-1, col=0, ignore_checkers=False):
        print("unio", fileName)
        try:
            editorWidget = self.add_editor(fileName,
                                           ignore_checkers=ignore_checkers)
            if line != -1:
                editorWidget.set_cursor_position(line, col)
            self.currentEditorChanged.emit(fileName)
        except file_manager.NinjaIOException as reason:
            QMessageBox.information(self,
                                    self.tr("The file couldn't be open"),
                                    str(reason))

    def is_open(self, filename):
        pass
        #return self.tabs.is_open(filename) != -1

    def move_to_open(self, filename):
        pass
        #FIXME: add in the current split?
        #if self.tabs.is_open(filename) != -1:
            #self.tabs.move_to_open(filename)
        #self.tabs.currentWidget().setFocus()
        #self.emit(SIGNAL("currentEditorChanged(QString)"), filename)

    def get_widget_for_id(self, filename):
        pass
        #widget = None
        #index = self.tabs.is_open(filename)
        #if index != -1:
            #widget = self.tabs.widget(index)
        #return widget

    def change_open_tab_id(self, idname, newId):
        """Search for the Tab with idname, and set the newId to that Tab."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
            #widget = self.tabs.widget(index)
            #tabName = file_manager.get_basename(newId)
            #self.tabs.change_open_tab_name(index, tabName)
            #widget.ID = newId

    def close_deleted_file(self, idname):
        """Search for the Tab with id, and ask the user if should be closed."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
            #result = QMessageBox.question(self, self.tr("Close Deleted File"),
                #self.tr("Are you sure you want to close the deleted file?\n"
                        #"The content will be completely deleted."),
                #buttons=QMessageBox.Yes | QMessageBox.No)
            #if result == QMessageBox.Yes:
                #self.tabs.removeTab(index)

    def save_file(self, editorWidget=None):
        #FIXME: check how we handle this
        if not editorWidget:
            editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            #editorWidget.just_saved = True
            if (editorWidget.nfile.is_new_file or
                    not editorWidget.nfile.has_write_permission()):
                return self.save_file_as()

            self.beforeFileSaved.emit(editorWidget.file_path)
            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)
            editorWidget.neditable.save_content()
            #file_manager.store_file_content(
                #fileName, content, addExtension=False)
            encoding = file_manager.get_file_encoding(editorWidget.text())
            editorWidget.encoding = encoding
            self.fileSaved.emit((self.tr("File Saved: %s") % editorWidget.file_path))
            return True
        except Exception as reason:
            logger.error('save_file: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def save_file_as(self):
        editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            filters = '(*.py);;(*.*)'
            if editorWidget.file_path:
                ext = file_manager.get_file_extension(editorWidget.file_path)
                if ext != 'py':
                    filters = '(*.%s);;(*.py);;(*.*)' % ext
            save_folder = self._get_save_folder(editorWidget.file_path)
            fileName = QFileDialog.getSaveFileName(
                self._parent, self.tr("Save File"), save_folder, filters)
            if not fileName:
                return False

            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)

            editorWidget.neditable.save_content(path=fileName)
            editorWidget.register_syntax(
                file_manager.get_file_extension(fileName))

            self.fileSaved.emit((self.tr("File Saved: %s") % fileName))
            self.currentEditorChanged.emit(fileName)
            return True
        except file_manager.NinjaFileExistsException as ex:
            QMessageBox.information(self, self.tr("File Already Exists"),
                                    (self.tr("Invalid Path: the file '%s' "
                                             " already exists.") %
                                    ex.filename))
        except Exception as reason:
            logger.error('save_file_as: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def _get_save_folder(self, fileName):
        """
        Returns the root directory of the 'Main Project' or the home folder
        """
        ninjaide = IDE.getInstance()
        current_project = ninjaide.get_current_project()
        if current_project:
            return current_project.path
        return os.path.expanduser("~")

    def save_project(self, projectFolder):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #editorWidget = self._tabMain.widget(i)
            #if type(editorWidget) is editor.Editor and \
            #file_manager.belongs_to_folder(projectFolder,
                    #editorWidget.file_path):
                #reloaded = self._tabMain.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
            #editorWidget = self.tabsecondary.widget(i)
            #if type(editorWidget) is editor.Editor and \
            #file_manager.belongs_to_folder(projectFolder,
                    #editorWidget.file_path):
                #reloaded = self.tabsecondary.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)

    def save_all(self):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #editorWidget = self._tabMain.widget(i)
            #if type(editorWidget) is editor.Editor:
                #reloaded = self._tabMain.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
            #editorWidget = self.tabsecondary.widget(i)
            #self.tabsecondary.check_for_external_modifications(editorWidget)
            #if type(editorWidget) is editor.Editor:
                #reloaded = self.tabsecondary.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)

    def call_editors_function(self, call_function, *arguments):
        pass
        #args = arguments[0]
        #kwargs = arguments[1]
        #for i in range(self.tabs.count()):
            #editorWidget = self.tabs.widget(i)
            #if isinstance(editorWidget, editor.Editor):
                #function = getattr(editorWidget, call_function)
                #function(*args, **kwargs)
        #TODO: add other splits

    def show_start_page(self):
        start = self.stack.widget(0)
        if isinstance(start, start_page.StartPage):
            self.stack.setCurrentIndex(0)
        else:
            startPage = start_page.StartPage(parent=self)
            startPage.openProject.connect(self.open_project)
            startPage.openPreferences.connect(self.openPreferences.emit)
            startPage.newFile.connect(self.add_editor)
            startPage.openFiles.connect(self.open_files_fromList)
            self.stack.insertWidget(0, startPage)
            self.stack.setCurrentIndex(0)

            self.tryMakeImagePreview(0)
            #"screen0.png"

    def show_python_doc(self):
        if sys.platform == 'win32':
            self.docPage = browser_widget.BrowserWidget(
                'http://docs.python.org/')
        else:
            process = runner.start_pydoc()
            self.docPage = browser_widget.BrowserWidget(process[1], process[0])
        self.add_tab(self.docPage, translations.TR_PYTHON_DOC)

    def show_report_bugs(self):
        webbrowser.open(resources.BUGS_PAGE)

    def show_plugins_doc(self):
        bugsPage = browser_widget.BrowserWidget(resources.PLUGINS_DOC, self)
        self.add_tab(bugsPage, translations.TR_HOW_TO_WRITE_PLUGINS)

    def editor_jump_to_line(self, lineno=None):
        """Jump to line *lineno* if it is not None
        otherwise ask to the user the line number to jump
        """
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.jump_to_line(lineno=lineno)

    def get_opened_documents(self):
        #return self.tabs.get_documents_data()
        return []

    def check_for_unsaved_files(self):
        pass
        #return self.tabs._check_unsaved_tabs()

    def get_unsaved_files(self):
        pass
        #return self.tabs.get_unsaved_files()

    def reset_editor_flags(self):
        pass
        #for i in range(self.tabs.count()):
            #widget = self.tabs.widget(i)
            #if isinstance(widget, editor.Editor):
                #widget.set_flags()

    def _specify_syntax(self, widget, syntaxLang):
        if isinstance(widget, editor.Editor):
            widget.restyle(syntaxLang)

    def apply_editor_theme(self, family, size):
        pass
        #for i in range(self.tabs.count()):
            #widget = self.tabs.widget(i)
            #if isinstance(widget, editor.Editor):
                #widget.restyle()
                #widget.set_font(family, size)

    def update_editor_margin_line(self):
        pass
        #for i in range(self.tabs.count()):
            #widget = self.tabs.widget(i)
            #if isinstance(widget, editor.Editor):
                #widget._update_margin_line()

    def open_project(self, path):
        print("open_project")
        self.openProject.emit(path)

    def close_python_doc(self):
        pass
        #close the python document server (if running)
        #if self.docPage:
            #index = self.tabs.indexOf(self.docPage)
            #self.tabs.removeTab(index)
            ##assign None to the browser
            #self.docPage = None

    def close_file(self):
        """Close the current tab in the current TabWidget."""
        self.current_widget.close_current_file()

    def create_file(self, base_path, project_path):
        self._add_file_folder.create_file(base_path, project_path)

    def create_folder(self, base_path, project_path):
        self._add_file_folder.create_folder(base_path, project_path)

    def change_tab(self):
        """Change the tab in the current TabWidget."""
        print("\nchange_tab")
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.next_item()
        pass

    def change_tab_reverse(self):
        """Change the tab in the current TabWidget backwards."""
        print("\nchange_tab_reverse")
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.previous_item()

    def toggle_tabs_and_spaces(self):
        """ Toggle Show/Hide Tabs and Spaces """

        settings.SHOW_TABS_AND_SPACES = not settings.SHOW_TABS_AND_SPACES
        qsettings = IDE.ninja_settings()
        qsettings.setValue('preferences/editor/showTabsAndSpaces',
                           settings.SHOW_TABS_AND_SPACES)

    def show_navigation_buttons(self):
        """Show Navigation menu."""
        self.stack.setCurrentWidget(self.splitter)
        self.combo_area.show_menu_navigation()

    def change_split_focus(self):
        pass
        #FIXME: check how we handle this
        #if self.actualTab == self._tabMain and self.tabsecondary.isVisible():
            #self.actualTab = self.tabsecondary
        #else:
            #self.actualTab = self._tabMain
        #widget = self.actualTab.currentWidget()
        #if widget is not None:
            #widget.setFocus()

    def shortcut_index(self, index):
        pass
        #self.tabs.setCurrentIndex(index)

    def print_file(self):
        """Call the print of ui_tool

        Call print of ui_tool depending on the focus of the application"""
        #TODO: Add funtionality for proyect tab and methods tab
        editorWidget = self.get_current_editor()
        if editorWidget is not None:
            fileName = "newDocument.pdf"
            if editorWidget.file_path:
                fileName = file_manager.get_basename(
                    editorWidget.file_path)
                fileName = fileName[:fileName.rfind('.')] + '.pdf'
            ui_tools.print_file(fileName, editorWidget.print_)

    def split_assistance(self):
        dialog = split_orientation.SplitOrientation(self)
        dialog.show()

    def close_split(self):
        if self.current_widget != self.combo_area:
            self.current_widget.bar.close_split()

    def split_vertically(self):
        self.show_split(False)

    def split_horizontally(self):
        self.show_split(True)

    def navigate_back(self):
        self.__navigate_with_keyboard(False)

    def navigate_forward(self):
        self.__navigate_with_keyboard(True)
예제 #2
0
class _MainContainer(QWidget):

    ###############################################################################
    # MainContainer SIGNALS
    ###############################################################################
    """
    newFileOpened(QString)
    allTabClosed()
    runFile(QString)
    addToProject(QString)
    showFileInExplorer(QString)
    recentTabsModified()
    currentEditorChanged(QString)
    fileOpened(QString)
    ---------migrationAnalyzed()
    findOcurrences(QString)
    ---------updateFileMetadata()
    editorKeyPressEvent(QEvent)
    locateFunction(QString, QString, bool) [functionName, filePath, isVariable]
    updateLocator(QString)
    beforeFileSaved(QString)
    fileSaved(QString)
    openPreferences()
    --------openProject(QString)
    ---------dontOpenStartPage()
    """

    ###############################################################################

    fileOpened = pyqtSignal('QString')
    updateLocator = pyqtSignal('QString')
    currentEditorChanged = pyqtSignal('QString')
    beforeFileSaved = pyqtSignal('QString')
    fileSaved = pyqtSignal('QString')

    def __init__(self, parent=None):
        super(_MainContainer, self).__init__(parent)
        self.setContentsMargins(0, 0, 0, 0)
        self._parent = parent
        self._vbox = QVBoxLayout(self)
        self._vbox.setContentsMargins(0, 0, 0, 0)
        self._vbox.setSpacing(0)
        self.stack = QStackedLayout()
        self.stack.setStackingMode(QStackedLayout.StackAll)
        self._vbox.addLayout(self.stack)
        self.splitter = dynamic_splitter.DynamicSplitter()
        self.setAcceptDrops(True)
        # self._files_handler = files_handler.FilesHandler(self)
        self._add_file_folder = add_file_folder.AddFileFolderWidget(self)

        # documentation browser
        self.docPage = None
        # Code Navigation
        # self._locator = locator.GoToDefinition()
        self.__codeBack = []
        self.__codeForward = []
        self.__bookmarksFile = ''
        self.__bookmarksPos = -1
        self.__breakpointsFile = ''
        self.__breakpointsPos = -1
        self.__operations = {
            0: self._navigate_code_jumps,
            1: self._navigate_bookmarks,
            2: self._navigate_breakpoints
        }

        # self.locateFunction['QString',
        #                    'QString',
        #                    bool].connect(self.locate_function)

        IDE.register_service('main_container', self)

        # Register signals connections
        connections = ({
            'target': 'main_container',
            'signal_name': 'updateLocator',
            'slot': self._explore_file_code
        }, {
            'target': 'filesystem',
            'signal_name': 'projectOpened',
            'slot': self._explore_code
        }, {
            'target': 'projects_explorer',
            'signal_name': 'updateLocator',
            'slot': self._explore_code
        })
        """
        {'target': 'menu_file',
            'signal_name': 'openFile(QString)',
            'slot': self.open_file},
        {'target': 'explorer_container',
            'signal_name': 'goToDefinition(int)',
            'slot': self.editor_go_to_line},
        {'target': 'explorer_container',
            'signal_name': 'pep8Activated(bool)',
            'slot': self.reset_pep8_warnings},
        {'target': 'explorer_container',
            'signal_name': 'lintActivated(bool)',
            'slot': self.reset_lint_warnings},
        {'target': 'filesystem',
            'signal_name': 'projectOpened',
            'slot': self._explore_code},
        {'target': 'main_container',
            'signal_name': 'updateLocator(QString)',
            'slot': self._explore_file_code},
        )
        """

        IDE.register_signals('main_container', connections)

        self.selector = main_selector.MainSelector(self)
        self._opening_dialog = False
        self.add_widget(self.selector)

        if settings.SHOW_START_PAGE:
            self.show_start_page()

        self.selector.changeCurrent[int].connect(self._change_current_stack)
        # self.selector.removeWidget[int].connect(self._remove_item_from_stack)
        # self.selector.ready.connect(self._selector_ready)
        self.selector.animationCompleted.connect(
            self._selector_animation_completed)
        # self.closeDialog['PyQt_PyObject'].connect(self.remove_widget)

    def install(self):
        ide = IDE.get_service('ide')
        ide.place_me_on("main_container", self, "central", top=True)

        self.combo_area = combo_editor.ComboEditor(original=True)
        self.combo_area.allFilesClosed.connect(self._files_closed)
        # self.combo_area.allFilesClosed.connect(self._files_closed)
        self.splitter.add_widget(self.combo_area)
        self.add_widget(self.splitter)

        self.current_widget = self.combo_area
        # Code Locator
        self._code_locator = locator_widget.LocatorWidget(ide)

        ui_tools.install_shortcuts(self, actions.ACTIONS, ide)

    def show_locator(self):
        """Show the locator widget"""

        if not self._code_locator.isVisible():
            self._code_locator.show()

    def _explore_code(self):
        """ Update locator metadata for the current projects """

        self._code_locator.explore_code()

    def _explore_file_code(self, path):
        """ Update locator metadata for the file in path """

        self._code_locator.explore_file_code(path)

    def add_status_bar(self, status):
        self._vbox.addWidget(status)

    @property
    def combo_header_size(self):
        return self.combo_area.bar.height()

    def add_widget(self, widget):
        self.stack.addWidget(widget)

    def remove_widget(self, widget):
        self.stack.removeWidget(widget)

    def _close_dialog(self, widget):
        self.emit(SIGNAL("closeDialog(PyQt_PyObject)"), widget)
        self.disconnect(widget, SIGNAL("finished(int)"),
                        lambda: self._close_dialog(widget))

    def show_dialog(self, widget):
        self._opening_dialog = True
        # self.connect(widget, SIGNAL("finished(int)"),
        #             lambda: self._close_dialog(widget))
        self.setVisible(True)
        self.stack.addWidget(widget)
        self.show_selector()

    def show_selector(self):
        if self.selector != self.stack.currentWidget():
            temp_dir = os.path.join(QDir.tempPath(), "ninja-ide")
            if not os.path.exists(temp_dir):
                os.mkdir(temp_dir)
            collected_data = []
            current = self.stack.currentIndex()
            for index in range(self.stack.count()):
                widget = self.stack.widget(index)
                if widget == self.selector:
                    continue
                pixmap = QWidget.grab(widget, widget.rect())
                path = os.path.join(temp_dir, "screen%s.png" % index)
                pixmap.save(path)
                collected_data.append((index, path))
            self.selector.set_model(collected_data)
            self._selector_ready()
        """
        if self.selector != self.stack.currentWidget():
            temp_dir = os.path.join(QDir.tempPath(), "ninja-ide")
            if not os.path.exists(temp_dir):
                os.mkdir(temp_dir)
            collected_data = []
            current = self.stack.currentIndex()
            for index in range(self.stack.count()):
                widget = self.stack.widget(index)
                if widget == self.selector:
                    continue
                closable = True
                if widget == self.splitter:
                    closable = False
                pixmap = QWidget.grab(widget, widget.rect())
                path = os.path.join(temp_dir, "screen%s.png" % index)
                pixmap.save(path)
                if index == current:
                    self.selector.set_preview(index, path)
                    collected_data.insert(0, (index, path, closable))
                else:
                    collected_data.append((index, path, closable))
            self.selector.set_model(collected_data)
        else:
            self.selector.close_selector()
        """

    def _selector_ready(self):
        print(self.stack.currentWidget())
        self.stack.setCurrentWidget(self.selector)
        print(self.stack.currentWidget())
        self.selector.start_animation()

    def _selector_animation_completed(self):
        if self._opening_dialog:
            # We choose the last one with -2, -1 (for last one) +
            # -1 for the hidden selector widget which is in the stacked too.
            self.selector.open_item(self.stack.count() - 2)
        self._opening_dialog = False

    def _change_current_stack(self, index):
        self.stack.setCurrentIndex(index)

    def _remove_item_from_stack(self, index):
        widget = self.stack.takeAt(index)
        del widget

    def show_editor_area(self):
        self.stack.setCurrentWidget(self.splitter)

    def _files_closed(self):
        if settings.SHOW_START_PAGE:
            self.show_start_page()

    def change_visibility(self):
        """Show/Hide the Main Container area."""
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def expand_symbol_combo(self):
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_symbol()

    def expand_file_combo(self):
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_file()

    def locate_function(self, function, filePath, isVariable):
        """Move the cursor to the proper position in the navigate stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append(
                (editorWidget.file_path, editorWidget.getCursorPosition()))
            self.__codeForward = []
        self._locator.navigate_to(function, filePath, isVariable)

    def run_file(self, path):
        self.emit(SIGNAL("runFile(QString)"), path)

    def _add_to_project(self, path):
        self.emit(SIGNAL("addToProject(QString)"), path)

    def _show_file_in_explorer(self, path):
        self.emit(SIGNAL("showFileInExplorer(QString)"), path)

    def paste_history(self):
        """Paste the text from the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            line, index = editorWidget.getCursorPosition()
            central = IDE.get_service('central_container')
            if central:
                editorWidget.insertAt(central.get_paste(), line, index)

    def copy_history(self):
        """Copy the selected text into the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            copy = editorWidget.selectedText()
            central = IDE.get_service('central_container')
            if central:
                central.add_copy(copy)

    def import_from_everywhere(self):
        """Insert an import line from any place in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            dialog = from_import_dialog.FromImportDialog(editorWidget, self)
            dialog.show()

    def add_back_item_navigation(self):
        """Add an item to the back stack and reset the forward stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append(
                (editorWidget.file_path, editorWidget.cursor_position))
            self.__codeForward = []

    def preview_in_browser(self):
        """Load the current html file in the default browser."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            if not editorWidget.file_path:
                self.save_file()
            ext = file_manager.get_file_extension(editorWidget.file_path)
            if ext in ('html', 'shpaml', 'handlebars', 'tpl'):
                webbrowser.open_new_tab(editorWidget.file_path)

    def add_bookmark_breakpoint(self):
        """Add a bookmark or breakpoint to the current file in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            if self.current_widget.bar.code_navigator.operation == 1:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.ControlModifier)
            elif self.current_widget.bar.code_navigator.operation == 2:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.NoModifier)

    def __navigate_with_keyboard(self, val):
        """Navigate between the positions in the jump history stack."""
        op = self.current_widget.bar.code_navigator.operation
        self.navigate_code_history(val, op)

    def navigate_code_history(self, val, op):
        """Navigate the code history."""
        self.__operations[op](val)

    def _navigate_code_jumps(self, val):
        """Navigate between the jump points."""
        node = None
        if not val and self.__codeBack:
            node = self.__codeBack.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeForward.append(
                    (editorWidget.file_path, editorWidget.getCursorPosition()))
        elif val and self.__codeForward:
            node = self.__codeForward.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeBack.append(
                    (editorWidget.file_path, editorWidget.getCursorPosition()))
        if node:
            filename = node[0]
            line, col = node[1]
            self.open_file(filename, line, col)

    def _navigate_breakpoints(self, val):
        """Navigate between the breakpoints."""
        # FIXME: put navigate breakpoints and bookmarks as one method.
        breakList = list(settings.BREAKPOINTS.keys())
        breakList.sort()
        if not breakList:
            return
        if self.__breakpointsFile not in breakList:
            self.__breakpointsFile = breakList[0]
        index = breakList.index(self.__breakpointsFile)
        breaks = settings.BREAKPOINTS.get(self.__breakpointsFile, [])
        lineNumber = 0
        # val == True: forward
        if val:
            if (len(breaks) - 1) > self.__breakpointsPos:
                self.__breakpointsPos += 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                if index < (len(breakList) - 1):
                    self.__breakpointsFile = breakList[index + 1]
                else:
                    self.__breakpointsFile = breakList[0]
                self.__breakpointsPos = 0
                lineNumber = settings.BREAKPOINTS[self.__breakpointsFile][0]
        else:
            if self.__breakpointsPos > 0:
                self.__breakpointsPos -= 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                self.__breakpointsFile = breakList[index - 1]
                breaks = settings.BREAKPOINTS[self.__breakpointsFile]
                self.__breakpointsPos = len(breaks) - 1
                lineNumber = breaks[self.__breakpointsPos]
        if file_manager.file_exists(self.__breakpointsFile):
            self.open_file(self.__breakpointsFile, lineNumber, None, True)
        else:
            settings.BREAKPOINTS.pop(self.__breakpointsFile)
            if settings.BREAKPOINTS:
                self._navigate_breakpoints(val)

    def _navigate_bookmarks(self, val):
        """Navigate between the bookmarks."""
        bookList = list(settings.BOOKMARKS.keys())
        bookList.sort()
        if not bookList:
            return
        if self.__bookmarksFile not in bookList:
            self.__bookmarksFile = bookList[0]
        index = bookList.index(self.__bookmarksFile)
        bookms = settings.BOOKMARKS.get(self.__bookmarksFile, [])
        lineNumber = 0
        # val == True: forward
        if val:
            if (len(bookms) - 1) > self.__bookmarksPos:
                self.__bookmarksPos += 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                if index < (len(bookList) - 1):
                    self.__bookmarksFile = bookList[index + 1]
                else:
                    self.__bookmarksFile = bookList[0]
                self.__bookmarksPos = 0
                lineNumber = settings.BOOKMARKS[self.__bookmarksFile][0]
        else:
            if self.__bookmarksPos > 0:
                self.__bookmarksPos -= 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                self.__bookmarksFile = bookList[index - 1]
                bookms = settings.BOOKMARKS[self.__bookmarksFile]
                self.__bookmarksPos = len(bookms) - 1
                lineNumber = bookms[self.__bookmarksPos]
        if file_manager.file_exists(self.__bookmarksFile):
            self.open_file(self.__bookmarksFile, lineNumber, None, True)
        else:
            # settings.BOOKMARKS.pop(self.__bookmarksFile)
            if settings.BOOKMARKS:
                self._navigate_bookmarks(val)

    def count_file_code_lines(self):
        """Count the lines of code in the current file."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            block_count = editorWidget.lines()
            blanks = re.findall('(^\n)|(^(\s+)?#)|(^( +)?($|\n))',
                                editorWidget.text(), re.M)
            blanks_count = len(blanks)
            resume = self.tr("Lines code: %s\n") % (block_count - blanks_count)
            resume += (self.tr("Blanks and commented lines: %s\n\n") %
                       blanks_count)
            resume += self.tr("Total lines: %s") % blockdget
            msgBox.exec_()

            msgBox = QMessageBox(QMessageBox.Information,
                                 self.tr("Summary of lines"), resume,
                                 QMessageBox.Ok, editorWidget)

    def editor_cut(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.cut()

    def editor_copy(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.copy()

    def editor_paste(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.paste()

    def editor_upper(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_upper()

    def editor_lower(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_lower()

    def editor_title(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_title()

    def editor_go_to_definition(self):
        """Search the definition of the method or variable under the cursor.

        If more than one method or variable is found with the same name,
        shows a table with the results and let the user decide where to go."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.go_to_definition()

    def editor_redo(self):
        """Execute the redo action in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.redo()

    def editor_undo(self):
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.undo()

    def editor_indent_less(self):
        """Indent 1 position to the left for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_less()

    def editor_indent_more(self):
        """Indent 1 position to the right for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_more()

    def editor_insert_debugging_prints(self):
        """Insert a print statement in each selected line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_debugging_prints(editorWidget)

    def editor_insert_pdb(self):
        """Insert a pdb.set_trace() statement in tjhe current line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_pdb(editorWidget)

    def editor_comment(self):
        """Mark the current line or selection as a comment."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.comment_or_uncomment(editorWidget)

    def editor_uncomment(self):
        """Uncomment the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.uncomment(editorWidget)

    def editor_insert_horizontal_line(self):
        """Insert an horizontal lines of comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_horizontal_line(editorWidget)

    def editor_insert_title_comment(self):
        """Insert a Title surrounded by comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_title_comment(editorWidget)

    def editor_remove_trailing_spaces(self):
        """Remove the trailing spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.remove_trailing_spaces(editorWidget)

    def editor_replace_tabs_with_spaces(self):
        """Replace the Tabs with Spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.replace_tabs_with_spaces(editorWidget)

    def editor_move_up(self):
        """Move the current line or selection one position up."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_up(editorWidget)

    def editor_move_down(self):
        """Move the current line or selection one position down."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_down(editorWidget)

    def editor_remove_line(self):
        """Remove the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.remove_line(editorWidget)

    def editor_duplicate(self):
        """Duplicate the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.duplicate(editorWidget)

    def editor_highlight_word(self):
        """Highlight the occurrences of the current word in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.highlight_selected_word()

    def editor_complete_declaration(self):
        """Do the opposite action that Complete Declaration expect."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.complete_declaration()

    def editor_go_to_line(self, line):
        """ Jump to the specified line in the current editor. """

        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.go_to_line(line)
            editorWidget.setFocus()

    def zoom_in_editor(self):
        """Increase the font size in the current editor."""

        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom(1.0)

    def zoom_out_editor(self):
        """Decrease the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom(-1.0)

    def reset_zoom(self):
        editor_widget = self.get_current_editor()
        if editor_widget is not None:
            editor_widget.reset_zoom()

    def recent_files_changed(self):
        self.emit(SIGNAL("recentTabsModified()"))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        file_path = event.mimeData().urls()[0].toLocalFile()
        self.open_file(file_path)

    def setFocus(self):
        widget = self.get_current_widget()
        if widget:
            widget.setFocus()

    def current_editor_changed(self, filename):
        """Notify the new filename of the current editor."""
        if filename is None:
            filename = translations.TR_NEW_DOCUMENT
        self.currentEditorChanged.emit(filename)

    def show_split(self, orientation_vertical=False):
        # IDE.select_current(self.current_widget.currentWidget())
        self.current_widget.split_editor(orientation_vertical)

    def add_editor(self, fileName=None, ignore_checkers=False):
        ninjaide = IDE.get_service('ide')
        editable = ninjaide.get_or_create_editable(fileName)
        if editable.editor:
            self.current_widget.set_current(editable)
            return self.current_widget.currentWidget()
        else:
            editable.ignore_checkers = ignore_checkers

        editorWidget = self.create_editor_from_editable(editable)

        # add the tab
        keep_index = (self.splitter.count() > 1
                      and self.combo_area.stacked.count() > 0)
        self.combo_area.add_editor(editable, keep_index)

        # emit a signal about the file open
        self.fileOpened.emit(fileName)

        if not keep_index:
            self.current_widget.set_current(editable)

        self.stack.setCurrentWidget(self.splitter)

        editorWidget.setFocus()

        return editorWidget

    def create_editor_from_editable(self, editable):
        neditor = editor.create_editor(editable)

        # Connect signals
        neditor.zoomChanged[int].connect(self._show_zoom_indicator)
        neditor.destroyed.connect(self._editor_destroyed)
        editable.fileSaved.connect(self._editor_tab_was_saved)
        neditor.addBackItemNavigation.connect(self.add_back_item_navigation)
        # self.connect(editable, SIGNAL("fileSaved(PyQt_PyObject)"),
        #             self._editor_tab_was_saved)
        # editorWidget.font_changed.connect(self.show_zoom_indicator)
        # self.connect(editorWidget, SIGNAL("openDropFile(QString)"),
        #             self.open_file)
        # self.connect(editorWidget, SIGNAL("addBackItemNavigation()"),
        #             self.add_back_item_navigation)
        # self.connect(editorWidget,
        #             SIGNAL("locateFunction(QString, QString, bool)"),
        #             self._editor_locate_function)
        # self.connect(editorWidget, SIGNAL("findOcurrences(QString)"),
        #             self._find_occurrences)
        # keyPressEventSignal for plugins
        # self.connect(editorWidget, SIGNAL("keyPressEvent(QEvent)"),
        #             self._editor_keyPressEvent)

        return neditor

    def _editor_destroyed(self):
        ui_tools.FadingIndicator.editor_destroyed()

    def _show_zoom_indicator(self, text):
        neditor = self.get_current_editor()
        ui_tools.FadingIndicator.show_text(neditor,
                                           "Zoom: {}%".format(str(text)))

    def reset_pep8_warnings(self, value):
        pass
        # FIXME: check how we handle this
        # for i in range(self._tabMain.count()):
        # widget = self._tabMain.widget(i)
        # if type(widget) is editor.Editor:
        # if value:
        # widget.syncDocErrorsSignal = True
        # widget.pep8.check_style()
        # else:
        # widget.hide_pep8_errors()

    def reset_lint_warnings(self, value):
        pass
        #FIXME: check how we handle this
        # for i in range(self._tabMain.count()):
        #widget = self._tabMain.widget(i)
        #if type(widget) is editor.Editor:
        #if value:
        #widget.syncDocErrorsSignal = True
        #widget.errors.check_errors()
        #else:
        #widget.hide_lint_errors()

    def show_zoom_indicator(self, text):
        ui_tools.FadingIndicator.show_text(self, "Zoom: {0}%".format(text))

    def _find_occurrences(self, word):
        self.emit(SIGNAL("findOcurrences(QString)"), word)

    def _editor_keyPressEvent(self, event):
        self.emit(SIGNAL("editorKeyPressEvent(QEvent)"), event)

    def _editor_locate_function(self, function, filePath, isVariable):
        self.emit(SIGNAL("locateFunction(QString, QString, bool)"), function,
                  filePath, isVariable)

    def _editor_tab_was_saved(self, editable=None):
        self.updateLocator.emit(editable.file_path)
        # self.emit(SIGNAL("updateLocator(QString)"), editable.file_path)

    def get_current_widget(self):
        return self.current_widget.currentWidget()

    def get_current_editor(self):
        """Return the Actual Editor or None

        Return an instance of Editor if the Current Tab contains
        an Editor or None if it is not an instance of Editor"""
        widget = self.current_widget.currentWidget()
        if isinstance(widget, editor.NEditor):
            return widget
        return None

    def reload_file(self, editorWidget=None):
        if editorWidget is None:
            editorWidget = self.get_current_editor()
            editorWidget.neditable.reload_file()

    def open_image(self, fileName):
        try:
            if not self.is_open(fileName):
                viewer = image_viewer.ImageViewer(fileName)
                # self.add_tab(viewer, file_manager.get_basename(fileName))
                # viewer.ID = fileName
            else:
                self.move_to_open(fileName)
        except Exception as reason:
            logger.error('open_image: %s', reason)
            QMessageBox.information(self, self.tr("Incorrect File"),
                                    self.tr("The image couldn\'t be open"))

    def open_file(self, filename='', line=-1, col=0, ignore_checkers=False):
        logger.debug("will try to open %s" % filename)
        if not filename:
            logger.debug("has nofilename")
            if settings.WORKSPACE:
                directory = settings.WORKSPACE
            else:
                directory = os.path.expanduser("~")
                editorWidget = self.get_current_editor()
                ninjaide = IDE.get_service('ide')
                if ninjaide:
                    current_project = ninjaide.get_current_project()
                    if current_project is not None:
                        directory = current_project
                    elif editorWidget is not None and editorWidget.file_path:
                        directory = file_manager.get_folder(
                            editorWidget.file_path)
            extensions = ';;'.join([
                '{}(*{})'.format(e.upper()[1:], e)
                for e in settings.SUPPORTED_EXTENSIONS + ['.*', '']
            ])
            fileNames = QFileDialog.getOpenFileNames(self,
                                                     self.tr("Open File"),
                                                     directory, extensions)[0]
        else:
            logger.debug("has filename")
            fileNames = [filename]
        if not fileNames:
            return

        for filename in fileNames:
            image_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png')
            if file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col, ignore_checkers)

    def __open_file(self, fileName='', line=-1, col=0, ignore_checkers=False):
        try:
            editorWidget = self.add_editor(fileName,
                                           ignore_checkers=ignore_checkers)
            if line != -1:
                editorWidget.go_to_line(line, col)
            self.currentEditorChanged.emit(fileName)
        except file_manager.NinjaIOException as reason:
            QMessageBox.information(self, self.tr("The file couldn't be open"),
                                    str(reason))

    def is_open(self, filename):
        pass
        #return self.tabs.is_open(filename) != -1

    def move_to_open(self, filename):
        pass
        #FIXME: add in the current split?
        #if self.tabs.is_open(filename) != -1:
        #self.tabs.move_to_open(filename)
        #self.tabs.currentWidget().setFocus()
        #self.emit(SIGNAL("currentEditorChanged(QString)"), filename)

    def get_widget_for_id(self, filename):
        pass
        #widget = None
        #index = self.tabs.is_open(filename)
        #if index != -1:
        #widget = self.tabs.widget(index)
        #return widget

    def change_open_tab_id(self, idname, newId):
        """Search for the Tab with idname, and set the newId to that Tab."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
        #widget = self.tabs.widget(index)
        #tabName = file_manager.get_basename(newId)
        #self.tabs.change_open_tab_name(index, tabName)
        #widget.ID = newId

    def close_deleted_file(self, idname):
        """Search for the Tab with id, and ask the user if should be closed."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
        #result = QMessageBox.question(self, self.tr("Close Deleted File"),
        #self.tr("Are you sure you want to close the deleted file?\n"
        #"The content will be completely deleted."),
        #buttons=QMessageBox.Yes | QMessageBox.No)
        #if result == QMessageBox.Yes:
        #self.tabs.removeTab(index)

    def save_file(self, editorWidget=None):
        # FIXME: check how we handle this
        if not editorWidget:
            editorWidget = self.get_current_editor()
        if editorWidget is None:
            return False
        # Ok, we have an editor instance
        # Save to file only if editor really was modified
        if editorWidget.is_modified:
            try:
                if (editorWidget.nfile.is_new_file
                        or not editorWidget.nfile.has_write_permission()):
                    return self.save_file_as()

                self.beforeFileSaved.emit(editorWidget.file_path)

                if settings.REMOVE_TRAILING_SPACES:
                    helpers.remove_trailing_spaces(editorWidget)
                # New line at end
                # FIXME: from settings
                helpers.insert_block_at_end(editorWidget)
                # Save convent
                editorWidget.neditable.save_content()
                encoding = file_manager.get_file_encoding(editorWidget.text)
                editorWidget.encoding = encoding

                self.fileSaved.emit(
                    self.tr("File Saved: {}".format(editorWidget.file_path)))

                return True
            except Exception as reason:
                logger.error('save_file: %s', reason)
                QMessageBox.information(self, self.tr("Save Error"),
                                        self.tr("The file couldn't be saved!"))
            return False

    def save_file_as(self):
        editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            filters = '(*.py);;(*.*)'
            if editorWidget.file_path:  # existing file
                ext = file_manager.get_file_extension(editorWidget.file_path)
                if ext != 'py':
                    filters = '(*.%s);;(*.py);;(*.*)' % ext
            save_folder = self._get_save_folder(editorWidget.file_path)
            fileName = QFileDialog.getSaveFileName(self._parent,
                                                   self.tr("Save File"),
                                                   save_folder, filters)[0]
            if not fileName:
                return False

            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)

            ext = file_manager.get_file_extension(fileName)
            if not ext:
                fileName = '%s.%s' % (
                    fileName,
                    'py',
                )

            editorWidget.neditable.save_content(path=fileName)
            # editorWidget.register_syntax(
            #     file_manager.get_file_extension(fileName))

            self.fileSaved.emit(self.tr("File Saved: {}".format(fileName)))

            self.currentEditorChanged.emit(fileName)

            return True
        except file_manager.NinjaFileExistsException as ex:
            QMessageBox.information(
                self, self.tr("File Already Exists"),
                (self.tr("Invalid Path: the file '%s' "
                         " already exists.") % ex.filename))
        except Exception as reason:
            logger.error('save_file_as: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def _get_save_folder(self, fileName):
        """
        Returns the root directory of the 'Main Project' or the home folder
        """
        ninjaide = IDE.get_service('ide')
        current_project = ninjaide.get_current_project()
        if current_project:
            return current_project.path
        return os.path.expanduser("~")

    def save_project(self, projectFolder):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
        #editorWidget = self._tabMain.widget(i)
        #if type(editorWidget) is editor.Editor and \
        #file_manager.belongs_to_folder(projectFolder,
        #editorWidget.file_path):
        #reloaded = self._tabMain.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
        #editorWidget = self.tabsecondary.widget(i)
        #if type(editorWidget) is editor.Editor and \
        #file_manager.belongs_to_folder(projectFolder,
        #editorWidget.file_path):
        #reloaded = self.tabsecondary.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)

    def save_all(self):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
        #editorWidget = self._tabMain.widget(i)
        #if type(editorWidget) is editor.Editor:
        #reloaded = self._tabMain.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
        #editorWidget = self.tabsecondary.widget(i)
        #self.tabsecondary.check_for_external_modifications(editorWidget)
        #if type(editorWidget) is editor.Editor:
        #reloaded = self.tabsecondary.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)

    def call_editors_function(self, call_function, *arguments):
        pass
        #args = arguments[0]
        #kwargs = arguments[1]
        #for i in range(self.tabs.count()):
        #editorWidget = self.tabs.widget(i)
        #if isinstance(editorWidget, editor.Editor):
        #function = getattr(editorWidget, call_function)
        #function(*args, **kwargs)
        #TODO: add other splits

    def show_start_page(self):
        start = self.stack.widget(0)
        if isinstance(start, start_page.StartPage):
            self.stack.setCurrentIndex(0)
        else:
            startPage = start_page.StartPage(parent=self)
            # self.connect(startPage, SIGNAL("openProject(QString)"),
            #             self.open_project)
            # self.connect(startPage, SIGNAL("openPreferences()"),
            #             lambda: self.emit(SIGNAL("openPreferences()")))
            # Connections
            startPage.newFile.connect(self.add_editor)
            self.stack.insertWidget(0, startPage)
            self.stack.setCurrentIndex(0)

    def show_python_doc(self):
        if sys.platform == 'win32':
            self.docPage = browser_widget.BrowserWidget(
                'http://docs.python.org/')
        else:
            process = runner.start_pydoc()
            self.docPage = browser_widget.BrowserWidget(process[1], process[0])
        self.add_tab(self.docPage, translations.TR_PYTHON_DOC)

    def show_report_bugs(self):
        webbrowser.open(resources.BUGS_PAGE)

    def show_plugins_doc(self):
        bugsPage = browser_widget.BrowserWidget(resources.PLUGINS_DOC, self)
        self.add_tab(bugsPage, translations.TR_HOW_TO_WRITE_PLUGINS)

    def editor_jump_to_line(self, lineno=None):
        """Jump to line *lineno* if it is not None
        otherwise ask to the user the line number to jump
        """
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.jump_to_line(lineno=lineno)

    def get_opened_documents(self):
        #return self.tabs.get_documents_data()
        return []

    def check_for_unsaved_files(self):
        pass
        #return self.tabs._check_unsaved_tabs()

    def get_unsaved_files(self):
        pass
        #return self.tabs.get_unsaved_files()

    def reset_editor_flags(self):
        pass
        #for i in range(self.tabs.count()):
        #widget = self.tabs.widget(i)
        #if isinstance(widget, editor.Editor):
        #widget.set_flags()

    def _specify_syntax(self, widget, syntaxLang):
        if isinstance(widget, editor.Editor):
            widget.restyle(syntaxLang)

    def apply_editor_theme(self, family, size):
        pass
        #for i in range(self.tabs.count()):
        #widget = self.tabs.widget(i)
        #if isinstance(widget, editor.Editor):
        #widget.restyle()
        #widget.set_font(family, size)

    def update_editor_margin_line(self):
        pass
        #for i in range(self.tabs.count()):
        #widget = self.tabs.widget(i)
        #if isinstance(widget, editor.Editor):
        #widget._update_margin_line()

    def open_project(self, path):
        self.emit(SIGNAL("openProject(QString)"), path)

    def close_python_doc(self):
        pass
        # close the python document server (if running)
        # if self.docPage:
        #    index = self.tabs.indexOf(self.docPage)
        #    self.tabs.removeTab(index)
        #    assign None to the browser
        #    self.docPage = None

    def close_file(self):
        self.current_widget.close_current_file()

    def create_file(self, base_path, project_path):
        self._add_file_folder.create_file(base_path, project_path)

    def create_folder(self, base_path, project_path):
        self._add_file_folder.create_folder(base_path, project_path)

    def change_tab(self):
        """Change the tab in the current TabWidget."""
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.next_item()

    def change_tab_reverse(self):
        """Change the tab in the current TabWidget backwards."""
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.previous_item()

    def toggle_tabs_and_spaces(self):
        """Toggle Show/Hide Tabs and Spaces"""

        settings.SHOW_TABS_AND_SPACES = not settings.SHOW_TABS_AND_SPACES
        qsettings = IDE.ninja_settings()
        qsettings.setValue('preferences/editor/show_tabs_and_spaces',
                           settings.SHOW_TABS_AND_SPACES)
        neditor = self.get_current_editor()
        if neditor is not None:
            neditor.show_whitespaces = settings.SHOW_TABS_AND_SPACES

    def show_navigation_buttons(self):
        """Show Navigation menu."""
        self.stack.setCurrentWidget(self.splitter)
        self.combo_area.show_menu_navigation()

    def change_split_focus(self):
        pass
        #FIXME: check how we handle this
        #if self.actualTab == self._tabMain and self.tabsecondary.isVisible():
        #self.actualTab = self.tabsecondary
        #else:
        #self.actualTab = self._tabMain
        #widget = self.actualTab.currentWidget()
        #if widget is not None:
        #widget.setFocus()

    def shortcut_index(self, index):
        pass
        #self.tabs.setCurrentIndex(index)

    def print_file(self):
        """Call the print of ui_tool

        Call print of ui_tool depending on the focus of the application"""
        #TODO: Add funtionality for proyect tab and methods tab
        editorWidget = self.get_current_editor()
        if editorWidget is not None:
            fileName = "newDocument.pdf"
            if editorWidget.file_path:
                fileName = file_manager.get_basename(editorWidget.file_path)
                fileName = fileName[:fileName.rfind('.')] + '.pdf'
            ui_tools.print_file(fileName, editorWidget.print_)

    def split_assistance(self):
        dialog = split_orientation.SplitOrientation(self)
        dialog.show()

    # def close_split(self):
    #    if self.current_widget != self.combo_area:
    #        self.current_widget.bar.close_split()

    # def split_vertically(self):
    #    self.show_split(False)

    # def split_horizontally(self):
    #    self.show_split(True)

    def navigate_back(self):
        self.__navigate_with_keyboard(False)

    def navigate_forward(self):
        self.__navigate_with_keyboard(True)
예제 #3
0
class RightPanel(QFrame):
    def __init__(self, app, parent=None):
        super().__init__(parent)

        self._app = app
        self._pixmap = None

        self._layout = QVBoxLayout(self)
        self._stacked_layout = QStackedLayout()
        self.scrollarea = ScrollArea(self._app, self)
        self.table_container = self.scrollarea.t
        # TODO: collection container will be removed
        self.collection_container = CollectionContainer(self._app, self)
        self.bottom_panel = BottomPanel(app, self)

        self._setup_ui()

    def _setup_ui(self):
        self.scrollarea.setMinimumHeight(100)
        self.collection_container.hide()
        self._layout.addWidget(self.bottom_panel)
        self._layout.addLayout(self._stacked_layout)
        self._stacked_layout.addWidget(self.scrollarea)
        self._stacked_layout.addWidget(self.collection_container)
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)

    def show_model(self, model):
        self.set_body(self.scrollarea)
        # TODO: use PreemptiveTask
        aio.create_task(self.table_container.show_model(model))

    def show_songs(self, songs):
        self.collection_container.hide()
        self.set_body(self.scrollarea)
        self.table_container.show_songs(songs)

    def set_body(self, widget):
        """

        .. versionadded:: 3.7.7
        """
        if widget is self.table_container:
            widget = self.scrollarea

        if widget is not self.scrollarea:
            self.show_background_image(None)

        # remove tmp widgets
        for i in range(self._stacked_layout.count()):
            w = self._stacked_layout.widget(i)
            if w not in (self.scrollarea, self.collection_container):
                self._stacked_layout.removeWidget(w)

        self._stacked_layout.addWidget(widget)
        self._stacked_layout.setCurrentWidget(widget)

    def show_collection(self, coll):
        def _show_pure_albums_coll(coll):
            self.set_body(self.scrollarea)
            reader = wrap(coll.models)
            self.table_container.show_albums_coll(reader)

        def _show_pure_songs_coll(coll):
            self.set_body(self.scrollarea)
            self.table_container.show_collection(coll)

        def _show_mixed_coll(coll):
            self.set_body(self.collection_container)
            self.collection_container.show_collection(coll)

        def _show_pure_videos_coll(coll):
            from feeluown.gui.page_containers.table import VideosRenderer

            self.set_body(self.scrollarea)
            reader = wrap(coll.models)
            renderer = VideosRenderer(reader)
            aio.create_task(self.table_container.set_renderer(renderer))

        if coll.type is CollectionType.sys_library:
            self._app.browser.goto(page='/colls/library')
            return

        types = set()
        for model in coll.models:
            types.add(model.meta.model_type)
            if len(types) >= 2:
                break

        if len(types) == 1:
            type_ = types.pop()
            if type_ == ModelType.song:
                _show_pure_songs_coll(coll)
            elif type_ == ModelType.album:
                _show_pure_albums_coll(coll)
            elif type_ == ModelType.video:
                _show_pure_videos_coll(coll)
            else:
                _show_mixed_coll(coll)
        else:
            _show_mixed_coll(coll)

    def show_background_image(self, pixmap):
        self._pixmap = pixmap
        if pixmap is None:
            self.table_container.meta_widget.setMinimumHeight(0)
        else:
            height = (self._app.height() - self.bottom_panel.height() -
                      self.table_container.toolbar.height()) // 2
            self.table_container.meta_widget.setMinimumHeight(height)
        self.update()

    def paintEvent(self, e):
        """
        draw pixmap as a the background with a dark overlay

        HELP: currently, this cost much CPU
        """
        painter = QPainter(self)
        painter.setPen(Qt.NoPen)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)

        # calculate available size
        draw_width = self.width()
        draw_height = 10  # spacing defined in table container
        draw_height += self.bottom_panel.height()
        if self.table_container.meta_widget.isVisible():
            draw_height += self.table_container.meta_widget.height()
        extra = self.table_container.current_extra
        if extra is not None and extra.isVisible():
            draw_height += extra.height()
        if self.table_container.toolbar.isVisible():
            draw_height += self.table_container.toolbar.height()

        scrolled = self.scrollarea.verticalScrollBar().value()
        max_scroll_height = draw_height - self.bottom_panel.height()

        if scrolled >= max_scroll_height:
            painter.save()
            painter.setBrush(self.palette().brush(QPalette.Window))
            painter.drawRect(self.bottom_panel.rect())
            painter.restore()
            return

        if self._pixmap is not None:
            self._draw_pixmap(painter, draw_width, draw_height, scrolled)
            self._draw_pixmap_overlay(painter, draw_width, draw_height,
                                      scrolled)
        else:
            # draw gradient for widgets(bottom panel + meta_widget + ...) above table
            self._draw_overlay(painter, draw_width, draw_height, scrolled)

            # if scrolled height > 30, draw background to seperate bottom_panel and body
            if scrolled >= 30:
                painter.save()
                painter.setBrush(self.palette().brush(QPalette.Window))
                painter.drawRect(self.bottom_panel.rect())
                painter.restore()
                return

            # since the body's background color is palette(base), we use
            # the color to draw background for remain empty area
            painter.save()
            painter.setBrush(self.palette().brush(QPalette.Base))
            painter.drawRect(0, draw_height, draw_width,
                             self.height() - draw_height)
            painter.restore()
        painter.end()

    def _draw_pixmap_overlay(self, painter, draw_width, draw_height, scrolled):
        painter.save()
        rect = QRect(0, 0, draw_width, draw_height)
        painter.translate(0, -scrolled)
        gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft())
        color = self.palette().color(QPalette.Base)
        if draw_height == self.height():
            gradient.setColorAt(0, add_alpha(color, 180))
            gradient.setColorAt(1, add_alpha(color, 230))
        else:
            if self._app.theme_mgr.theme == Light:
                gradient.setColorAt(0, add_alpha(color, 220))
                gradient.setColorAt(0.1, add_alpha(color, 180))
                gradient.setColorAt(0.2, add_alpha(color, 140))
                gradient.setColorAt(0.6, add_alpha(color, 140))
                gradient.setColorAt(0.8, add_alpha(color, 200))
                gradient.setColorAt(0.9, add_alpha(color, 240))
                gradient.setColorAt(1, color)
            else:
                gradient.setColorAt(0, add_alpha(color, 50))
                gradient.setColorAt(0.6, add_alpha(color, 100))
                gradient.setColorAt(0.8, add_alpha(color, 200))
                gradient.setColorAt(0.9, add_alpha(color, 240))
                gradient.setColorAt(1, color)
        painter.setBrush(gradient)
        painter.drawRect(rect)
        painter.restore()

    def _draw_overlay(self, painter, draw_width, draw_height, scrolled):
        painter.save()
        rect = QRect(0, 0, draw_width, draw_height)
        painter.translate(0, -scrolled)
        gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft())
        gradient.setColorAt(0, self.palette().color(QPalette.Window))
        gradient.setColorAt(1, self.palette().color(QPalette.Base))
        painter.setBrush(gradient)
        painter.drawRect(rect)
        painter.restore()

    def _draw_pixmap(self, painter, draw_width, draw_height, scrolled):
        # scale pixmap
        scaled_pixmap = self._pixmap.scaledToWidth(
            draw_width, mode=Qt.SmoothTransformation)
        pixmap_size = scaled_pixmap.size()

        # draw the center part of the pixmap on available rect
        painter.save()
        brush = QBrush(scaled_pixmap)
        painter.setBrush(brush)
        # note: in practice, most of the time, we can't show the
        # whole artist pixmap, as a result, the artist head will be cut,
        # which causes bad visual effect. So we render the top-center part
        # of the pixmap here.
        y = (pixmap_size.height() - draw_height) // 3
        painter.translate(0, -y - scrolled)
        rect = QRect(0, y, draw_width, draw_height)
        painter.drawRect(rect)
        painter.restore()

    def sizeHint(self):
        size = super().sizeHint()
        return QSize(760, size.height())
예제 #4
0
class DialogWindow(QWidget):
    DIALOG_MAINMENU = 'mainmenu'
    DIALOG_TALK = 'talk'
    DIALOG_INPUT = 'input'

    def __init__(self, soul, win_id):
        QWidget.__init__(self)
        self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint
                            | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        # self.setAttribute(Qt.WA_DeleteOnClose)
        # self.setMouseTracking(True)
        # self.setAcceptDrops(True)

        self.ID = win_id
        self._soul = soul
        self._ghost = self._soul.getGhost()
        self._shellwindow = self._soul.getShellWindow()
        self._framelessWindowHint = True
        self.isFlip = False
        self.setWindowTitle(self._ghost.name)
        self.setContentsMargins(0, 0, 0, 0)

        self._bgImage = None
        self._bgPixmap = None
        self._bgMask = None
        self._rect = None

        self._curPage = 0
        self._widgets = {}
        self._talkLabel = None
        self._inputLineEdit = None
        self._callback = None
        self.init()

    def init(self):
        # rect
        rect = self._soul.memoryRead('DialogRect', [])
        if len(rect) > 0:
            self._rect = QRect(rect[0], rect[1], rect[2], rect[3])
            self.resize(self._rect.size())
        else:
            p_pos = self._shellwindow.pos()
            p_size = self._shellwindow.size()
            self.resize(kikka.const.WindowConst.DialogWindowDefaultSize)
            x = int(p_pos.x() - self.size().width())
            y = int(p_pos.y() + p_size.height() / 2 - self.size().height())

            self._rect = QRect(QPoint(x, y), self.size())
            rectdata = [
                x - p_pos.x(), y - p_pos.y(),
                self.size().width(),
                self.size().height()
            ]
            self._soul.memoryWrite('DialogRect', rectdata)

        # default control
        self._talkLabel = QLabel()
        self._talkLabel.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self._talkLabel.setWordWrap(True)

        self._inputLabel = QLabel()
        self._inputLineEdit = QLineEdit()
        self._inputOk = QPushButton("OK")
        self._inputOk.clicked.connect(self.onInputOk)
        self._inputCancel = QPushButton("Cancel")
        self._inputCancel.clicked.connect(self.onInputCancel)

        # default UI
        talkLayout = QVBoxLayout()
        talkLayout.addWidget(self._talkLabel)
        talkWidget = QWidget(self)
        talkWidget.setContentsMargins(0, 0, 0, 0)
        talkWidget.setLayout(talkLayout)

        menuWidget = QWidget(self)
        menuWidget.setContentsMargins(0, 0, 0, 0)

        l = QHBoxLayout()
        l.addStretch()
        l.addWidget(self._inputOk)
        l.addWidget(self._inputCancel)
        inputLayout = QVBoxLayout()
        inputLayout.addWidget(self._inputLabel)
        inputLayout.addWidget(self._inputLineEdit)
        inputLayout.addLayout(l)
        inputLayout.addStretch()
        inputWidget = QWidget(self)
        inputWidget.setContentsMargins(0, 0, 0, 0)
        inputWidget.setLayout(inputLayout)

        self.setPage(self.DIALOG_MAINMENU, menuWidget)
        self.setPage(self.DIALOG_TALK, talkWidget)
        self.setPage(self.DIALOG_INPUT, inputWidget)

        self._mainLayout = QStackedLayout()
        self._mainLayout.addWidget(menuWidget)
        self.setLayout(self._mainLayout)

    def setFramelessWindowHint(self, boolean):
        self._framelessWindowHint = boolean
        if self._framelessWindowHint is False:
            self.clearMask()
            self.setWindowFlag(Qt.FramelessWindowHint, False)
            self.setWindowOpacity(0.8)
            self.setEnabled(False)

            self.show()
            self.move(2 * self.pos().x() - self.geometry().x(),
                      2 * self.pos().y() - self.geometry().y())
            self.update()
            self.activateWindow()
        else:
            self._rect.setX(self.geometry().x() - self._shellwindow.pos().x())
            self._rect.setY(self.geometry().y() - self._shellwindow.pos().y())
            self._rect.setSize(self.geometry().size())
            rectdata = [
                self._rect.x(),
                self._rect.y(),
                self._rect.width(),
                self._rect.height()
            ]
            self._soul.memoryWrite('DialogRect', rectdata)

            pos = QPoint(self.pos().x(), self.pos().y())
            self.setWindowFlag(Qt.FramelessWindowHint, True)
            self.setWindowOpacity(1)
            self.setEnabled(True)
            self.setMask(self._bgMask)
            self.show()
            self.move(pos.x(), pos.y())

    def updatePosition(self):
        if self._framelessWindowHint is False:
            return

        p_pos = self._shellwindow.pos()
        p_size = self._shellwindow.size()
        new_x = self._rect.x() + p_pos.x()
        new_y = self._rect.y() + p_pos.y()
        self.resize(self._rect.size())

        flip = False
        sw, sh = kikka.helper.getScreenResolution()
        if new_x + self.width() > sw or new_x < 0:
            flip = True
            new_x = int(p_pos.x() * 2 + p_size.width() - new_x - self.width())
            if new_x + self.width() > sw:
                new_x = p_pos.x() - self.width()
            if new_x < 0:
                new_x = p_pos.x() + p_size.width()
        if self.isFlip != flip:
            self.isFlip = flip
            self.repaint()

        super().move(new_x, new_y)

    def setPage(self, tag, qwidget):
        if tag in self._widgets:
            self._widgets[tag].deleteLater()
        qwidget.hide()
        qwidget.setParent(self)
        self._widgets[tag] = qwidget

    def getTalkLabel(self):
        return self._talkLabel

    def showInputBox(self, title, default='', callback=None):
        self._inputLabel.setText(title)
        self._inputLineEdit.setText(default)
        self._callback = callback
        self.show(self.DIALOG_INPUT)

    def show(self, pageTag=None):
        if pageTag is None:
            pageTag = self.DIALOG_MAINMENU
        elif pageTag not in self._widgets:
            logging.warning("show: page[%s] not exist" % pageTag)
            pageTag = self.DIALOG_MAINMENU

        if self._widgets[pageTag] != self._mainLayout.currentWidget():
            self._mainLayout.removeWidget(self._mainLayout.currentWidget())
            self._mainLayout.addWidget(self._widgets[pageTag])
            self._mainLayout.setCurrentIndex(0)
            self._curPage = pageTag

        param = kikka.helper.makeGhostEventParam(
            self._ghost.ID, self._soul.ID, kikka.const.GhostEvent.Dialog_Show,
            'Show')
        param.data['pageTag'] = self._curPage
        self._ghost.emitGhostEvent(param)

        super().show()
        self.updatePosition()

    def closeEvent(self, event):
        self.setFramelessWindowHint(True)
        event.ignore()
        pass

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.repaint()

    def paintEvent(self, event):
        painter = QPainter(self)
        pixmap = QPixmap().fromImage(self._bgImage, Qt.AutoColor)
        painter.drawPixmap(self.rect(), pixmap)

        opt = QStyleOption()
        opt.initFrom(self)
        self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
        super().paintEvent(event)

    def setBalloon(self, balloon):
        self.setMinimumSize(balloon.minimumsize)
        self.setContentsMargins(balloon.margin[0], balloon.margin[1],
                                balloon.margin[2], balloon.margin[3])
        self.setStyleSheet(balloon.stylesheet)
        self.style().unpolish(self)
        self.style().polish(self)

    def repaint(self):
        self._bgImage = self._ghost.getBalloonImage(self.size(), self.isFlip,
                                                    self.ID)
        self._bgPixmap = QPixmap().fromImage(self._bgImage, Qt.AutoColor)
        self._bgMask = self._bgPixmap.mask()
        super().repaint()

    def talkClear(self):
        self._talkLabel.setText('')

    def onTalk(self, message, speed=50):
        text = self._talkLabel.text()
        text += message
        self._talkLabel.setText(text)

    def onInputOk(self):
        if self._callback is not None:
            self._callback(self._inputLineEdit.text())
        self.hide()

    def onInputCancel(self):
        self.hide()
예제 #5
0
class MainWidget(QMainWindow):
    __instance = None

    @staticmethod
    def getinstance():
        if (MainWidget.__instance == None):
            MainWidget()
        return MainWidget.__instance
		
    def __init__(self, user:User):
        super().__init__()
        if (MainWidget.__instance != None):
            raise Exception ("Singleton")
        else:
            self.initUI(user)
            MainWidget.__instance = self
			
				
    def initUI(self, user:User):    
        self.mainWidget = QWidget()
        self.setMinimumSize(500,500)
        self.user = user
        self.controller = MainWidgetController(self.user)
        self.setStyleSheet(open('main.css').read())
        self.dashboard_button = QPushButton("Dashboard")
        self.dashboard_button.setFixedWidth(150)
        self.dashboard_button.clicked.connect(lambda success:self.LoadDashboardLayout(success))
        self.dashboard_button.setObjectName("dashboard_button")
        
        self.home_button = QPushButton("Home")
        self.home_button.setFixedWidth(150)
        self.home_button.clicked.connect(lambda:self.LoadHomeLayout())
        self.home_button.setObjectName("home_button")
        
        self.profile_button = QPushButton("Profile")
        self.profile_button.setFixedWidth(150)
        self.profile_button.clicked.connect(lambda success:self.LoadProfileLayout(success))
        self.profile_button.setObjectName("profile_button")
                
        
        self.grid = QGridLayout()

        self.upperLayout = QHBoxLayout()
        
        self.upperLayout.addWidget(self.dashboard_button)
        self.upperLayout.addWidget(self.home_button)
        self.upperLayout.addWidget(self.profile_button)
        
        self.upperExternal = QFrame()
        self.upperExternal.setObjectName("upperExternal")    
        self.upperExternal.setLayout(self.upperLayout)
        
       #print(self.user.courses)
       
        self.home_layout = None
        self.dashboard_layout = None
        self.profile_layout = None
        self.course_layout = None
        self.new_course_layout = None
        self.movie_layout = None
        self.addmovie_layout = None
        self.CourseMovies_layout = None
        self.changepass_layout = None
        
        self.stack = QStackedLayout()
        
        self.grid.addWidget(self.upperExternal,1,1)
        self.grid.addLayout(self.stack,2,1)
        
        self.mainWidget.setLayout(self.grid)
        self.setCentralWidget(self.mainWidget)
        self.LoadHomeLayout()
#        self.Recommender=RecommendationEngine()
#        self.Recommender.LoadRecommendations(self.user)
        exit = QAction("&Exit", self)
        exit.triggered.connect(self.closeEvent)
        
        
        self.show()
    
    def closeEvent(self, event):
        
        self.silence()
        close = QMessageBox()
        close.setText("You sure?")
        close.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel)
        close = close.exec()
        
        if close == QMessageBox.Yes:        
            event.accept()
        else:
            event.ignore()
    
    
    #HomeLayoout----------------------------------------------------------------------------------
    #Sets homelayout as default layout
    def LoadHomeLayout(self):
        self.setWindowTitle("Home")
        if self.home_layout == None:
            self.home_layout = HomeLayout(self.user)
            self.home_layout._WatchMovie_.connect(lambda url, M_ID:self.LoadMovieLayout(url, M_ID))
            self.stack.addWidget(self.home_layout)
        self.stack.setCurrentWidget(self.home_layout)
        self.silence()
    
    #sets movielayout as default layout
    def LoadMovieLayout(self, url, movieID):
        self.setWindowTitle("Movie")
        if self.movie_layout!=None:
            self.stack.removeWidget(self.movie_layout)
            del self.movie_layout
            
        self.movie_layout = MovieLayout(url, movieID, self.user)
        self.stack.addWidget(self.movie_layout)
        self.stack.setCurrentWidget(self.movie_layout) 
 
    
    
    

    #DashBoardLayout----------------------------------------------------------------------------------
    #sets dashboard layout as default layout
    def LoadDashboardLayout(self, success):
        if self.dashboard_layout!=None:
            self.stack.removeWidget(self.dashboard_layout)
            del self.dashboard_layout
       
        self.setWindowTitle("Dashboard")
        
        self.dashboard_layout = DashboardLayout(self.user)
        self.dashboard_layout.new_course_request.connect(self.LoadCourseLayout)
        
        self.dashboard_layout.openCourse_request.connect(lambda x: self.LoadCourseMovies(x))
        self.stack.addWidget(self.dashboard_layout)
            
        self.stack.setCurrentWidget(self.dashboard_layout)
        self.silence()
        
        if(success == 1):
            self.dashboard_layout.message.setText("Successfully Submitted Course")
            self.course_layout = None
        elif(success == 2):
            self.dashboard_layout.message.setText("Successfully Submitted Movie")
            self.addmovie_layout = None
        elif(success == 3):
            pass
        elif(success == 4):
            self.dashboard_layout.message.setText("Successfully Enrolled in Course")
            self.course_layout = None
    
    #sets course layout as default layout (upload courses)
    def LoadCourseLayout(self):
        self.setWindowTitle("Add Course")
        if self.course_layout == None and isinstance(self.user, Professor) == True:
            self.course_layout = CourseInputDialog(self.user)
            self.course_layout.loaddashlayout.connect(lambda success:self.LoadDashboardLayout(success)) 
            
            self.stack.addWidget(self.course_layout)
        elif self.course_layout == None and isinstance(self.user, Student) == True:
            self.course_layout = CourseInputDialog(self.user)
            self.course_layout.loaddashlayout.connect(lambda success:self.LoadDashboardLayout(success))       
            self.stack.addWidget(self.course_layout)
#        self.course_layout.refreshDash.connect(self.)
        self.course_layout.refreshCourses_request.connect(self.RefreshProfile)
        self.stack.setCurrentWidget(self.course_layout)
    
    #sets dash movie layout as default layout (upload movie)
    def LoadDashMovieLayout(self, courseID):
        self.setWindowTitle("Add Movie")
        if self.addmovie_layout!=None:
            self.stack.removeWidget(self.addmovie_layout)
            del self.addmovie_layout
               
        self.addmovie_layout = MovieInputDialog(self.user, courseID)
        self.addmovie_layout.goback_request.connect(lambda C_ID:self.LoadCourseMovies(C_ID))
        self.stack.addWidget(self.addmovie_layout)
        self.stack.setCurrentWidget(self.addmovie_layout)
    
    def LoadCourseMovies(self, courseID):
        self.setWindowTitle("Course Movies")
        if self.CourseMovies_layout!=None:
            self.stack.removeWidget(self.CourseMovies_layout)
            del self.CourseMovies_layout
        self.CourseMovies_layout = CourseMovieLayout(self.user, courseID)
        self.CourseMovies_layout.new_movie_request.connect(lambda C_ID: self.LoadDashMovieLayout(C_ID))
        self.CourseMovies_layout.goback_request.connect(lambda success:self.LoadDashboardLayout(success))
        self.CourseMovies_layout._WatchMovie_.connect(lambda url, M_ID:self.LoadMovieLayout(url, M_ID))
        self.stack.addWidget(self.CourseMovies_layout)
            
        self.stack.setCurrentWidget(self.CourseMovies_layout)

 
    
    
    #ProfileLayout---------------------------------------------------------------------------------------------
    #sets profile layout as default layout
    def LoadProfileLayout(self, success):
        self.setWindowTitle("Profile")
        if self.profile_layout != None:
            self.stack.removeWidget(self.profile_layout)
            del self.profile_layout
            
        self.profile_layout = ProfileLayout(self.user)
        self.profile_layout.changePass_request.connect(lambda : self.LoadChangePassLayout())
        self.profile_layout.changeImage_request.connect(lambda image: self.ChangeImage(image))
        if(success == 1):
            self.profile_layout.errorMessage.setText("Password Changed Successfully")
        
        
        self.stack.addWidget(self.profile_layout)
        self.stack.setCurrentWidget(self.profile_layout)
        self.silence()
        
    def LoadChangePassLayout(self):
        self.setWindowTitle("Change Password")
        if self.changepass_layout == None:
            self.changepass_layout = ChangePasswordLayout(self.user)
            self.changepass_layout.goback_request.connect(lambda success:self.LoadProfileLayout(success))    
            self.stack.addWidget(self.changepass_layout)
            
        self.stack.setCurrentWidget(self.changepass_layout)

    #-----------------------------------------------------------------------------------------------------------
    #stops movie from running in background (movie cleanup)
    def silence(self):
        if(self.movie_layout != None):
            self.movie_layout.Stop()
            
    def RefreshProfile(self):
        self.user.courses = self.controller.refresh()
        
        
    def ChangeImage(self, image):
        self.user.image = image
예제 #6
0
class mainWindow(QMainWindow):
    end_game = False

    def __init__(self):
        super().__init__()
        self.setWindowTitle('Oczko 21')
        self.setGeometry(400, 40, 700, 640)
        self.create_welcome_layout()
        self.stacked_layout = QStackedLayout()
        self.stacked_layout.addWidget(self.welcome_widget)

        self.central_widget = QWidget()
        self.central_widget.setLayout(self.stacked_layout)
        self.setCentralWidget(self.central_widget)

        #====================Create New Game Layout=====================
        self.create_new_game_layout()
        self.stacked_layout.addWidget(self.new_game_widget)

        #==========================MAIN MENU====================================
        self.statusBar()
        newGame = QAction('&New Game', self)
        newGame.setStatusTip('Starts a new game...')
        newGame.triggered.connect(self.newGame_opt)

        help = QAction('&Help', self)
        help.setStatusTip('Help...')
        help.triggered.connect(self.help_opt)

        quitGame = QAction('&Quit', self)
        quitGame.setStatusTip('Quits the game...')
        quitGame.triggered.connect(self.quit_opt)

        mainMenu = self.menuBar()

        optionsMenu = mainMenu.addMenu('&Options')
        optionsMenu.addAction(newGame)
        optionsMenu.addAction(help)
        optionsMenu.addAction(quitGame)

        #=======================END MAIN MENU===========================================

    def newGame_opt(self):  #options from menu bar

        if self.stacked_layout.currentIndex() != 0:
            choice = QMessageBox.question(self, 'Start a new game',
                                          'Do you want to start a new game?',
                                          QMessageBox.Yes | QMessageBox.No)

            if choice == QMessageBox.Yes:
                self.new_game_radio_button.check_first()
                self.stacked_layout.setCurrentIndex(1)
                self.player1_line_edit.setText('Player 1')
                self.player2_line_edit.setText('Player 2')
            else:
                pass

        else:
            self.new_game_radio_button.check_first()
            self.stacked_layout.setCurrentIndex(1)
            self.player1_line_edit.setText('Player 1')
            self.player2_line_edit.setText('Player 2')

    def quit_opt(self):  #options from menu bar

        choice = QMessageBox.question(self, 'Exit',
                                      'Do you really want to exit the game?',
                                      QMessageBox.Yes | QMessageBox.No)

        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

    def help_opt(self):  # options from menu bar

        self.dialog = HelpWindow()
        self.dialog.show()

    @classmethod
    def end_game_change_value(cls,
                              value):  #method used to verify if game has ended
        cls.end_game = value

    def create_welcome_layout(self):  #first layout

        self.welcome_layout = QVBoxLayout()
        self.welcome_widget = QWidget()
        self.welcome_widget.setLayout(self.welcome_layout)

    def create_new_game_layout(self):  #start new game layout (new game menu)

        self.player1_label = QLabel('First player name:')
        self.player2_label = QLabel('Second player name:')

        self.player1_line_edit = QLineEdit()
        self.player2_line_edit = QLineEdit()

        self.cancel_button = QPushButton('Cancel')
        self.cancel_button.setMaximumWidth(330)
        self.cancel_button.setMinimumWidth(330)
        self.cancel_button.setMinimumHeight(60)

        self.start_button = QPushButton('Start New Game')
        self.start_button.setMaximumWidth(330)
        self.start_button.setMinimumWidth(330)
        self.start_button.setMinimumHeight(60)

        self.start_button.clicked.connect(self.start_new_game)
        self.cancel_button.clicked.connect(self.cancel)

        self.player_grid = QGridLayout()
        self.new_game_grid = QGridLayout()

        #player grid
        self.player_grid.addWidget(self.player1_label, 0, 0)
        self.player_grid.addWidget(self.player2_label, 1, 0)
        self.player_grid.addWidget(self.player1_line_edit, 0, 1)
        self.player_grid.addWidget(self.player2_line_edit, 1, 1)

        #new game grid

        self.new_game_radio_button = RadioButton('Play with',
                                                 ('NPC', 'Friend'))
        self.new_game_grid.addWidget(self.new_game_radio_button, 0, 0)
        self.new_game_grid.addLayout(self.player_grid, 0, 1)
        self.new_game_grid.addWidget(self.cancel_button, 1, 0)
        self.new_game_grid.addWidget(self.start_button, 1, 1)

        self.new_game_widget = QWidget()
        self.new_game_widget.setLayout(self.new_game_grid)

    def create_game_layout(self, player_type):

        self.player1_points = QLabel('0')
        self.player1_points.setAlignment(Qt.AlignTop)
        self.player2_points = QLabel('0')
        self.player2_points.setAlignment(Qt.AlignTop)

        self.player1_name = QLabel(self.player1_line_edit.text())

        if player_type == 1:
            self.player2_name = QLabel(self.player2_line_edit.text() +
                                       ' (NPC)')
        else:
            self.player2_name = QLabel(self.player2_line_edit.text())

        self.points1_label = QLabel('Points:')
        self.points1_label.setAlignment(Qt.AlignBottom)
        self.points2_label = QLabel('Points:')
        self.points2_label.setAlignment(Qt.AlignBottom)

        self.player1_card = QLabel()
        self.player2_card = QLabel()

        self.stop_button_player1 = QPushButton('Stop')
        self.pull_button_player1 = QPushButton('Pull')

        self.stop_button_player2 = QPushButton('Stop')
        self.pull_button_player2 = QPushButton('Pull')

        self.new_deal_button = QPushButton('New Deal')

        self.information_field = QPlainTextEdit('Log here baby')
        self.information_field.setMaximumHeight(243)
        self.information_field.setMaximumWidth(200)

        #Buttons connection

        self.stop_button_player1.clicked.connect(
            lambda: self.stop_card_player1(player_type))
        self.stop_button_player1.setMinimumHeight(30)
        self.pull_button_player1.clicked.connect(
            lambda: self.pull_card_player1(player_type))
        self.pull_button_player1.setMinimumHeight(30)

        self.stop_button_player2.clicked.connect(self.stop_card_player2)
        self.stop_button_player2.setMinimumHeight(30)
        self.pull_button_player2.clicked.connect(self.pull_card_player2)
        self.pull_button_player2.setMinimumHeight(30)

        self.new_deal_button.clicked.connect(self.new_deal)
        self.new_deal_button.setMaximumWidth(90)
        self.new_deal_button.setMinimumHeight(80)

        #Table

        self.table = QTableWidget()
        self.table.setRowCount(11)
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(
            ("{0};{1};").format(self.player1_name.text(),
                                self.player2_name.text()).split(";"))
        self.table.setVerticalHeaderLabels(
            ("1;2;3;4;5;6;7;8;9;10;SUM").split(";"))
        self.table.setMaximumHeight(355)
        self.table.setMaximumWidth(237)

        #Grids definitions

        self.main_game_grid = QGridLayout()
        self.board_grid = QGridLayout()
        self.table_grid = QGridLayout()
        self.below_table_grid = QGridLayout()

        self.player1_grid = QGridLayout()
        self.player2_grid = QGridLayout()

        self.player1_board_grid = QGridLayout()
        self.player2_board_grid = QGridLayout()

        self.player1_buttons_grid = QGridLayout()
        self.player2_buttons_grid = QGridLayout()

        self.player1_points_grid = QGridLayout()
        self.player2_points_grid = QGridLayout()

        #player points grids

        self.player1_points_grid.addWidget(self.points1_label, 0, 0)
        self.player1_points_grid.addWidget(self.player1_points, 1, 0)

        self.player2_points_grid.addWidget(self.points2_label, 0, 0)
        self.player2_points_grid.addWidget(self.player2_points, 1, 0)

        #player buttons grids

        self.player1_buttons_grid.addWidget(self.stop_button_player1, 0, 0)
        self.player1_buttons_grid.addWidget(self.pull_button_player1, 0, 1)

        self.player2_buttons_grid.addWidget(self.stop_button_player2, 0, 0)
        self.player2_buttons_grid.addWidget(self.pull_button_player2, 0, 1)

        #player board grids

        self.player1_board_grid.addWidget(self.player1_name, 0, 0)
        self.player1_board_grid.addWidget(self.player1_card, 0, 1)
        self.player1_board_grid.addLayout(self.player1_points_grid, 0, 3)

        self.player2_board_grid.addWidget(self.player2_name, 0, 0)
        self.player2_board_grid.addWidget(self.player2_card, 0, 1)
        self.player2_board_grid.addLayout(self.player2_points_grid, 0, 3)

        #player grids

        self.player1_grid.addLayout(self.player1_buttons_grid, 0, 0)
        self.player1_grid.addLayout(self.player1_board_grid, 1, 0)

        self.player2_grid.addLayout(self.player2_buttons_grid, 1, 0)
        self.player2_grid.addLayout(self.player2_board_grid, 0, 0)

        #below table grid

        self.below_table_grid.addWidget(self.information_field, 0, 0)
        self.below_table_grid.addWidget(self.new_deal_button, 0, 1)

        #three main grids

        self.board_grid.addLayout(self.player1_grid, 0, 0)
        self.board_grid.addLayout(self.player2_grid, 1, 0)

        self.table_grid.addWidget(self.table, 0, 0)
        self.table_grid.addLayout(self.below_table_grid, 1, 0)

        self.main_game_grid.addLayout(self.board_grid, 0, 0)
        self.main_game_grid.addLayout(self.table_grid, 0, 1)

        # layout

        self.game_widget = QWidget()
        self.game_widget.setLayout(self.main_game_grid)

    def cancel(self):

        self.stacked_layout.setCurrentIndex(0)

    def start_new_game(self):

        player_type = self.new_game_radio_button.selected_button()

        if len(self.player1_line_edit.text()) > 10 or len(
                self.player2_line_edit.text()) > 10:
            QMessageBox.information(
                self, "Too long name",
                "At least one of player's name is too long. It has to be shorter than 10 characters."
            )

        elif self.player1_line_edit.text(
        ) == '' or self.player2_line_edit.text() == '':
            QMessageBox.information(
                self, "Empty name",
                "At least one of player's name is empty. Please provide correct one."
            )

        else:
            if self.stacked_layout.count() > 2:
                self.stacked_layout.removeWidget(self.game_widget)

            self.create_game_layout(player_type)
            self.stacked_layout.addWidget(self.game_widget)
            self.stacked_layout.setCurrentIndex(2)
            self.player1_score = 0
            self.player2_score = 0
            self.match = -1
            self.new_match()

    def new_match(self):
        self.end_game_change_value(False)
        self.new_deal_button.setDisabled(True)
        self.match += 1
        self.deck = Deck()
        self.turn = 0
        self.disable_player2_buttons()
        self.stop_counter = 0
        self.player1_allcards = []
        self.player2_allcards = []
        self.pixmap = QPixmap('karty\empty.png')
        self.pixmap = self.pixmap.scaledToWidth(180)
        self.player1_card.setPixmap(self.pixmap)
        self.player2_card.setPixmap(self.pixmap)
        self.information_field.setPlainText('New deal! {0} starts'.format(
            self.player1_name.text()))

    def pull_card_player1(self, player_type):
        #card pixmap
        self.pixmap1 = QPixmap(
            os.path.join('karty', '{0}.png').format(self.deck.pack[self.turn]))
        self.pixmap1 = self.pixmap1.scaledToWidth(180)
        self.player1_card.setPixmap(self.pixmap1)

        self.player1_points.setText(
            str(
                int(self.player1_points.text()) +
                self.points(self.deck.pack[self.turn][:2])))
        #log info
        self.information_field.setPlainText(
            self.information_field.toPlainText() +
            '\n{0} pulls and gains {1} points'.format(
                self.player1_name.text(),
                str(self.points(self.deck.pack[self.turn][:2]))))

        self.player1_allcards.append(self.deck.pack[self.turn])

        self.turn += 1
        self.stop_counter = 0
        self.disable_player1_buttons()
        if player_type == 1:
            self.game_function()
            if self.end_game == False:
                self.npc_turn()
        elif player_type == 2 and self.end_game == False:
            self.enable_player2_buttons()
            self.game_function()
        else:
            self.disable_player1_buttons()
            self.disable_player2_buttons()

    def stop_card_player1(self, player_type):

        self.stop_counter += 1
        #log info
        self.information_field.setPlainText(
            self.information_field.toPlainText() +
            '\n{0} stops the card'.format(self.player1_name.text()))

        self.disable_player1_buttons()

        if player_type == 1:
            self.game_function()
            if self.end_game == False:
                self.npc_turn()
        elif player_type == 2 and self.end_game == False:
            self.enable_player2_buttons()
            self.game_function()
        else:
            self.disable_player1_buttons()
            self.disable_player2_buttons()

    def pull_card_player2(self):
        #card pixmap
        self.pixmap2 = QPixmap(
            os.path.join('karty', '{0}.png').format(self.deck.pack[self.turn]))
        self.pixmap2 = self.pixmap2.scaledToWidth(180)
        self.player2_card.setPixmap(self.pixmap2)

        self.player2_points.setText(
            str(
                int(self.player2_points.text()) +
                self.points(self.deck.pack[self.turn][:2])))

        #log info
        self.information_field.setPlainText(
            self.information_field.toPlainText() +
            '\n{0} pulls and gains {1} points'.format(
                self.player2_name.text(),
                str(self.points(self.deck.pack[self.turn][:2]))))

        self.player2_allcards.append(self.deck.pack[self.turn])

        self.turn += 1
        self.stop_counter = 0
        self.disable_player2_buttons()

        if self.end_game == False:
            self.enable_player1_buttons()
            self.game_function()
        else:
            self.disable_player1_buttons()

    def stop_card_player2(self):

        self.disable_player2_buttons()
        self.stop_counter += 1
        #log info
        self.information_field.setPlainText(
            self.information_field.toPlainText() +
            '\n{0} stops the card'.format(self.player2_name.text()))

        if self.end_game == False:
            self.enable_player1_buttons()
            self.game_function()

    def game_function(self):  #check whether there is a winning result

        if int(self.player1_points.text()) == 21 and int(
                self.player2_points.text()) == 21:
            self.draw()

        if int(self.player1_points.text()) == 21 and self.stop_counter == 1:
            self.player1_wins()

        if int(self.player2_points.text()) == 21 and self.stop_counter == 1:
            self.player2_wins()

        # =====================Two Aces========================

        if int(self.player1_points.text()
               ) == 22 and 'AA' in self.player1_allcards[
                   0] and 'AA' in self.player1_allcards[1]:
            self.player1_wins()
            self.information_field.setPlainText(
                self.information_field.toPlainText() +
                '\n{0} has two Aces!'.format(self.player1_name.text()))

        if int(self.player2_points.text()
               ) == 22 and 'AA' in self.player2_allcards[
                   0] and 'AA' in self.player2_allcards[1]:
            self.player2_wins()
            self.information_field.setPlainText(
                self.information_field.toPlainText() +
                '\n{0} has two Aces!'.format(self.player1_name.text()))

        # ==================================================================

        #============================Two times Stop button in row============================

        if self.stop_counter == 2:
            if int(self.player1_points.text()) > int(
                    self.player2_points.text()):
                self.player1_wins()

            elif int(self.player1_points.text()) < int(
                    self.player2_points.text()):
                self.player2_wins()

            else:
                self.draw()

        if int(self.player1_points.text()) > 21:  # player 1 exceeds 21 points
            self.information_field.setPlainText(
                self.information_field.toPlainText() + '. 21 is exceeded!')
            self.player2_wins()

        if int(self.player2_points.text()) > 21:  # player 2 exceeds 21 points
            self.disable_player1_buttons()
            self.information_field.setPlainText(
                self.information_field.toPlainText() + '. 21 is exceeded!')
            self.player1_wins()

    def npc_turn(self):  #determines when npc pulls or stops the card
        time.sleep(0.5)
        if int(self.player1_points.text()) == 21 and int(
                self.player2_points.text()) in [18, 19]:
            self.pull_card_player2()
        elif int(self.player1_points.text()) == 21 and int(
                self.player2_points.text()) == 20:
            self.stop_card_player2()
        elif int(self.player1_points.text()) >= 21:
            self.stop_card_player2()
        elif int(self.player1_points.text()) >= int(
                self.player2_points.text()) or int(
                    self.player2_points.text()) <= 11:
            self.pull_card_player2()
        elif int(self.player2_points.text()) == 12:
            if random.randint(0, 100) < 85:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        elif int(self.player2_points.text()) == 13:
            if random.randint(0, 100) < 80:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        elif int(self.player2_points.text()) == 14:
            if random.randint(0, 100) < 70:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        elif int(self.player2_points.text()) == 15:
            if random.randint(0, 100) < 50:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        elif int(self.player2_points.text()) == 16:
            if random.randint(0, 100) < 35:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        elif int(self.player2_points.text()) == 17:
            if random.randint(0, 100) < 20:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        elif int(self.player2_points.text()) >= 18:
            if random.randint(0, 100) < 5:
                self.pull_card_player2()
            else:
                self.stop_card_player2()
        else:
            self.stop_card_player2()

    def player1_wins(self):  #action when player 1 wins
        self.player1_score += 1
        self.sum_rows()
        self.disable_player1_buttons()
        self.disable_player2_buttons()
        self.table.setItem(self.match, 0, QTableWidgetItem('1'))
        self.table.setItem(self.match, 1, QTableWidgetItem('0'))
        self.end_game_change_value(True)
        #log
        self.information_field.setPlainText(
            self.information_field.toPlainText() +
            '\n{0} wins the deal with {1} points!'.format(
                self.player1_name.text(), self.player1_points.text()))
        if self.match < 9:
            self.new_deal_button.setDisabled(False)
        else:
            self.result_message(self.player1_score, self.player2_score)

    def player2_wins(self):  #action when player 2 wins
        self.player2_score += 1
        self.sum_rows()
        self.disable_player1_buttons()
        self.disable_player2_buttons()
        self.table.setItem(self.match, 0, QTableWidgetItem('0'))
        self.table.setItem(self.match, 1, QTableWidgetItem('1'))
        self.end_game_change_value(True)
        #log
        self.information_field.setPlainText(
            self.information_field.toPlainText() +
            '\n{0} wins the deal with {1} points!'.format(
                self.player2_name.text(), self.player2_points.text()))
        if self.match < 9:
            self.new_deal_button.setDisabled(False)
        else:
            self.result_message(self.player1_score, self.player2_score)

    def draw(self):  #action when there is a draw
        self.disable_player1_buttons()
        self.disable_player2_buttons()
        self.table.setItem(self.match, 0, QTableWidgetItem('0'))
        self.table.setItem(self.match, 1, QTableWidgetItem('0'))
        self.end_game_change_value(True)
        #log
        self.information_field.setPlainText(
            self.information_field.toPlainText() + '\nDraw!')
        if self.match < 9:
            self.new_deal_button.setDisabled(False)
        else:
            self.result_message(self.player1_score, self.player2_score)

    def result_message(self, player1_score, player2_score):
        if player1_score > player2_score:
            QMessageBox.information(
                self, "{0} won!".format(self.player1_name.text()),
                "The score is {0}:{1}. Good luck next time {2}!".format(
                    player1_score, player2_score, self.player2_name.text()))
        elif player1_score < player2_score:
            QMessageBox.information(
                self, "{0} won!".format(self.player2_name.text()),
                "The score is {0}:{1}. Good luck next time {2}!".format(
                    player2_score, player1_score, self.player1_name.text()))
        else:
            QMessageBox.information(
                self, "Draw!",
                "Both players scored {0} points".format(player1_score))

    def disable_player1_buttons(self):
        self.pull_button_player1.setDisabled(True)
        self.stop_button_player1.setDisabled(True)

    def enable_player1_buttons(self):
        self.pull_button_player1.setDisabled(False)
        self.stop_button_player1.setDisabled(False)

    def disable_player2_buttons(self):
        self.pull_button_player2.setDisabled(True)
        self.stop_button_player2.setDisabled(True)

    def enable_player2_buttons(self):
        self.pull_button_player2.setDisabled(False)
        self.stop_button_player2.setDisabled(False)

    def points(self,
               value):  #method to match card's name with its points value
        score = {
            '11': 1,
            '22': 2,
            '33': 3,
            '44': 4,
            '55': 5,
            '66': 6,
            '77': 7,
            '88': 8,
            '99': 9,
            '10': 10,
            'WW': 2,
            'DD': 3,
            'KK': 4,
            'AA': 11
        }
        return score[value]

    def sum_rows(self):  #sums rows from the table
        self.table.setItem(10, 0, QTableWidgetItem(str(self.player1_score)))
        self.table.setItem(10, 1, QTableWidgetItem(str(self.player2_score)))

    def new_deal(self):  #start new deal

        self.enable_player1_buttons()
        self.player1_card.setText('')
        self.player2_card.setText('')
        self.player1_points.setText('0')
        self.player2_points.setText('0')
        self.new_match()
예제 #7
0
class MainUI(QWidget):
    def __init__(self, parent=None):
        # 创建更新历史数据的线程
        self.hist_data_thread = UpdateHistData()
        self.hist_data_thread.update_hist_data_signal.connect(
            self.update_hist_data)
        self.hist_data_thread.start()

        # 创建实时价格更新线程
        self.live_price_thread = GetLivePrice()
        self.live_price_thread.update_data.connect(self.update_price)
        # 在历史数据更新完成后再启动

        super(MainUI, self).__init__(parent)
        # 设置窗口名称
        self.setWindowTitle("APIA Quant")
        # initial size
        self.resize(1200, 600)
        # 完成一些复杂的主要的布局
        self.init_ui()
        # 窗口居中显示
        self.center()
        # 设置窗口透明度
        self.setWindowOpacity(0.98)
        self.main_layout.setSpacing(0)
        #设置窗口主题
        self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

    def init_ui(self):
        # 创建主部件的网格布局
        self.main_layout = QHBoxLayout(self)

        # 左侧布局开始
        # 创建左侧frame
        self.left_frame = QFrame(self)
        self.left_frame.setFrameShape(QFrame.StyledPanel)

        #在这个frame中使用垂直布局
        self.left_verticalLayout = QVBoxLayout(self.left_frame)

        # function buttons
        self.login_btn = QPushButton(self.left_frame)
        self.login_btn.setText("Login")
        self.login_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.login_btn.clicked.connect(self.login)
        self.login_btn.setEnabled(False)
        self.login_btn.setShortcut(Qt.Key_Return)

        self.home_btn = QPushButton(self.left_frame)
        self.home_btn.setText('Home')
        self.home_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.home_btn.clicked.connect(lambda: self.display_right(index=1))
        self.home_btn.setEnabled(False)

        self.manage_etf_btn = QPushButton(self.left_frame)
        self.manage_etf_btn.setText('Manage ETFs')
        self.manage_etf_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.manage_etf_btn.clicked.connect(
            lambda: self.display_right(index=2))
        self.manage_etf_btn.setEnabled(False)

        self.get_hist_btn = QPushButton(self.left_frame)
        self.get_hist_btn.setText('Update Historical Data')
        self.get_hist_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.get_hist_btn.clicked.connect(lambda: self.display_right(index=3))
        self.get_hist_btn.setEnabled(False)

        self.candle_btn = QPushButton(self.left_frame)
        self.candle_btn.setText('Show Candles')
        self.candle_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.candle_btn.clicked.connect(lambda: self.display_right(index=4))
        self.candle_btn.setEnabled(False)

        self.trading_signal_btn = QPushButton(self.left_frame)
        self.trading_signal_btn.setText('Trading Signals')
        self.trading_signal_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.trading_signal_btn.clicked.connect(
            lambda: self.display_right(index=5))
        self.trading_signal_btn.setEnabled(False)

        self.back_test_btn = QPushButton(self.left_frame)
        self.back_test_btn.setText('Back Test')
        self.back_test_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.back_test_btn.clicked.connect(lambda: self.display_right(index=6))
        self.back_test_btn.setEnabled(False)

        self.core_strategy_btn = QPushButton(self.left_frame)
        self.core_strategy_btn.setText('Core Strategy Table')
        self.core_strategy_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.core_strategy_btn.clicked.connect(
            lambda: self.display_right(index=7))
        self.core_strategy_btn.setEnabled(False)

        self.position_calculator_btn = QPushButton(self.left_frame)
        self.position_calculator_btn.setText('Position Calculator')
        self.position_calculator_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.position_calculator_btn.clicked.connect(
            lambda: self.display_right(index=8))
        self.position_calculator_btn.setEnabled(False)

        self.quit_btn = QPushButton(self.left_frame)
        self.quit_btn.setText('Quit')
        self.quit_btn.setFont(QFont('Arial', 12, QFont.Bold))
        self.quit_btn.clicked.connect(QCoreApplication.instance().quit)
        self.quit_btn.setEnabled(True)

        # 将上述功能按键添加到当前的垂直布局
        self.left_verticalLayout.addWidget(self.login_btn)
        self.left_verticalLayout.addWidget(self.home_btn)
        self.left_verticalLayout.addWidget(self.manage_etf_btn)
        self.left_verticalLayout.addWidget(self.get_hist_btn)
        self.left_verticalLayout.addWidget(self.candle_btn)
        self.left_verticalLayout.addWidget(self.trading_signal_btn)
        self.left_verticalLayout.addWidget(self.back_test_btn)
        self.left_verticalLayout.addWidget(self.core_strategy_btn)
        self.left_verticalLayout.addWidget(self.position_calculator_btn)
        self.left_verticalLayout.addWidget(self.quit_btn)

        # 右侧布局开始
        # 创建右侧frame
        self.right_frame = QFrame(self)
        self.right_frame.setFrameShape(QFrame.StyledPanel)

        #这里之后会另外进行UI创建的
        self.login_pg = Login()
        self.get_hist_pg = GetHistData()
        # 创建别的页面之前先更新数据
        self.get_hist_pg.get_hist_data()
        self.home_pg = Home()
        self.candle_pg = Candle()
        self.manage_etf_pg = ETFManagement()
        self.trading_signal_pg = TradingSignal()
        self.back_test_pg = BackTest()
        self.core_strategy_pg = CoreStrategy()
        self.position_calculator_pg = PositionCalculator()

        # 在右侧frame创建stack
        self.stack = QStackedLayout(self.right_frame)
        #将上面的页面加入到stack
        self.stack.addWidget(self.login_pg)
        self.stack.addWidget(self.home_pg)
        self.stack.addWidget(self.manage_etf_pg)
        self.stack.addWidget(self.get_hist_pg)
        self.stack.addWidget(self.candle_pg)
        self.stack.addWidget(self.trading_signal_pg)
        self.stack.addWidget(self.back_test_pg)
        self.stack.addWidget(self.core_strategy_pg)
        self.stack.addWidget(self.position_calculator_pg)

        # 用于更新etf列表的信号连接
        self.manage_etf_pg.re_init_signal.connect(self.re_init)

        # 创建splitter
        self.splitter = QSplitter(Qt.Horizontal)
        self.splitter.addWidget(self.left_frame)
        self.splitter.addWidget(self.right_frame)
        self.splitter.setSizes((200, 800))

        # 将splitter加入到main_layout
        self.main_layout.addWidget(self.splitter)

        self.setLayout(self.main_layout)

        # 窗口最大化
        # self.showMaximized()

    def center(self):
        # 获取桌面尺寸
        screen = QDesktopWidget().screenGeometry()
        # 获取窗口本身的尺寸和位置
        size = self.geometry()
        # 对窗口进行平移
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def display_right(self, index):
        # 在右边frame显示对应的页面
        self.stack.setCurrentIndex(index)

        if index != 2:
            self.get_hist_pg.pgb.setVisible(False)
            self.get_hist_pg.pgb.setValue(0)

    def login(self):
        if LoginForm().exec_() == QDialog.Accepted:
            # 将login按钮设置为不可用
            self.login_btn.setText("Welcome to APIA Quant System")
            self.login_btn.setEnabled(False)
            # 将剩下的按钮全部设为可用,代表登录成功
            self.home_btn.setEnabled(True)
            self.manage_etf_btn.setEnabled(True)
            self.get_hist_btn.setEnabled(True)
            self.candle_btn.setEnabled(True)
            self.trading_signal_btn.setEnabled(True)
            self.back_test_btn.setEnabled(True)
            self.core_strategy_btn.setEnabled(True)
            self.position_calculator_btn.setEnabled(True)
            # 直接跳转至home页面
            self.stack.setCurrentIndex(1)

    def re_init(self):
        # 先终止线程,防止数据对不上
        self.live_price_thread.terminate()
        self.live_price_thread.etfs = np.load('./Data/etfs.npy').tolist()

        # 重新启动线程
        self.live_price_thread.start()

        self.stack.removeWidget(self.home_pg)
        del self.home_pg
        self.stack.removeWidget(self.manage_etf_pg)
        del self.manage_etf_pg
        self.stack.removeWidget(self.get_hist_pg)
        del self.get_hist_pg
        self.stack.removeWidget(self.candle_pg)
        del self.candle_pg
        self.stack.removeWidget(self.trading_signal_pg)
        del self.trading_signal_pg
        self.stack.removeWidget(self.back_test_pg)
        del self.back_test_pg
        self.stack.removeWidget(self.core_strategy_pg)
        del self.core_strategy_pg
        self.stack.removeWidget(self.position_calculator_pg)
        del self.position_calculator_pg

        # 创建别的页面之前先更新数据
        # self.get_hist_pg.get_hist_data()
        self.home_pg = Home()
        self.manage_etf_pg = ETFManagement()
        self.get_hist_pg = GetHistData()
        self.candle_pg = Candle()
        self.trading_signal_pg = TradingSignal()
        self.back_test_pg = BackTest()
        self.core_strategy_pg = CoreStrategy()
        self.position_calculator_pg = PositionCalculator()

        # 将上面的页面加入到stack
        self.stack.addWidget(self.login_pg)
        self.stack.addWidget(self.home_pg)
        self.stack.addWidget(self.manage_etf_pg)
        self.stack.addWidget(self.get_hist_pg)
        self.stack.addWidget(self.candle_pg)
        self.stack.addWidget(self.trading_signal_pg)
        self.stack.addWidget(self.back_test_pg)
        self.stack.addWidget(self.core_strategy_pg)
        self.stack.addWidget(self.position_calculator_pg)

        self.manage_etf_pg.re_init_signal.connect(window.re_init)

        self.stack.setCurrentIndex(1)

    def update_hist_data(self, sig):
        print(sig)
        self.hist_data_thread.terminate()
        self.live_price_thread.start()
        self.login_btn.setEnabled(True)

    def update_price(self, data):
        self.home_pg.show_live_price(data)
        self.candle_pg.update_price(data)
        self.position_calculator_pg.update_position_table(data)
예제 #8
0
class MainWidget(QMainWindow):
    def __init__(self, user: User):
        super().__init__()

        self.mainWidget = QWidget()

        self.setMinimumSize(500, 500)
        self.user = user
        self.setStyleSheet(open('main.css').read())
        self.dashboard_button = QPushButton("Dashboard")
        self.dashboard_button.clicked.connect(
            lambda success: self.LoadDashboardLayout(success))

        self.home_button = QPushButton("Home")
        self.home_button.clicked.connect(lambda: self.LoadHomeLayout())

        self.profile_button = QPushButton("Profile")
        self.profile_button.clicked.connect(
            lambda success: self.LoadProfileLayout(success))

        self.grid = QGridLayout()

        self.upperLayout = QHBoxLayout()

        self.upperLayout.addWidget(self.dashboard_button)
        self.upperLayout.addWidget(self.home_button)
        self.upperLayout.addWidget(self.profile_button)

        self.upperExternal = QFrame()
        self.upperExternal.setStyleSheet(
            ".QFrame{background-color: white; border: 2px solid black; border-radius: 10px;}"
        )

        self.upperExternal.setLayout(self.upperLayout)

        #print(self.user.courses)

        self.home_layout = None
        self.dashboard_layout = None
        self.profile_layout = None
        self.course_layout = None
        self.new_course_layout = None
        self.movie_layout = None
        self.addmovie_layout = None
        self.CourseMovies_layout = None
        self.changepass_layout = None

        self.stack = QStackedLayout()

        self.grid.addWidget(self.upperExternal, 1, 1)
        self.grid.addLayout(self.stack, 2, 1)

        self.mainWidget.setLayout(self.grid)
        self.setCentralWidget(self.mainWidget)
        self.LoadHomeLayout()
        #        self.Recommender=RecommendationEngine()
        #        self.Recommender.LoadRecommendations(self.user)
        exit = QAction("&Exit", self)
        exit.triggered.connect(self.closeEvent)

        self.show()

    def closeEvent(self, event):

        self.silence()
        close = QMessageBox()
        close.setText("You sure?")
        close.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel)
        close = close.exec()

        if close == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    #HomeLayoout----------------------------------------------------------------------------------
    #Sets homelayout as default layout
    def LoadHomeLayout(self):
        self.setWindowTitle("Home")
        if self.home_layout == None:
            self.home_layout = HomeLayout(self.user)
            self.home_layout._WatchMovie_.connect(
                lambda url, M_ID: self.LoadMovieLayout(url, M_ID))
            self.stack.addWidget(self.home_layout)
        self.stack.setCurrentWidget(self.home_layout)

    #sets movielayout as default layout
    def LoadMovieLayout(self, url, movieID):
        self.setWindowTitle("Movie")
        if self.movie_layout != None:
            self.stack.removeWidget(self.movie_layout)
            del self.movie_layout

        self.movie_layout = MovieLayout(url, movieID, self.user)
        self.stack.addWidget(self.movie_layout)
        self.stack.setCurrentWidget(self.movie_layout)

    #DashBoardLayout----------------------------------------------------------------------------------
    #sets dashboard layout as default layout
    def LoadDashboardLayout(self, success):
        if (success == 1):
            self.dashboard_layout.message.setText(
                "Successfully Submitted Course")
            self.course_layout = None
        elif (success == 2):
            self.dashboard_layout.message.setText(
                "Successfully Submitted Movie")
            self.addmovie_layout = None
        elif (success == 3):
            pass

        self.setWindowTitle("Dashboard")
        if self.dashboard_layout == None:
            self.dashboard_layout = DashboardLayout(self.user)
            self.dashboard_layout.new_course_request.connect(
                self.LoadCourseLayout)

            self.dashboard_layout.openCourse_request.connect(
                lambda x: self.LoadCourseMovies(x))
            self.stack.addWidget(self.dashboard_layout)

        self.stack.setCurrentWidget(self.dashboard_layout)
        self.silence()

    #sets course layout as default layout (upload courses)
    def LoadCourseLayout(self):
        self.setWindowTitle("Add Course")
        if self.course_layout == None:
            self.course_layout = CourseInputDialog(self.user)
            self.course_layout.loaddashlayout.connect(
                lambda success: self.LoadDashboardLayout(success))
            self.stack.addWidget(self.course_layout)

        self.stack.setCurrentWidget(self.course_layout)

    #sets dash movie layout as default layout (upload movie)
    def LoadDashMovieLayout(self, courseID):
        self.setWindowTitle("Add Movie")
        if self.addmovie_layout != None:
            self.stack.removeWidget(self.addmovie_layout)
            del self.addmovie_layout

        self.addmovie_layout = MovieInputDialog(self.user, courseID)
        self.addmovie_layout.goback_request.connect(
            lambda C_ID: self.LoadCourseMovies(C_ID))
        self.stack.addWidget(self.addmovie_layout)
        self.stack.setCurrentWidget(self.addmovie_layout)

    def LoadCourseMovies(self, courseID):
        self.setWindowTitle("Course Movies")
        if self.CourseMovies_layout != None:
            self.stack.removeWidget(self.CourseMovies_layout)
            del self.CourseMovies_layout
        self.CourseMovies_layout = CourseMovieLayout(self.user, courseID)
        self.CourseMovies_layout.new_movie_request.connect(
            lambda C_ID: self.LoadDashMovieLayout(C_ID))
        self.CourseMovies_layout.goback_request.connect(
            lambda success: self.LoadDashboardLayout(success))
        self.CourseMovies_layout._WatchMovie_.connect(
            lambda url, M_ID: self.LoadMovieLayout(url, M_ID))
        self.stack.addWidget(self.CourseMovies_layout)

        self.stack.setCurrentWidget(self.CourseMovies_layout)

    #ProfileLayout---------------------------------------------------------------------------------------------
    #sets profile layout as default layout
    def LoadProfileLayout(self, success):
        self.setWindowTitle("Profile")
        if self.profile_layout != None:
            self.stack.removeWidget(self.profile_layout)
            del self.profile_layout

        self.profile_layout = ProfileLayout(self.user)
        self.profile_layout.changePass_request.connect(
            lambda: self.LoadChangePassLayout())

        if (success == 1):
            self.profile_layout.errorMessage.setText(
                "Password Changed Successfully")

        self.stack.addWidget(self.profile_layout)
        self.stack.setCurrentWidget(self.profile_layout)
        self.silence()

    def LoadChangePassLayout(self):
        self.setWindowTitle("Change Password")
        if self.changepass_layout == None:
            self.changepass_layout = ChangePasswordLayout(self.user)
            self.changepass_layout.goback_request.connect(
                lambda success: self.LoadProfileLayout(success))
            self.stack.addWidget(self.changepass_layout)

        self.stack.setCurrentWidget(self.changepass_layout)

    #-----------------------------------------------------------------------------------------------------------
    #stops movie from running in background (movie cleanup)
    def silence(self):
        if (self.movie_layout != None):
            self.movie_layout.Stop()
예제 #9
0
class SolveEquationWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.start = True
        self.resize(300, 200)
        self.layout = QStackedLayout()
        self.start_widget = QWidget()
        self.start_layout = QVBoxLayout()

        self._21equation = QPushButton('2 variables linear equation')
        self._21equation.clicked.connect(
            partial(self.create_solving_widget, 2, 3, func='line'))
        self._21equation.setMinimumHeight(80)
        change_font(self._21equation)

        self._31equation = QPushButton('3 variables linear equation')
        self._31equation.clicked.connect(
            partial(self.create_solving_widget, 3, 4, func='line'))
        self._31equation.setMinimumHeight(80)
        change_font(self._31equation)

        self._12equation = QPushButton('1 variables quadratic equation')
        self._12equation.clicked.connect(
            partial(self.create_solving_widget, 1, 3, func='quad'))
        self._12equation.setMinimumHeight(80)
        change_font(self._12equation)

        self.start_layout.addWidget(self._21equation)
        self.start_layout.addWidget(self._31equation)
        self.start_layout.addWidget(self._12equation)

        self.start_widget.setLayout(self.start_layout)
        self.layout.addWidget(self.start_widget)
        self.setLayout(self.layout)

    def create_solving_widget(self, row, column, func):
        self.func = func
        self.start = False
        self.solving_widget = QWidget()

        self.solving_layout = QVBoxLayout()

        return_button = Button('Return')
        return_button.clicked.connect(self.return_to_start_widget)
        self.solving_layout.addWidget(return_button)

        self.entries = []
        for i in range(row):
            self.entries.append(QHBoxLayout())
            for j in range(column):
                self.entries[i].addWidget(QLineEdit())
            self.solving_layout.addLayout(self.entries[i])

        result_hbox = QHBoxLayout()
        result_label = QLabel('Result')
        result_hbox.addWidget(result_label)
        self.result_num = []
        if func == 'quad':
            row = 2
        for i in range(row):
            self.result_num.append(QLabel())
            result_hbox.addWidget(self.result_num[i])
        self.solving_layout.addLayout(result_hbox)

        ok_button = Button('OK')
        ok_button.clicked.connect(self.solve)
        self.solving_layout.addWidget(ok_button)

        self.solving_widget.setLayout(self.solving_layout)

        self.layout.addWidget(self.solving_widget)
        self.layout.setCurrentIndex(1)

    def return_to_start_widget(self):
        self.start = True
        clear_layout(self.solving_layout)
        del self.solving_widget
        self.layout.removeWidget(self.layout.currentWidget())
        self.layout.setCurrentIndex(0)

    def solve(self):
        para = []
        for hbox in self.entries:
            for i in range(hbox.count()):
                para.append(evaluator.parse(hbox.itemAt(i).widget().text()))
        if self.func == 'line':
            result = linear_solver(*para)
        elif self.func == 'quad':
            result = quad_solver(*para)
        if result:
            for i in range(len(self.result_num)):
                self.result_num[i].setText(str(round(result[i], 11)))
        else:
            self.result_num[0].setText("No Answer")

    def keyPressEvent(self, event):
        if not self.start:
            if event.key() == Qt.Key_Enter:
                self.solve()

    @staticmethod
    def run(parent=None, position=None):
        w = SolveEquationWidget(parent)
        if position is not None:
            w.move(position)
        w.show()