Esempio n. 1
0
class ComboEditor(QWidget):

    def __init__(self, original=False):
        super(ComboEditor, self).__init__()
        self.__original = original
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)

        self.bar = ActionBar()
        self.connect(self.bar, SIGNAL("changeCurrent(PyQt_PyObject)"),
            self.set_current)
        vbox.addWidget(self.bar)

        self.stacked = QStackedLayout()
        vbox.addLayout(self.stacked)

    def currentWidget(self):
        return self.stacked.currentWidget()

    def add_editor(self, neditable):
        """Add Editor Widget to the UI area."""
        if neditable.editor:
            self.stacked.addWidget(neditable.editor)
            self.bar.add_item(neditable.display_name, neditable)

            # Editor Signals
            self.connect(neditable.editor, SIGNAL("cursorPositionChanged()"),
                self._update_cursor_position)

            # Connect file system signals only in the original
            if self.__original:
                pass

    def set_current(self, neditable):
        self.stacked.setCurrentWidget(neditable.editor)
        self._update_cursor_position(ignore_sender=True)
        neditable.editor.setFocus()

    def widget(self, index):
        return self.stacked.widget(index)

    def count(self):
        """Return the number of editors opened."""
        return self.stacked.count()

    def _update_cursor_position(self, ignore_sender=False):
        obj = self.sender()
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if ignore_sender or editor == obj:
            line = editor.textCursor().blockNumber() + 1
            col = editor.textCursor().columnNumber()
            self.bar.update_line_col(line, col)
Esempio n. 2
0
class CSVImportDialog(QDialog):
    def __init__(self, parent=None, **kwargs):
        super(CSVImportDialog, self).__init__(parent, **kwargs)
        self.setLayout(QVBoxLayout())

        self._options = None
        self._path = None
        self.__update_pending = False

        self._optionswidget = CSVOptionsWidget()
        self._optionswidget.format_changed.connect(self._invalidate_preview)

        self._stack = QStackedLayout()
        self._stack.setContentsMargins(0, 0, 0, 0)
        prev_box = QGroupBox("Preview")
        prev_box.setLayout(self._stack)
        self._preview = QTableView(tabKeyNavigation=False)
        self._preview_error = QLabel()
        self._stack.addWidget(self._preview)
        self._stack.addWidget(self._preview_error)

        buttons = QDialogButtonBox(
            orientation=Qt.Horizontal,
            standardButtons=(QDialogButtonBox.Ok | QDialogButtonBox.Cancel |
                             QDialogButtonBox.Reset)
        )
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)

        def on_clicked(button):
            if buttons.buttonRole(button) == QDialogButtonBox.ResetRole:
                self.reset()

        buttons.clicked.connect(on_clicked)

        self.layout().addWidget(self._optionswidget)
        self.layout().addWidget(prev_box)
        self.layout().addWidget(buttons)

    def set_options(self, options):
        self._options = options
        self._optionswidget.set_dialect(options.dialect)
        self._optionswidget.set_header_format(options.header_format)
        self._optionswidget.set_missing_values(options.missing_values or "")
        self._invalidate_preview()

    def options(self):
        missing_values = self._optionswidget.missing_values()
        return CSV(self._optionswidget.dialect(),
                   header_format=self._optionswidget.header_format(),
                   missing_values=missing_values)

    def set_path(self, path):
        """Set the preview path."""
        if self._path != path:
            self._path = path
            self._invalidate_preview()

    def path(self):
        """Return the preview path"""
        return self._path

    def reset(self):
        """Reset the options to their default values."""
        self.set_options(self._options)

    def _invalidate_preview(self):
        if not self.__update_pending:
            self.__update_pending = True
            QApplication.postEvent(self, QEvent(QEvent.User))

    def customEvent(self, event):
        if self.__update_pending:
            self.__update_pending = False
            self._update_preview()

    def _update_preview(self):
        if not self._path:
            return

        head = itertools.islice(open(self._path, "rU"), 20)
        head = StringIO("".join(head))
        try:
            data = load_csv(head, **self.options()._asdict())
        except csv.Error as err:
            self._preview_error.setText(
                "Cannot load data preview:\n {!s}".format(err)
            )
            self._stack.setCurrentWidget(self._preview_error)
        except (Orange.data.io.CSVFormatError,
                Orange.data.io.VariableDefinitionError) as err:
            self._preview_error.setText(
                "Data formating error:\n {!s}".format(err)
            )
            self._stack.setCurrentWidget(self._preview_error)
        except Exception as err:
            self._preview_error.setText(
                "Cannot load data preview:\n {!s}".format(err)
            )
            self._stack.setCurrentWidget(self._preview_error)
            raise
        else:
            model = TableModel(data, None, self)
            self._preview.setModel(model)
            self._preview.resizeColumnsToContents()
            self._stack.setCurrentWidget(self._preview)
Esempio n. 3
0
class CSVImportDialog(QDialog):
    def __init__(self, parent=None, **kwargs):
        super(CSVImportDialog, self).__init__(parent, **kwargs)
        self.setLayout(QVBoxLayout())

        self._options = None
        self._path = None
        self.__update_pending = False

        self._optionswidget = CSVOptionsWidget()
        self._optionswidget.format_changed.connect(self._invalidate_preview)

        self._stack = QStackedLayout()
        self._stack.setContentsMargins(0, 0, 0, 0)
        prev_box = QGroupBox("Preview")
        prev_box.setLayout(self._stack)
        self._preview = QTableView(tabKeyNavigation=False)
        self._preview_error = QLabel()
        self._stack.addWidget(self._preview)
        self._stack.addWidget(self._preview_error)

        buttons = QDialogButtonBox(
            orientation=Qt.Horizontal,
            standardButtons=(QDialogButtonBox.Ok | QDialogButtonBox.Cancel
                             | QDialogButtonBox.Reset))
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)

        def on_clicked(button):
            if buttons.buttonRole(button) == QDialogButtonBox.ResetRole:
                self.reset()

        buttons.clicked.connect(on_clicked)

        self.layout().addWidget(self._optionswidget)
        self.layout().addWidget(prev_box)
        self.layout().addWidget(buttons)

    def set_options(self, options):
        self._options = options
        self._optionswidget.set_dialect(options.dialect)
        self._optionswidget.set_header_format(options.header_format)
        self._optionswidget.set_missing_values(options.missing_values or "")
        self._invalidate_preview()

    def options(self):
        missing_values = self._optionswidget.missing_values()
        return CSV(self._optionswidget.dialect(),
                   header_format=self._optionswidget.header_format(),
                   missing_values=missing_values)

    def set_path(self, path):
        """Set the preview path."""
        if self._path != path:
            self._path = path
            self._invalidate_preview()

    def path(self):
        """Return the preview path"""
        return self._path

    def reset(self):
        """Reset the options to their default values."""
        self.set_options(self._options)

    def _invalidate_preview(self):
        if not self.__update_pending:
            self.__update_pending = True
            QApplication.postEvent(self, QEvent(QEvent.User))

    def customEvent(self, event):
        if self.__update_pending:
            self.__update_pending = False
            self._update_preview()

    def _update_preview(self):
        if not self._path:
            return

        head = itertools.islice(open(self._path, "rU"), 20)
        head = StringIO("".join(head))
        try:
            data = load_csv(head, **self.options()._asdict())
        except csv.Error as err:
            self._preview_error.setText(
                "Cannot load data preview:\n {!s}".format(err))
            self._stack.setCurrentWidget(self._preview_error)
        except (Orange.data.io.CSVFormatError,
                Orange.data.io.VariableDefinitionError) as err:
            self._preview_error.setText(
                "Data formating error:\n {!s}".format(err))
            self._stack.setCurrentWidget(self._preview_error)
        except Exception as err:
            self._preview_error.setText(
                "Cannot load data preview:\n {!s}".format(err))
            self._stack.setCurrentWidget(self._preview_error)
            raise
        else:
            model = TableModel(data, None, self)
            self._preview.setModel(model)
            self._preview.resizeColumnsToContents()
            self._stack.setCurrentWidget(self._preview)
Esempio n. 4
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()
    """

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

    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)

        #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.connect(self, SIGNAL("locateFunction(QString, QString, bool)"),
                     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.connect(self.selector, SIGNAL("changeCurrent(int)"),
                     self._change_current_stack)
        self.connect(self.selector, SIGNAL("removeWidget(int)"),
                     self._remove_item_from_stack)
        self.connect(self.selector, SIGNAL("ready()"), self._selector_ready)
        self.connect(self.selector, SIGNAL("animationCompleted()"),
                     self._selector_animation_completed)
        self.connect(self, SIGNAL("closeDialog(PyQt_PyObject)"),
                     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.connect(self.combo_area, SIGNAL("allFilesClosed()"),
                     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):
        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
                closable = True
                if widget == self.splitter:
                    closable = False
                pixmap = QPixmap.grabWidget(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):
        self.stack.setCurrentWidget(self.selector)
        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.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 == 'html':
                webbrowser.open(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()

    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):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.jump_to_line(line)

    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.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.emit(SIGNAL("currentEditorChanged(QString)"), 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 editable.editor
        else:
            editable.ignore_checkers = ignore_checkers

        editorWidget = self.create_editor_from_editable(editable)

        #add the tab
        if self.current_widget != self.combo_area:
            self.combo_area.add_editor(editable)
        self.current_widget.add_editor(editable)

        #emit a signal about the file open
        self.emit(SIGNAL("fileOpened(QString)"), fileName)

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

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

        #Connect signals
        self.connect(editable, SIGNAL("fileSaved(PyQt_PyObject)"),
                     self._editor_tab_was_saved)
        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 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.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.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.Editor):
            return widget
        return None

    def reload_file(self, editorWidget=None):
        if editorWidget is None:
            editorWidget = self.get_current_editor()
            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_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 = list(
                QFileDialog.getOpenFileNames(self, self.tr("Open File"),
                                             directory, extensions))
        else:
            logger.debug("has filename")
            fileNames = [filename]
        if not fileNames:
            return

        for filename in fileNames:
            if file_manager.get_file_extension(filename) in ('jpg', 'png'):
                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.set_cursor_position(line, col)
            self.emit(SIGNAL("currentEditorChanged(QString)"), 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.emit(SIGNAL("beforeFileSaved(QString)"),
                      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.emit(SIGNAL("fileSaved(QString)"),
                      (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.emit(SIGNAL("fileSaved(QString)"),
                      (self.tr("File Saved: %s") % fileName))
            self.emit(SIGNAL("currentEditorChanged(QString)"), 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()")))
            self.connect(startPage, SIGNAL("newFile()"), 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):
        """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."""
        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/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)
Esempio n. 5
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()
    """

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

    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)

        #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.connect(self, SIGNAL("locateFunction(QString, QString, bool)"),
                     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.connect(self.selector, SIGNAL("changeCurrent(int)"),
                     self._change_current_stack)
        self.connect(self.selector, SIGNAL("removeWidget(int)"),
                     self._remove_item_from_stack)
        self.connect(self.selector, SIGNAL("ready()"),
                     self._selector_ready)
        self.connect(self.selector, SIGNAL("animationCompleted()"),
                     self._selector_animation_completed)
        self.connect(self, SIGNAL("closeDialog(PyQt_PyObject)"),
                     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.connect(self.combo_area, SIGNAL("allFilesClosed()"),
                     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):
        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
                closable = True
                if widget == self.splitter:
                    closable = False
                pixmap = QPixmap.grabWidget(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):
        self.stack.setCurrentWidget(self.selector)
        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.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 == 'html':
                webbrowser.open(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()

    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):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.jump_to_line(line)

    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.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.emit(SIGNAL("currentEditorChanged(QString)"), 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 editable.editor
        else:
            editable.ignore_checkers = ignore_checkers

        editorWidget = self.create_editor_from_editable(editable)

        #add the tab
        if self.current_widget != self.combo_area:
            self.combo_area.add_editor(editable)
        self.current_widget.add_editor(editable)

        #emit a signal about the file open
        self.emit(SIGNAL("fileOpened(QString)"), fileName)

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

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

        #Connect signals
        self.connect(editable, SIGNAL("fileSaved(PyQt_PyObject)"),
                     self._editor_tab_was_saved)
        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 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.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.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.Editor):
            return widget
        return None

    def reload_file(self, editorWidget=None):
        if editorWidget is None:
            editorWidget = self.get_current_editor()
            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_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 = list(QFileDialog.getOpenFileNames(self,
                             self.tr("Open File"), directory, extensions))
        else:
            logger.debug("has filename")
            fileNames = [filename]
        if not fileNames:
            return

        for filename in fileNames:
            if file_manager.get_file_extension(filename) in ('jpg', 'png'):
                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.set_cursor_position(line, col)
            self.emit(SIGNAL("currentEditorChanged(QString)"), 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.emit(SIGNAL("beforeFileSaved(QString)"),
                      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.emit(SIGNAL("fileSaved(QString)"),
                      (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.emit(SIGNAL("fileSaved(QString)"),
                            (self.tr("File Saved: %s") % fileName))
            self.emit(SIGNAL("currentEditorChanged(QString)"), 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()")))
            self.connect(startPage, SIGNAL("newFile()"), 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):
        """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."""
        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/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)
Esempio n. 6
0
class MusicPreviewWidget(QWidget):
    def __init__(self, parent=None):
        super(MusicPreviewWidget, self).__init__(parent)
        self._lastbuildtime = 10.0
        self._running = None
        self._current = None

        self._chooserLabel = QLabel()
        self._chooser = QComboBox(self, activated=self.selectDocument)
        self._log = log.Log()
        self._view = popplerview.View()
        self._progress = widgets.progressbar.TimedProgressBar()

        self._stack = QStackedLayout()
        self._top = QWidget()

        layout = QVBoxLayout()
        self.setLayout(layout)

        layout.addWidget(self._top)
        layout.addLayout(self._stack)
        layout.addWidget(self._progress)

        top = QHBoxLayout()
        top.setContentsMargins(0, 0, 0, 0)
        top.setSpacing(2)
        self._top.setLayout(top)
        top.addWidget(self._chooserLabel)
        top.addWidget(self._chooser)
        top.addStretch(1)

        self._stack.addWidget(self._log)
        self._stack.addWidget(self._view)

        self._top.hide()
        app.aboutToQuit.connect(self.cleanup)
        app.translateUI(self)

    def translateUI(self):
        self._chooserLabel.setText(_("Document:"))

    def preview(self, text, title=None):
        """Runs LilyPond on the given text and shows the resulting PDF."""
        j = self._running = MusicPreviewJob(text, title)
        j.done.connect(self._done)
        self._log.clear()
        self._log.connectJob(j)
        j.start()
        self._progress.start(self._lastbuildtime)

    def _done(self, success):
        self._progress.stop(False)
        pdfs = self._running.resultfiles()
        self.setDocuments(pdfs)
        if not pdfs:
            self._stack.setCurrentWidget(self._log)
            return
        self._lastbuildtime = self._running.elapsed_time()
        self._stack.setCurrentWidget(self._view)
        if self._current:
            self._current.cleanup()
        self._current = self._running  # keep the tempdir
        self._running = None

    def setDocuments(self, pdfs):
        """Loads the given PDF path names in the UI."""
        self._documents = [popplertools.Document(name) for name in pdfs]
        self._chooser.clear()
        self._chooser.addItems([d.name() for d in self._documents])
        self._top.setVisible(len(self._documents) > 1)
        if pdfs:
            self._chooser.setCurrentIndex(0)
            self.selectDocument(0)
        else:
            self._view.clear()

    def selectDocument(self, index):
        doc = self._documents[index].document()
        if doc:
            self._view.load(doc)

    def cleanup(self):
        if self._running:
            self._running.abort()
            self._running.cleanup()
            self._running = None
        if self._current:
            self._current.cleanup()
            self._current = None
        self._stack.setCurrentWidget(self._log)
        self._top.hide()
        self._view.clear()

    def print_(self):
        """Prints the currently displayed document."""
        if self._documents:
            doc = self._documents[self._chooser.currentIndex()]
            import popplerprint
            popplerprint.printDocument(doc, self)
Esempio n. 7
0
class MusicPreviewWidget(QWidget):
    def __init__(self, parent=None):
        super(MusicPreviewWidget, self).__init__(parent)
        self._lastbuildtime = 10.0
        self._running = None
        self._current = None
        
        self._chooserLabel = QLabel()
        self._chooser = QComboBox(self, activated=self.selectDocument)
        self._log = log.Log()
        self._view = popplerview.View()
        self._progress = widgets.progressbar.TimedProgressBar()
        
        self._stack = QStackedLayout()
        self._top = QWidget()
        
        layout = QVBoxLayout()
        self.setLayout(layout)
        
        layout.addWidget(self._top)
        layout.addLayout(self._stack)
        layout.addWidget(self._progress)
        
        top = QHBoxLayout()
        top.setContentsMargins(0, 0, 0, 0)
        top.setSpacing(2)
        self._top.setLayout(top)
        top.addWidget(self._chooserLabel)
        top.addWidget(self._chooser)
        top.addStretch(1)
        
        self._stack.addWidget(self._log)
        self._stack.addWidget(self._view)
        
        self._top.hide()
        app.aboutToQuit.connect(self.cleanup)
        app.translateUI(self)
    
    def translateUI(self):
        self._chooserLabel.setText(_("Document:"))
        
    def preview(self, text, title=None):
        """Runs LilyPond on the given text and shows the resulting PDF."""
        j = self._running = MusicPreviewJob(text, title)
        j.done.connect(self._done)
        self._log.clear()
        self._log.connectJob(j)
        j.start()
        self._progress.start(self._lastbuildtime)
    
    def _done(self, success):
        self._progress.stop(False)
        pdfs = self._running.resultfiles()
        self.setDocuments(pdfs)
        if not pdfs:
            self._stack.setCurrentWidget(self._log)
            return
        self._lastbuildtime = self._running.elapsed_time()
        self._stack.setCurrentWidget(self._view)
        if self._current:
            self._current.cleanup()
        self._current = self._running # keep the tempdir
        self._running = None
        
    def setDocuments(self, pdfs):
        """Loads the given PDF path names in the UI."""
        self._documents = [popplertools.Document(name) for name in pdfs]
        self._chooser.clear()
        self._chooser.addItems([d.name() for d in self._documents])
        self._top.setVisible(len(self._documents) > 1)
        if pdfs:
            self._chooser.setCurrentIndex(0)
            self.selectDocument(0)
        else:
            self._view.clear()

    def selectDocument(self, index):
        doc = self._documents[index].document()
        if doc:
            self._view.load(doc)

    def cleanup(self):
        if self._running:
            self._running.abort()
            self._running.cleanup()
            self._running = None
        if self._current:
            self._current.cleanup()
            self._current = None
        self._stack.setCurrentWidget(self._log)
        self._top.hide()
        self._view.clear()
    
    def print_(self):
        """Prints the currently displayed document."""
        if self._documents:
            doc = self._documents[self._chooser.currentIndex()]
            import popplerprint
            popplerprint.printDocument(doc, self)
Esempio n. 8
0
class InstallWizard(QDialog):

    def __init__(self, config, network, storage, app):
        QDialog.__init__(self)
        self.app = app
        self.config = config
        self.network = network
        self.storage = storage
        self.setMinimumSize(575, 400)
        self.setMaximumSize(575, 400)
        self.setWindowTitle('Electrum-VCN' + '  -  ' + _('Install Wizard'))
        self.connect(self, QtCore.SIGNAL('accept'), self.accept)
        self.stack = QStackedLayout()
        self.setLayout(self.stack)

    def set_layout(self, layout):
        w = QWidget()
        w.setLayout(layout)
        self.stack.addWidget(w)
        self.stack.setCurrentWidget(w)
        self.show()

    def restore_or_create(self):
        vbox = QVBoxLayout()

        main_label = QLabel(_("Electrum-VCN could not find an existing wallet."))
        vbox.addWidget(main_label)

        grid = QGridLayout()
        grid.setSpacing(5)

        gb1 = QGroupBox(_("What do you want to do?"))
        vbox.addWidget(gb1)
        vbox1 = QVBoxLayout()
        gb1.setLayout(vbox1)

        b1 = QRadioButton(gb1)
        b1.setText(_("Create new wallet"))
        b1.setChecked(True)

        b2 = QRadioButton(gb1)
        b2.setText(_("Restore a wallet or import keys"))

        group1 = QButtonGroup()
        group1.addButton(b1)
        group1.addButton(b2)
        vbox1.addWidget(b1)
        vbox1.addWidget(b2)

        gb2 = QGroupBox(_("Wallet type:"))
        vbox.addWidget(gb2)

        vbox2 = QVBoxLayout()
        gb2.setLayout(vbox2)

        group2 = QButtonGroup()

        self.wallet_types = [
            ('standard', _("Standard wallet")),
            ('twofactor', _("Wallet with two-factor authentication")),
            ('multisig', _("Multi-signature wallet")),
            ('hardware', _("Hardware wallet")),
        ]

        for i, (wtype, name) in enumerate(self.wallet_types):
            if not filter(lambda x: x[0] == wtype, electrum.wallet.wallet_types):
                continue
            button = QRadioButton(gb2)
            button.setText(name)
            vbox2.addWidget(button)
            group2.addButton(button)
            group2.setId(button, i)

            if i == 0:
                button.setChecked(True)

        vbox.addStretch(1)
        self.set_layout(vbox)
        vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _('Next'))))
        self.show()
        self.raise_()

        if not self.exec_():
            return None, None

        action = 'create' if b1.isChecked() else 'restore'
        wallet_type = self.wallet_types[group2.checkedId()][0]
        return action, wallet_type

    def verify_seed(self, seed, sid, func=None):
        r = self.enter_seed_dialog(MSG_VERIFY_SEED, sid, func)
        if not r:
            return
        if prepare_seed(r) != prepare_seed(seed):
            QMessageBox.warning(None, _('Error'), _('Incorrect seed'), _('OK'))
            return False
        else:
            return True

    def get_seed_text(self, seed_e):
        text = unicode(seed_e.toPlainText()).strip()
        text = ' '.join(text.split())
        return text

    def is_any(self, text):
        return Wallet.is_seed(text) or Wallet.is_old_mpk(text) or Wallet.is_xpub(text) or Wallet.is_xprv(text) or Wallet.is_address(text) or Wallet.is_private_key(text)

    def is_mpk(self, text):
        return Wallet.is_xpub(text) or Wallet.is_old_mpk(text)

    def enter_seed_dialog(self, msg, sid, func=None):
        if func is None:
            func = self.is_any
        vbox, seed_e = seed_dialog.enter_seed_box(msg, self, sid)
        vbox.addStretch(1)
        button = OkButton(self, _('Next'))
        vbox.addLayout(Buttons(CancelButton(self), button))
        button.setEnabled(False)
        seed_e.textChanged.connect(lambda: button.setEnabled(func(self.get_seed_text(seed_e))))
        self.set_layout(vbox)
        if not self.exec_():
            return
        return self.get_seed_text(seed_e)

    def multi_mpk_dialog(self, xpub_hot, n):
        vbox = QVBoxLayout()
        scroll = QScrollArea()
        scroll.setEnabled(True)
        scroll.setWidgetResizable(True)
        vbox.addWidget(scroll)

        w = QWidget()
        scroll.setWidget(w)

        innerVbox = QVBoxLayout()
        w.setLayout(innerVbox)

        vbox0 = seed_dialog.show_seed_box(MSG_SHOW_MPK, xpub_hot, 'hot')
        innerVbox.addLayout(vbox0)
        entries = []
        for i in range(n):
            msg = _("Please enter the master public key of cosigner") + ' %d' % (i + 1)
            vbox2, seed_e2 = seed_dialog.enter_seed_box(msg, self, 'cold')
            innerVbox.addLayout(vbox2)
            entries.append(seed_e2)
        vbox.addStretch(1)
        button = OkButton(self, _('Next'))
        vbox.addLayout(Buttons(CancelButton(self), button))
        button.setEnabled(False)
        f = lambda: button.setEnabled(
            map(lambda e: Wallet.is_xpub(
                self.get_seed_text(e)), entries) == [True] * len(entries))
        for e in entries:
            e.textChanged.connect(f)
        self.set_layout(vbox)
        if not self.exec_():
            return
        return map(lambda e: self.get_seed_text(e), entries)

    def multi_seed_dialog(self, n):
        vbox = QVBoxLayout()
        scroll = QScrollArea()
        scroll.setEnabled(True)
        scroll.setWidgetResizable(True)
        vbox.addWidget(scroll)

        w = QWidget()
        scroll.setWidget(w)

        innerVbox = QVBoxLayout()
        w.setLayout(innerVbox)

        vbox1, seed_e1 = seed_dialog.enter_seed_box(MSG_ENTER_SEED_OR_MPK, self, 'hot')
        innerVbox.addLayout(vbox1)
        entries = [seed_e1]
        for i in range(n):
            vbox2, seed_e2 = seed_dialog.enter_seed_box(MSG_ENTER_SEED_OR_MPK, self, 'cold')
            innerVbox.addLayout(vbox2)
            entries.append(seed_e2)
        vbox.addStretch(1)
        button = OkButton(self, _('Next'))
        vbox.addLayout(Buttons(CancelButton(self), button))
        button.setEnabled(False)
        f = lambda: button.setEnabled(
            map(lambda e: self.is_any(
                self.get_seed_text(e)), entries) == [True] * len(entries))
        for e in entries:
            e.textChanged.connect(f)
        self.set_layout(vbox)
        if not self.exec_():
            return
        return map(lambda e: self.get_seed_text(e), entries)

    def waiting_dialog(self, task, msg=_("Electrum is generating your addresses, please wait.")):
        def target():
            task()
            self.emit(QtCore.SIGNAL('accept'))

        vbox = QVBoxLayout()
        self.waiting_label = QLabel(msg)
        vbox.addWidget(self.waiting_label)
        self.set_layout(vbox)
        t = threading.Thread(target=target)
        t.start()
        self.exec_()

    def network_dialog(self):
        # skip this if config already exists
        if self.config.get('server') is not None:
            return

        grid = QGridLayout()
        grid.setSpacing(5)

        label = QLabel(_(
            "Electrum communicates with remote servers to get ",
            'information about your transactions and addresses. ',
            'The servers all fulfil the same purpose only ',
            'differing in hardware. In most cases you simply ',
            'want to let Electrum pick one at random if you ',
            'have a preference though feel free to select a server manually.') + "\n\n" + _(
            "How do you want to connect to a server:") + " ")
        label.setWordWrap(True)
        grid.addWidget(label, 0, 0)

        gb = QGroupBox()

        b1 = QRadioButton(gb)
        b1.setText(_("Auto connect"))
        b1.setChecked(True)

        b2 = QRadioButton(gb)
        b2.setText(_("Select server manually"))

        # b3 = QRadioButton(gb)
        # b3.setText(_("Stay offline"))

        grid.addWidget(b1, 1, 0)
        grid.addWidget(b2, 2, 0)
        # grid.addWidget(b3, 3, 0)

        vbox = QVBoxLayout()
        vbox.addLayout(grid)

        vbox.addStretch(1)
        vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _('Next'))))

        self.set_layout(vbox)
        if not self.exec_():
            return

        if b2.isChecked():
            return NetworkDialog(self.network, self.config, None).do_exec()
        else:
            self.config.set_key('auto_connect', True, True)
            return

    def show_message(self, msg, icon=None):
        vbox = QVBoxLayout()
        self.set_layout(vbox)
        if icon:
            logo = QLabel()
            logo.setPixmap(icon)
            vbox.addWidget(logo)
        vbox.addWidget(QLabel(msg))
        vbox.addStretch(1)
        vbox.addLayout(Buttons(CloseButton(self)))
        if not self.exec_():
            return None

    def choice(self, title, msg, choices):
        vbox = QVBoxLayout()
        self.set_layout(vbox)
        vbox.addWidget(QLabel(title))
        gb2 = QGroupBox(msg)
        vbox.addWidget(gb2)

        vbox2 = QVBoxLayout()
        gb2.setLayout(vbox2)

        group2 = QButtonGroup()
        for i, c in enumerate(choices):
            button = QRadioButton(gb2)
            button.setText(c[1])
            vbox2.addWidget(button)
            group2.addButton(button)
            group2.setId(button, i)
            if i == 0:
                button.setChecked(True)
        vbox.addStretch(1)
        vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _('Next'))))
        if not self.exec_():
            return
        wallet_type = choices[group2.checkedId()][0]
        return wallet_type

    def multisig_choice(self):
        vbox = QVBoxLayout()
        self.set_layout(vbox)
        vbox.addWidget(QLabel(_("Multi Signature Wallet")))

        cw = CosignWidget(2, 2)
        vbox.addWidget(cw, 1)
        vbox.addWidget(QLabel(_("Please choose the number of signatures needed to unlock funds in your wallet") + ':'))

        m_edit = QSpinBox()
        n_edit = QSpinBox()
        m_edit.setValue(2)
        n_edit.setValue(2)
        n_edit.setMinimum(2)
        n_edit.setMaximum(15)
        m_edit.setMinimum(1)
        m_edit.setMaximum(2)
        n_edit.valueChanged.connect(m_edit.setMaximum)

        n_edit.valueChanged.connect(cw.set_n)
        m_edit.valueChanged.connect(cw.set_m)

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel(_('Require')))
        hbox.addWidget(m_edit)
        hbox.addWidget(QLabel(_('of')))
        hbox.addWidget(n_edit)
        hbox.addWidget(QLabel(_('signatures')))
        hbox.addStretch(1)

        vbox.addLayout(hbox)
        vbox.addStretch(1)
        vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _('Next'))))
        if not self.exec_():
            return
        m = int(m_edit.value())
        n = int(n_edit.value())
        wallet_type = '%dof%d' % (m, n)
        return wallet_type

    def question(self, msg, yes_label=_('OK'), no_label=_('Cancel'), icon=None):
        vbox = QVBoxLayout()
        self.set_layout(vbox)
        if icon:
            logo = QLabel()
            logo.setPixmap(icon)
            vbox.addWidget(logo)
        label = QLabel(msg)
        label.setWordWrap(True)
        vbox.addWidget(label)
        vbox.addStretch(1)
        vbox.addLayout(Buttons(CancelButton(self, no_label), OkButton(self, yes_label)))
        if not self.exec_():
            return None
        return True

    def show_seed(self, seed, sid):
        vbox = seed_dialog.show_seed_box_msg(seed, sid)
        vbox.addLayout(Buttons(CancelButton(self), OkButton(self, _("Next"))))
        self.set_layout(vbox)
        return self.exec_()

    def password_dialog(self):
        msg = _("Please choose a password to encrypt your wallet keys.") + '\n' + _(
            "Leave these fields empty if you want to disable encryption.")
        from password_dialog import make_password_dialog, run_password_dialog
        self.set_layout(make_password_dialog(self, None, msg))
        return run_password_dialog(self, None, self)[2]

    def run(self, action, wallet_type):
        if action in ['create', 'restore']:
            if wallet_type == 'multisig':
                wallet_type = self.multisig_choice()
                if not wallet_type:
                    return
            elif wallet_type == 'hardware':
                hardware_wallets = []
                for item in electrum.wallet.wallet_types:
                    t, name, description, loader = item
                    if t == 'hardware':
                        try:
                            p = loader()
                        except:
                            util.print_error("cannot load plugin for:", name)
                            continue
                        if p:
                            hardware_wallets.append((name, description))
                wallet_type = self.choice(_("Hardware Wallet"), 'Select your hardware wallet', hardware_wallets)

                if not wallet_type:
                    return
            elif wallet_type == 'twofactor':
                wallet_type = '2fa'
            if action == 'create':
                self.storage.put('wallet_type', wallet_type, False)

        if action is None:
            return

        if action == 'restore':
            wallet = self.restore(wallet_type)
            if not wallet:
                return
            action = None
        else:
            wallet = Wallet(self.storage)
            action = wallet.get_action()
            # fixme: password is only needed for multiple accounts
            password = None

        # load wallet in plugins
        always_hook('installwizard_load_wallet', wallet, self)

        while action is not None:
            util.print_error("installwizard:", wallet, action)

            if action == 'create_seed':
                lang = self.config.get('language')
                seed = wallet.make_seed(lang)
                if not self.show_seed(seed, None):
                    return
                if not self.verify_seed(seed, None):
                    return
                password = self.password_dialog()
                wallet.add_seed(seed, password)
                wallet.create_master_keys(password)

            elif action == 'add_cosigners':
                n = int(re.match('(\d+)of(\d+)', wallet.wallet_type).group(2))
                xpub1 = wallet.master_public_keys.get("x1/")
                r = self.multi_mpk_dialog(xpub1, n - 1)
                if not r:
                    return
                for i, xpub in enumerate(r):
                    wallet.add_master_public_key("x%d/" % (i + 2), xpub)

            elif action == 'create_accounts':
                wallet.create_main_account(password)
                self.waiting_dialog(wallet.synchronize)

            else:
                f = always_hook('get_wizard_action', self, wallet, action)
                if not f:
                    raise BaseException('unknown wizard action', action)
                r = f(wallet, self)
                if not r:
                    return

            # next action
            action = wallet.get_action()

        if self.network:
            if self.network.interfaces:
                self.network_dialog()
            else:
                QMessageBox.information(None, _('Warning'), _('You are offline'), _('OK'))
                self.network.stop()
                self.network = None

        # start wallet threads
        wallet.start_threads(self.network)

        if action == 'restore':
            self.waiting_dialog(lambda: wallet.restore(self.waiting_label.setText))
            if self.network:
                msg = _("Recovery successful") if wallet.is_found() else _("No transactions found for this seed")
            else:
                msg = _("This wallet was restored offline. It may contain more addresses than displayed.")
            QMessageBox.information(None, _('Information'), msg, _('OK'))

        return wallet

    def restore(self, t):

            if t == 'standard':
                text = self.enter_seed_dialog(MSG_ENTER_ANYTHING, None)
                if not text:
                    return
                if Wallet.is_xprv(text):
                    password = self.password_dialog()
                    wallet = Wallet.from_xprv(text, password, self.storage)
                elif Wallet.is_old_mpk(text):
                    wallet = Wallet.from_old_mpk(text, self.storage)
                elif Wallet.is_xpub(text):
                    wallet = Wallet.from_xpub(text, self.storage)
                elif Wallet.is_address(text):
                    wallet = Wallet.from_address(text, self.storage)
                elif Wallet.is_private_key(text):
                    password = self.password_dialog()
                    wallet = Wallet.from_private_key(text, password, self.storage)
                elif Wallet.is_seed(text):
                    password = self.password_dialog()
                    wallet = Wallet.from_seed(text, password, self.storage)
                else:
                    raise BaseException('unknown wallet type')

            elif re.match('(\d+)of(\d+)', t):
                n = int(re.match('(\d+)of(\d+)', t).group(2))
                key_list = self.multi_seed_dialog(n - 1)
                if not key_list:
                    return
                password = self.password_dialog() if any(map(lambda x: Wallet.is_seed(x) or Wallet.is_xprv(x), key_list)) else None
                wallet = Wallet.from_multisig(key_list, password, self.storage, t)

            else:
                self.storage.put('wallet_type', t, False)
                # call the constructor to load the plugin (side effect)
                Wallet(self.storage)
                wallet = always_hook('installwizard_restore', self, self.storage)
                if not wallet:
                    util.print_error("no wallet")
                    return

            # create first keys offline
            self.waiting_dialog(wallet.synchronize)

            return wallet
Esempio n. 9
0
class ComboEditor(QWidget):

    def __init__(self, original=False):
        super(ComboEditor, self).__init__()
        self.__original = original
        self._symbols_index = []
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)

        self.bar = ActionBar()
        vbox.addWidget(self.bar)

        self.stacked = QStackedLayout()
        vbox.addLayout(self.stacked)

        self._main_container = IDE.get_service('main_container')

        self.connect(self.bar, SIGNAL("changeCurrent(PyQt_PyObject)"),
            self.set_current)
        self.connect(self.bar, SIGNAL("runFile(QString)"),
            self._run_file)
        self.connect(self.bar, SIGNAL("addToProject(QString)"),
            self._add_to_project)
        self.connect(self.bar, SIGNAL("goToSymbol(int)"),
            self._go_to_symbol)
        self.connect(self.bar, SIGNAL("reopenTab(QString)"),
            lambda path: self._main_container.open_file(path))
        self.connect(self.bar, SIGNAL("recentTabsModified()"),
            lambda: self._main_container.recent_files_changed())
        self.connect(self.bar.code_navigator.btnPrevious, SIGNAL("clicked()"),
            lambda: self._navigate_code(False))
        self.connect(self.bar.code_navigator.btnNext, SIGNAL("clicked()"),
            lambda: self._navigate_code(True))

    def _navigate_code(self, val):
        op = self.bar.code_navigator.operation
        self._main_container.navigate_code_history(val, op)

    def currentWidget(self):
        return self.stacked.currentWidget()

    def add_editor(self, neditable):
        """Add Editor Widget to the UI area."""
        if neditable.editor:
            self.stacked.addWidget(neditable.editor)
            self.bar.add_item(neditable.display_name, neditable)

            # Editor Signals
            self.connect(neditable.editor, SIGNAL("cursorPositionChanged()"),
                self._update_cursor_position)
            self.connect(neditable.editor, SIGNAL("currentLineChanged(int)"),
                self._set_current_symbol)
            self.connect(neditable, SIGNAL("checkersUpdated(PyQt_PyObject)"),
                self._show_notification_icon)
            self.connect(neditable, SIGNAL("fileSaved(PyQt_PyObject)"),
                self._update_symbols)

            # Connect file system signals only in the original
            self.connect(neditable, SIGNAL("fileClosing(PyQt_PyObject)"),
                self._close_file)
            if self.__original:
                self.connect(neditable,
                    SIGNAL("neverSavedFileClosing(PyQt_PyObject)"),
                    self._ask_for_save)

            # Load Symbols
            self._load_symbols(neditable)

    def show_combo_file(self):
        self.bar.combo.showPopup()

    def close_current_file(self):
        self.bar.about_to_close_file()

    def _close_file(self, neditable):
        index = self.bar.close_file(neditable)
        layoutItem = self.stacked.takeAt(index)
        neditable.editor.completer.cc.unload_module()
        self._add_to_last_opened(neditable.file_path)
        layoutItem.widget().deleteLater()

    def _add_to_last_opened(self, path):
        if path not in settings.LAST_OPENED_FILES:
            settings.LAST_OPENED_FILES.append(path)
            if len(settings.LAST_OPENED_FILES) > settings.MAX_REMEMBER_TABS:
                self.__lastOpened = self.__lastOpened[1:]
            self.emit(SIGNAL("recentTabsModified()"))

    def _ask_for_save(self, neditable):
        val = QMessageBox.No
        fileName = neditable.file_path
        val = QMessageBox.question(
            self, (self.tr('The file %s was not saved') %
                fileName),
                self.tr("Do you want to save before closing?"),
                QMessageBox.Yes | QMessageBox.No |
                QMessageBox.Cancel)
        if val == QMessageBox.No:
            neditable.nfile.close(force_close=True)
        elif val == QMessageBox.Yes:
            self._main_container.save_file(neditable.editor)
            neditable.nfile.close()

    def _run_file(self, path):
        self._main_container.run_file(path)

    def _add_to_project(self, path):
        self._main_container._add_to_project(path)

    def set_current(self, neditable):
        if neditable:
            self.stacked.setCurrentWidget(neditable.editor)
            self._update_cursor_position(ignore_sender=True)
            neditable.editor.setFocus()
            self._main_container.current_editor_changed(
                neditable.file_path)

    def widget(self, index):
        return self.stacked.widget(index)

    def count(self):
        """Return the number of editors opened."""
        return self.stacked.count()

    def _update_cursor_position(self, ignore_sender=False):
        obj = self.sender()
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if ignore_sender or editor == obj:
            line = editor.textCursor().blockNumber() + 1
            col = editor.textCursor().columnNumber()
            self.bar.update_line_col(line, col)

    def _set_current_symbol(self, line, ignore_sender=False):
        obj = self.sender()
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if ignore_sender or editor == obj:
            index = bisect.bisect(self._symbols_index, line)
            if self._symbols_index[index] > line:
                index -= 1
            self.bar.set_current_symbol(index)

    def _go_to_symbol(self, index):
        line = self._symbols_index[index]
        editor = self.stacked.currentWidget()
        editor.go_to_line(line)

    def _update_symbols(self, neditable):
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if editor == neditable.editor:
            self._load_symbols(neditable)

    def _load_symbols(self, neditable):
        symbols_handler = settings.get_symbols_handler('py')
        source = neditable.editor.toPlainText()
        source = source.encode(neditable.editor.encoding)
        symbols = symbols_handler.get_symbols_simplified(source)
        self._symbols_index = sorted(symbols.keys())
        symbols = sorted(list(symbols.items()), key=lambda x: x[0])
        self.bar.add_symbols(symbols)
        line = neditable.editor.textCursor().blockNumber()
        self._set_current_symbol(line, True)

    def _show_notification_icon(self, neditable):
        checkers = neditable.sorted_checkers
        icon = QIcon()
        for items in checkers:
            checker, color, _ = items
            if checker.checks:
                if isinstance(checker.checker_icon, int):
                    icon = self.style().standardIcon(checker.checker_icon)
                elif isinstance(checker.checker_icon, str):
                    icon = QIcon(checker.checker_icon)
                break
        self.bar.update_item_icon(neditable, icon)
Esempio n. 10
0
class ComboEditor(QWidget):

    def __init__(self, original=False):
        super(ComboEditor, self).__init__()
        self.__original = original
        self._symbols_index = []
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)

        self.bar = ActionBar()
        vbox.addWidget(self.bar)

        self.stacked = QStackedLayout()
        vbox.addLayout(self.stacked)

        self._main_container = IDE.get_service('main_container')

        self.connect(self.bar, SIGNAL("changeCurrent(PyQt_PyObject)"),
            self.set_current)
        self.connect(self.bar, SIGNAL("runFile(QString)"),
            self._run_file)
        self.connect(self.bar, SIGNAL("addToProject(QString)"),
            self._add_to_project)
        self.connect(self.bar, SIGNAL("goToSymbol(int)"),
            self._go_to_symbol)
        self.connect(self.bar, SIGNAL("reopenTab(QString)"),
            lambda path: self._main_container.open_file(path))
        self.connect(self.bar, SIGNAL("recentTabsModified()"),
            lambda: self._main_container.recent_files_changed())
        self.connect(self.bar.code_navigator.btnPrevious, SIGNAL("clicked()"),
            lambda: self._navigate_code(False))
        self.connect(self.bar.code_navigator.btnNext, SIGNAL("clicked()"),
            lambda: self._navigate_code(True))

    def _navigate_code(self, val):
        op = self.bar.code_navigator.operation
        self._main_container.navigate_code_history(val, op)

    def currentWidget(self):
        return self.stacked.currentWidget()

    def add_editor(self, neditable):
        """Add Editor Widget to the UI area."""
        if neditable.editor:
            self.stacked.addWidget(neditable.editor)
            self.bar.add_item(neditable.display_name, neditable)

            # Editor Signals
            self.connect(neditable.editor, SIGNAL("cursorPositionChanged()"),
                self._update_cursor_position)
            self.connect(neditable.editor, SIGNAL("currentLineChanged(int)"),
                self._set_current_symbol)
            self.connect(neditable, SIGNAL("checkersUpdated(PyQt_PyObject)"),
                self._show_notification_icon)
            self.connect(neditable, SIGNAL("fileSaved(PyQt_PyObject)"),
                self._update_symbols)

            # Connect file system signals only in the original
            self.connect(neditable, SIGNAL("fileClosing(PyQt_PyObject)"),
                self._close_file)
            if self.__original:
                self.connect(neditable,
                    SIGNAL("neverSavedFileClosing(PyQt_PyObject)"),
                    self._ask_for_save)

            # Load Symbols
            self._load_symbols(neditable)

    def show_combo_file(self):
        self.bar.combo.showPopup()

    def close_current_file(self):
        self.bar.about_to_close_file()

    def _close_file(self, neditable):
        index = self.bar.close_file(neditable)
        layoutItem = self.stacked.takeAt(index)
        neditable.editor.completer.cc.unload_module()
        self._add_to_last_opened(neditable.file_path)
        layoutItem.widget().deleteLater()

    def _add_to_last_opened(self, path):
        if path not in settings.LAST_OPENED_FILES:
            settings.LAST_OPENED_FILES.append(path)
            if len(settings.LAST_OPENED_FILES) > settings.MAX_REMEMBER_TABS:
                self.__lastOpened = self.__lastOpened[1:]
            self.emit(SIGNAL("recentTabsModified()"))

    def _ask_for_save(self, neditable):
        val = QMessageBox.No
        fileName = neditable.file_path
        val = QMessageBox.question(
            self, (self.tr('The file %s was not saved') %
                fileName),
                self.tr("Do you want to save before closing?"),
                QMessageBox.Yes | QMessageBox.No |
                QMessageBox.Cancel)
        if val == QMessageBox.No:
            neditable.nfile.close(force_close=True)
        elif val == QMessageBox.Yes:
            self._main_container.save_file(neditable.editor)
            neditable.nfile.close()

    def _run_file(self, path):
        self._main_container.run_file(path)

    def _add_to_project(self, path):
        self._main_container._add_to_project(path)

    def set_current(self, neditable):
        if neditable:
            self.stacked.setCurrentWidget(neditable.editor)
            self._update_cursor_position(ignore_sender=True)
            neditable.editor.setFocus()
            self._main_container.current_editor_changed(
                neditable.file_path)

    def widget(self, index):
        return self.stacked.widget(index)

    def count(self):
        """Return the number of editors opened."""
        return self.stacked.count()

    def _update_cursor_position(self, ignore_sender=False):
        obj = self.sender()
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if ignore_sender or editor == obj:
            line = editor.textCursor().blockNumber() + 1
            col = editor.textCursor().columnNumber()
            self.bar.update_line_col(line, col)

    def _set_current_symbol(self, line, ignore_sender=False):
        obj = self.sender()
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if ignore_sender or editor == obj:
            index = bisect.bisect(self._symbols_index, line)
            if (index >= len(self._symbols_index) or
                self._symbols_index[index] > (line + 1)):
                index -= 1
            self.bar.set_current_symbol(index)

    def _go_to_symbol(self, index):
        line = self._symbols_index[index]
        editor = self.stacked.currentWidget()
        editor.go_to_line(line)

    def _update_symbols(self, neditable):
        editor = self.stacked.currentWidget()
        # Check if it's current to avoid signals from other splits.
        if editor == neditable.editor:
            self._load_symbols(neditable)

    def _load_symbols(self, neditable):
        symbols_handler = settings.get_symbols_handler('py')
        source = neditable.editor.toPlainText()
        source = source.encode(neditable.editor.encoding)
        symbols = symbols_handler.get_symbols_simplified(source)
        self._symbols_index = sorted(symbols.keys())
        symbols = sorted(list(symbols.items()), key=lambda x: x[0])
        self.bar.add_symbols(symbols)
        line = neditable.editor.textCursor().blockNumber()
        self._set_current_symbol(line, True)

    def _show_notification_icon(self, neditable):
        checkers = neditable.sorted_checkers
        icon = QIcon()
        for items in checkers:
            checker, color, _ = items
            if checker.checks:
                if isinstance(checker.checker_icon, int):
                    icon = self.style().standardIcon(checker.checker_icon)
                elif isinstance(checker.checker_icon, str):
                    icon = QIcon(checker.checker_icon)
                break
        self.bar.update_item_icon(neditable, icon)