class QAbstractTextDocumentLayoutTest(UsesQApplication):

    objectType = QTextFormat.UserObject + 1

    def foo(self):
        fmt = QTextCharFormat()
        fmt.setObjectType(QAbstractTextDocumentLayoutTest.objectType)

        cursor = self.textEdit.textCursor()
        cursor.insertText(py3k.unichr(0xfffc), fmt)
        self.textEdit.setTextCursor(cursor)
        self.textEdit.close()

    def testIt(self):

        self.textEdit = QTextEdit()
        self.textEdit.show()

        interface = Foo()
        self.textEdit.document().documentLayout().registerHandler(
            QAbstractTextDocumentLayoutTest.objectType, interface)

        QTimer.singleShot(0, self.foo)
        self.app.exec_()

        self.assertTrue(Foo.called)
class QAbstractTextDocumentLayoutTest(UsesQApplication):

    objectType = QTextFormat.UserObject + 1

    def foo(self):
        fmt = QTextCharFormat()
        fmt.setObjectType(QAbstractTextDocumentLayoutTest.objectType)

        cursor = self.textEdit.textCursor()
        cursor.insertText(py3k.unichr(0xFFFC), fmt)
        self.textEdit.setTextCursor(cursor)
        self.textEdit.close()

    def testIt(self):

        self.textEdit = QTextEdit()
        self.textEdit.show()

        interface = Foo()
        self.textEdit.document().documentLayout().registerHandler(QAbstractTextDocumentLayoutTest.objectType, interface)

        QTimer.singleShot(0, self.foo)
        self.app.exec_()

        self.assertTrue(Foo.called)
Beispiel #3
0
 def testRefcount(self):
     textedit = QTextEdit()
     textedit.setReadOnly(True)
     doc = textedit.document()
     cursor = QTextCursor(doc)
     cursor.insertText("PySide Rocks")
     ud = TestUserData({"Life": 42})
     self.assertEqual(sys.getrefcount(ud), 2)
     cursor.block().setUserData(ud)
     self.assertEqual(sys.getrefcount(ud), 3)
     ud2 = cursor.block().userData()
     self.assertEqual(sys.getrefcount(ud), 4)
     self.udata = weakref.ref(ud, None)
     del ud, ud2
     self.assertEqual(sys.getrefcount(self.udata()), 2)
Beispiel #4
0
 def testRefcount(self):
     textedit = QTextEdit()
     textedit.setReadOnly(True)
     doc = textedit.document()
     cursor = QTextCursor(doc)
     cursor.insertText("PySide Rocks")
     ud = TestUserData({"Life": 42})
     self.assertEqual(sys.getrefcount(ud), 2)
     cursor.block().setUserData(ud)
     self.assertEqual(sys.getrefcount(ud), 3)
     ud2 = cursor.block().userData()
     self.assertEqual(sys.getrefcount(ud), 4)
     self.udata = weakref.ref(ud, None)
     del ud, ud2
     self.assertEqual(sys.getrefcount(self.udata()), 2)
Beispiel #5
0
    def tesIterator(self):
        edit = QTextEdit()
        cursor = edit.textCursor()
        fmt = QTextCharFormat()
        frags = []
        for i in range(10):
            fmt.setFontPointSize(i+10)
            frags.append("block%d"%i)
            cursor.insertText(frags[i], fmt)

        doc = edit.document()
        block = doc.begin()

        index = 0
        for i in block:
            self.assertEqual(i.fragment().text(), frags[index])
            index += 1
Beispiel #6
0
    def tesIterator(self):
        edit = QTextEdit()
        cursor = edit.textCursor()
        fmt = QTextCharFormat()
        frags = []
        for i in range(10):
            fmt.setFontPointSize(i + 10)
            frags.append("block%d" % i)
            cursor.insertText(frags[i], fmt)

        doc = edit.document()
        block = doc.begin()

        index = 0
        for i in block:
            self.assertEqual(i.fragment().text(), frags[index])
            index += 1
Beispiel #7
0
class RobocompDslGui(QMainWindow):
    def __init__(self, parent=None):
        super(RobocompDslGui, self).__init__(parent)
        self.setWindowTitle("Create new component")
        # self._idsl_paths = []
        self._communications = {
            "implements": [],
            "requires": [],
            "subscribesTo": [],
            "publishes": []
        }
        self._interfaces = {}
        self._cdsl_doc = CDSLDocument()
        self._command_process = QProcess()

        self._main_widget = QWidget()
        self._main_layout = QVBoxLayout()
        self.setCentralWidget(self._main_widget)

        self._name_layout = QHBoxLayout()
        self._name_line_edit = QLineEdit()
        self._name_line_edit.textEdited.connect(self.update_component_name)
        self._name_line_edit.setPlaceholderText("New component name")
        self._name_layout.addWidget(self._name_line_edit)
        self._name_layout.addStretch()

        # DIRECTORY SELECTION
        self._dir_line_edit = QLineEdit()
        # self._dir_line_edit.textEdited.connect(self.update_completer)
        self._dir_completer = QCompleter()
        self._dir_completer_model = QFileSystemModel()
        if os.path.isdir(ROBOCOMP_COMP_DIR):
            self._dir_line_edit.setText(ROBOCOMP_COMP_DIR)
            self._dir_completer_model.setRootPath(ROBOCOMP_COMP_DIR)
        self._dir_completer.setModel(self._dir_completer_model)
        self._dir_line_edit.setCompleter(self._dir_completer)

        self._dir_button = QPushButton("Select directory")
        self._dir_button.clicked.connect(self.set_output_directory)
        self._dir_layout = QHBoxLayout()
        self._dir_layout.addWidget(self._dir_line_edit)
        self._dir_layout.addWidget(self._dir_button)

        # LIST OF ROBOCOMP INTERFACES
        self._interface_list = QListWidget()
        self._interface_list.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self._interface_list.itemSelectionChanged.connect(
            self.set_comunication)

        # LIST OF CONNECTION TyPES
        self._type_combo_box = QComboBox()
        self._type_combo_box.addItems(
            ["publishes", "implements", "subscribesTo", "requires"])
        self._type_combo_box.currentIndexChanged.connect(
            self.reselect_existing)

        # BUTTON TO ADD A NEW CONNECTION
        # self._add_connection_button = QPushButton("Add")
        # self._add_connection_button.clicked.connect(self.add_new_comunication)
        self._add_connection_layout = QHBoxLayout()
        # self._add_connection_layout.addWidget(self._add_connection_button)
        self._language_combo_box = QComboBox()
        self._language_combo_box.addItems(["Python", "Cpp", "Cpp11"])
        self._language_combo_box.currentIndexChanged.connect(
            self.update_language)
        self._add_connection_layout.addWidget(self._language_combo_box)
        self._add_connection_layout.addStretch()
        self._gui_check_box = QCheckBox()
        self._gui_check_box.stateChanged.connect(self.update_gui_selection)
        self._gui_label = QLabel("Use Qt GUI")
        self._add_connection_layout.addWidget(self._gui_label)
        self._add_connection_layout.addWidget(self._gui_check_box)

        # WIDGET CONTAINING INTERFACES AND TYPES
        self._selection_layout = QVBoxLayout()
        self._selection_layout.addWidget(self._type_combo_box)
        self._selection_layout.addWidget(self._interface_list)
        self._selection_layout.addLayout(self._add_connection_layout)
        self._selection_widget = QWidget()
        self._selection_widget.setLayout(self._selection_layout)

        # TEXT EDITOR WITH THE RESULTING CDSL CODE
        self._editor = QTextEdit(self)
        self._editor.setHtml("")

        self._document = self._editor.document()
        self._component_directory = None

        # SPLITTER WITH THE SELECTION AND THE CODE
        self._body_splitter = QSplitter(Qt.Horizontal)
        self._body_splitter.addWidget(self._selection_widget)
        self._body_splitter.addWidget(self._editor)
        self._body_splitter.setStretchFactor(0, 2)
        self._body_splitter.setStretchFactor(1, 9)

        # CREATION BUTTONS
        self._create_button = QPushButton("Create .cdsl")
        self._create_button.clicked.connect(self.write_cdsl_file)
        self._creation_layout = QHBoxLayout()
        self._creation_layout.addStretch()
        self._creation_layout.addWidget(self._create_button)

        self._console = QConsole()
        self._command_process.readyReadStandardOutput.connect(
            self._console.standard_output)
        self._command_process.readyReadStandardError.connect(
            self._console.error_output)

        # ADDING WIDGETS TO MAIN LAYOUT
        self._main_widget.setLayout(self._main_layout)
        self._main_layout.addLayout(self._name_layout)
        self._main_layout.addLayout(self._dir_layout)
        self._main_layout.addWidget(self._body_splitter)
        self._main_layout.addLayout(self._creation_layout)
        self._main_layout.addWidget(self._console)
        self.setMinimumSize(800, 500)
        self._editor.setText(self._cdsl_doc.generate_doc())

    # self.editor->show();

    # def update_completer(self, path):
    # 	print "update_completer %s"%path
    # 	info = QFileInfo(path)
    # 	if info.exists() and info.isDir():
    # 			if not path.endswith(os.path.pathsep):
    # 				new_path = os.path.join(path, os.sep)
    # 				# self._dir_line_edit.setText(new_path)
    # 			all_dirs_output = [dI for dI in os.listdir(path) if os.path.isdir(os.path.join(path, dI))]
    # 			print all_dirs_output
    # 			self._dir_completer.complete()

    def load_idsl_files(self, fullpath=None):
        if fullpath is None:
            fullpath = ROBOCOMP_INTERFACES
        idsls_dir = os.path.join(ROBOCOMP_INTERFACES, "IDSLs")
        if os.path.isdir(idsls_dir):
            for full_filename in os.listdir(idsls_dir):
                file_name, file_extension = os.path.splitext(full_filename)
                if "idsl" in file_extension.lower():
                    full_idsl_path = os.path.join(idsls_dir, full_filename)
                    # self._idsl_paths.append(os.path.join(idsls_dir,full_filename))
                    self.parse_idsl_file(full_idsl_path)
        self._interface_list.addItems(self._interfaces.keys())

    def parse_idsl_file(self, fullpath):

        with open(fullpath, 'r') as fin:
            interface_name = None
            for line in fin:
                result = re.findall(r'^\s*interface\s+(\w+)\s*\{?\s*$',
                                    line,
                                    flags=re.MULTILINE)
                if len(result) > 0:
                    interface_name = result[0]
            print("%s for idsl %s" % (interface_name, fullpath))
            if interface_name is not None:
                self._interfaces[interface_name] = fullpath

    def add_new_comunication(self):
        interface_names = self._interface_list.selectedItems()
        com_type = str(self._type_combo_box.currentText())
        for iface_name_item in interface_names:
            iface_name = str(iface_name_item.text())
            self._communications[com_type].append(iface_name)
            idsl_full_path = self._interfaces[iface_name]
            idsl_full_filename = os.path.basename(idsl_full_path)
            self._cdsl_doc.add_comunication(com_type, iface_name)
            self._cdsl_doc.add_import(idsl_full_filename)
        self.update_editor()

    def set_comunication(self):
        interface_names = self._interface_list.selectedItems()
        com_type = str(self._type_combo_box.currentText())
        self._communications[com_type] = []
        self._cdsl_doc.clear_comunication(com_type)
        for iface_name_item in interface_names:
            iface_name = str(iface_name_item.text())
            self._communications[com_type].append(iface_name)
            self._cdsl_doc.add_comunication(com_type, iface_name)
        self.update_imports()
        self.update_editor()

    def update_imports(self):
        self._cdsl_doc.clear_imports()
        for com_type in self._communications:
            for iface_name in self._communications[com_type]:
                idsl_full_path = self._interfaces[iface_name]
                idsl_full_filename = os.path.basename(idsl_full_path)
                self._cdsl_doc.add_import(idsl_full_filename)

    def update_language(self):
        language = self._language_combo_box.currentText()
        self._cdsl_doc.set_language(str(language))
        self.update_editor()

    def update_gui_selection(self):
        checked = self._gui_check_box.isChecked()
        if checked:
            self._cdsl_doc.set_qui(True)
        else:
            self._cdsl_doc.set_qui(False)
        self.update_editor()

    def update_component_name(self, name):
        self._cdsl_doc.set_name(name)
        self.update_editor()

    def update_editor(self):
        self._editor.setText(self._cdsl_doc.generate_doc())

    def set_output_directory(self):
        dir_set = False
        while not dir_set:
            dir = QFileDialog.getExistingDirectory(
                self, "Select Directory", ROBOCOMP_COMP_DIR,
                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
            if self.check_dir_is_empty(str(dir)):
                self._dir_line_edit.setText(dir)
                dir_set = True

    def write_cdsl_file(self):
        component_dir = str(self._dir_line_edit.text())
        text = self._cdsl_doc.generate_doc()
        if not self._name_line_edit.text():
            component_name, ok = QInputDialog.getText(self,
                                                      'No component name set',
                                                      'Enter component name:')
            if ok:
                self.update_component_name(component_name)
                self._name_line_edit.setText(component_name)
            else:
                return False

        if not os.path.exists(component_dir):
            if QMessageBox.Yes == QMessageBox.question(
                    self, "Directory doesn't exist.",
                    "Do you want create the directory %s?" % component_dir,
                    QMessageBox.Yes | QMessageBox.No):
                os.makedirs(component_dir)
            else:
                QMessageBox.question(
                    self, "Directory not exist",
                    "Can't create a component witout a valid directory")
                return False

        file_path = os.path.join(component_dir,
                                 str(self._name_line_edit.text()) + ".cdsl")
        if os.path.exists(file_path):
            if QMessageBox.No == QMessageBox.question(
                    self, "File already exists", "Do you want to overwrite?",
                    QMessageBox.Yes | QMessageBox.No):
                return False

        with open(file_path, 'w') as the_file:
            the_file.write(text)
        self.execute_robocomp_cdsl()
        return True

    def execute_robocomp_cdsl(self):
        cdsl_file_path = os.path.join(
            str(self._dir_line_edit.text()),
            str(self._name_line_edit.text()) + ".cdsl")
        command = "python -u %s/robocompdsl.py %s %s" % (
            ROBOCOMPDSL_DIR, cdsl_file_path,
            os.path.join(str(self._dir_line_edit.text())))
        self._console.append_custom_text("%s\n" % command)
        self._command_process.start(command,
                                    QProcess.Unbuffered | QProcess.ReadWrite)

    def reselect_existing(self):
        com_type = self._type_combo_box.currentText()
        selected = self._communications[com_type]
        self._interface_list.clearSelection()
        for iface in selected:
            items = self._interface_list.findItems(iface,
                                                   Qt.MatchFlag.MatchExactly)
            if len(items) > 0:
                item = items[0]
                item.setSelected(True)

    def check_dir_is_empty(self, dir_path):
        if len(os.listdir(dir_path)) > 0:
            msgBox = QMessageBox()
            msgBox.setWindowTitle("Directory not empty")
            msgBox.setText(
                "The selected directory is not empty.\n"
                "For a new Component you usually want a new directory.\n"
                "Do you want to use this directory anyway?")
            msgBox.setStandardButtons(QMessageBox.Yes)
            msgBox.addButton(QMessageBox.No)
            msgBox.setDefaultButton(QMessageBox.No)
            if msgBox.exec_() == QMessageBox.Yes:
                return True
            else:
                return False
        else:
            return True
Beispiel #8
0
class MainWindow(QMainWindow):
    windows = []

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

        # Store ourself.
        self.windows.append(self)

        # State!
        self.current_file = None

        # Editor!
        self.editor = QTextEdit()
        self.setCentralWidget(self.editor)

        # Style the editor
        #style.apply_stylesheet(self.editor, 'editor.qss')

        # Menus and Stuff!
        self.init_actions()
        self.init_menus()
        self.init_toolbars()
        self.init_statusbar()

        # Settings!
        self.init_settings()

        # Icons!
        self.reload_icons()
        #style.style_reloaded.connect(self.reload_icons)

        # Fancy!
        #style.enable_aero(self)
        self.update_title()

        # Now, for some plugins.
#        plugins.run_signal('new_window', self)

##### Action Icons! #######################################################

    def reload_icons(self):
        #self.setWindowIcon(style.icon('application'))
        pass
#         a = self.actions
#         for key in a.keys():
#             a[key].setIcon(style.icon(key.lower()))

##### Actions! ############################################################

    def init_actions(self):
        self.actions = a = {}

        ##### File Menu #######################################################

        a['document-new'] = QAction("&New",
                                    self,
                                    shortcut=QKeySequence.New,
                                    statusTip="Create a new file.",
                                    triggered=self.action_new)

        a['document-open'] = QAction("&Open",
                                     self,
                                     shortcut=QKeySequence.Open,
                                     statusTip="Open an existing file.",
                                     triggered=self.action_open)

        a['document-save'] = QAction("&Save",
                                     self,
                                     shortcut=QKeySequence.Save,
                                     statusTip="Save the document to disk.",
                                     triggered=self.action_save)

        a['application-exit'] = QAction("E&xit",
                                        self,
                                        statusTip="Exit the application.",
                                        triggered=self.close)

        ##### Edit Menu #######################################################

        a['edit-cut'] = QAction("Cu&t",
                                self,
                                shortcut=QKeySequence.Cut,
                                triggered=self.editor.cut)

        a['edit-copy'] = QAction("&Copy",
                                 self,
                                 shortcut=QKeySequence.Copy,
                                 triggered=self.editor.copy)

        a['edit-paste'] = QAction("&Paste",
                                  self,
                                  shortcut=QKeySequence.Paste,
                                  triggered=self.editor.paste)

        a['edit-cut'].setEnabled(False)
        a['edit-copy'].setEnabled(False)

        self.editor.copyAvailable.connect(a['edit-cut'].setEnabled)
        self.editor.copyAvailable.connect(a['edit-copy'].setEnabled)

        ##### Tool Menu #######################################################

        # This is the fun part.
        a['addon-manager'] = QAction("&Add-ons",
                                     self,
                                     shortcut="Ctrl+Shift+A",
                                     statusTip="Display the Add-ons manager.",
                                     triggered=addons.show)

#         a['view-refresh'] = QAction("&Reload Style", self,
#                                 shortcut="Ctrl+Shift+R",
#                                 statusTip="Reload the style.",
#                                 triggered=style.reload)

##### Menus! ##############################################################

    def init_menus(self):
        self.menuBar().clear()
        a = self.actions

        file = self.menuBar().addMenu("&File")
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])
        file.addSeparator()
        file.addAction(a['application-exit'])

        edit = self.menuBar().addMenu("&Edit")
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.menuBar().addMenu("&Tools")
        tools.addAction(a['addon-manager'])
        #tools.addAction(a['view-refresh'])

    ##### Explosions! #########################################################

    ##### Toolbars! ###########################################################

    def init_toolbars(self):
        a = self.actions

        file = self.addToolBar("File")
        file.setObjectName('filebar')
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])

        edit = self.addToolBar("Edit")
        edit.setObjectName('editbar')
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.addToolBar("Tools")
        tools.setObjectName('toolsbar')
        tools.addAction(a['addon-manager'])
        #tools.addAction(a['view-refresh'])

    ##### Statusbars! #########################################################

    def init_statusbar(self):
        self.statusBar().showMessage("Ready.")

    ##### Settings! ###########################################################

    def init_settings(self):
        self.restoreGeometry(profile.get("geometry"))
        self.restoreState(profile.get("state"))

    def save_settings(self):
        profile.set("geometry", self.saveGeometry())
        profile.set("state", self.saveState())

    ##### Actual Actions! #####################################################

    def update_title(self):
        if self.current_file:
            title = os.path.basename(self.current_file)
        else:
            title = "Untitled"
        self.setWindowTitle("%s - %s" %
                            (title, QApplication.instance().applicationName()))

    def action_new(self):
        if self.try_save():
            self.editor.clear()
            self.current_file = None
            self.update_title()

    def action_open(self):
        if self.try_save():
            fn = QFileDialog.getOpenFileName(self)[0]
            if not fn:
                return

            self.do_open(fn)

    def do_open(self, fn):
        with open(fn, 'r') as f:
            content = f.read()

        self.editor.setPlainText(content)
        self.current_file = fn
        self.update_title()

    def action_save(self):
        if not self.editor.document().isModified():
            return

        if not self.current_file:
            self.current_file = QFileDialog.getSaveFileName(self)[0]
            self.update_title()

        if not self.current_file:
            return

        with open(self.current_file, 'w') as f:
            f.write(self.editor.toPlainText())
        self.editor.document().setModified(False)

    ##### Adventure! ##########################################################

    def try_save(self):
        if self.editor.document().isModified():
            ret = QMessageBox.warning(
                self, "Blah Blah Blah",
                "That's an awfully nice modified document you've got there"
                ". It'd be a shame if anything... happened to it. Catch "
                "my drift?",
                QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
            if ret == QMessageBox.Save:
                self.action_save()

            elif ret == QMessageBox.Cancel:
                return False

        return True

    def showRaise(self):
        """ Show and raise the window. """
        #         self.show()
        #         self.raise_()
        #         self.setFocus()
        self.activateWindow()
        if self.isMinimized():
            self.showNormal()

    def closeEvent(self, event):
        if self.try_save():
            self.save_settings()

            if self in self.windows:
                self.windows.remove(self)

#            plugins.run_signal('close_window', self)

            event.accept()
        else:
            event.ignore()
Beispiel #9
0
class MainWindow(QMainWindow):
    windows = []

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

        # Store ourself.
        self.windows.append(self)

        # State!
        self.current_file = None

        # Editor!
        self.editor = QTextEdit()
        self.setCentralWidget(self.editor)

        # Style the editor
        style.apply_stylesheet(self.editor, 'editor.qss')
        
        # Menus and Stuff!
        self.init_actions()
        self.init_menus()
        self.init_toolbars()
        self.init_statusbar()

        # Settings!
        self.init_settings()

        # Icons!
        self.reload_icons()
        style.style_reloaded.connect(self.reload_icons)

        # Fancy!
        style.enable_aero(self)
        self.update_title()

        # Now, for some plugins.
        plugins.run_signal('new_window', self)

    ##### Action Icons! #######################################################

    def reload_icons(self):
        self.setWindowIcon(style.icon('application'))

        a = self.actions
        for key in a.keys():
            a[key].setIcon(style.icon(key.lower()))

    ##### Actions! ############################################################

    def init_actions(self):
        self.actions = a = {}

        ##### File Menu #######################################################

        a['document-new'] = QAction("&New", self, shortcut=QKeySequence.New,
                        statusTip="Create a new file.",
                        triggered=self.action_new)

        a['document-open'] = QAction("&Open", self, shortcut=QKeySequence.Open,
                        statusTip="Open an existing file.",
                        triggered=self.action_open)

        a['document-save'] = QAction("&Save", self, shortcut=QKeySequence.Save,
                        statusTip="Save the document to disk.",
                        triggered=self.action_save)

        a['application-exit'] = QAction("E&xit", self,
                        statusTip="Exit the application.",
                        triggered=self.close)

        ##### Edit Menu #######################################################

        a['edit-cut'] = QAction("Cu&t", self, shortcut=QKeySequence.Cut,
                        triggered=self.editor.cut)

        a['edit-copy'] = QAction("&Copy", self, shortcut=QKeySequence.Copy,
                        triggered=self.editor.copy)

        a['edit-paste'] = QAction("&Paste", self, shortcut=QKeySequence.Paste,
                        triggered=self.editor.paste)

        a['edit-cut'].setEnabled(False)
        a['edit-copy'].setEnabled(False)

        self.editor.copyAvailable.connect(a['edit-cut'].setEnabled)
        self.editor.copyAvailable.connect(a['edit-copy'].setEnabled)

        ##### Tool Menu #######################################################

        # This is the fun part.
        a['addon-manager'] = QAction("&Add-ons", self, shortcut="Ctrl+Shift+A",
                                statusTip="Display the Add-ons manager.",
                                triggered=addons.show)

        a['view-refresh'] = QAction("&Reload Style", self,
                                shortcut="Ctrl+Shift+R",
                                statusTip="Reload the style.",
                                triggered=style.reload)

    ##### Menus! ##############################################################

    def init_menus(self):
        self.menuBar().clear()
        a = self.actions

        file = self.menuBar().addMenu("&File")
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])
        file.addSeparator()
        file.addAction(a['application-exit'])

        edit = self.menuBar().addMenu("&Edit")
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.menuBar().addMenu("&Tools")
        tools.addAction(a['addon-manager'])
        tools.addAction(a['view-refresh'])

    ##### Explosions! #########################################################

    ##### Toolbars! ###########################################################

    def init_toolbars(self):
        a = self.actions

        file = self.addToolBar("File")
        file.setObjectName('filebar')
        file.addAction(a['document-new'])
        file.addAction(a['document-open'])
        file.addAction(a['document-save'])

        edit = self.addToolBar("Edit")
        edit.setObjectName('editbar')
        edit.addAction(a['edit-cut'])
        edit.addAction(a['edit-copy'])
        edit.addAction(a['edit-paste'])

        tools = self.addToolBar("Tools")
        tools.setObjectName('toolsbar')
        tools.addAction(a['addon-manager'])
        tools.addAction(a['view-refresh'])

    ##### Statusbars! #########################################################

    def init_statusbar(self):
        self.statusBar().showMessage("Ready.")

    ##### Settings! ###########################################################

    def init_settings(self):
        self.restoreGeometry(profile.get("geometry"))
        self.restoreState(profile.get("state"))

    def save_settings(self):
        profile.set("geometry", self.saveGeometry())
        profile.set("state", self.saveState())

    ##### Actual Actions! #####################################################

    def update_title(self):
        if self.current_file:
            title = os.path.basename(self.current_file)
        else:
            title = "Untitled"
        self.setWindowTitle("%s - %s" % (title,
                QApplication.instance().applicationName()))

    def action_new(self):
        if self.try_save():
            self.editor.clear()
            self.current_file = None
            self.update_title()

    def action_open(self):
        if self.try_save():
            fn = QFileDialog.getOpenFileName(self)[0]
            if not fn:
                return

            self.do_open(fn)

    def do_open(self, fn):
        with open(fn, 'r') as f:
            content = f.read()

        self.editor.setPlainText(content)
        self.current_file = fn
        self.update_title()

    def action_save(self):
        if not self.editor.document().isModified():
            return

        if not self.current_file:
            self.current_file = QFileDialog.getSaveFileName(self)[0]
            self.update_title()

        if not self.current_file:
            return

        with open(self.current_file, 'w') as f:
            f.write(self.editor.toPlainText())
        self.editor.document().setModified(False)

    ##### Adventure! ##########################################################

    def try_save(self):
        if self.editor.document().isModified():
            ret = QMessageBox.warning(self, "Blah Blah Blah",
                    "That's an awfully nice modified document you've got there"
                    ". It'd be a shame if anything... happened to it. Catch "
                    "my drift?",
                    QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel
                    )
            if ret == QMessageBox.Save:
                self.action_save()

            elif ret == QMessageBox.Cancel:
                return False

        return True

    def closeEvent(self, event):
        if self.try_save():
            self.save_settings()

            if self in self.windows:
                self.windows.remove(self)

            plugins.run_signal('close_window', self)

            event.accept()
        else:
            event.ignore()
Beispiel #10
0
class qNotebook(QVBoxLayout):
    def __init__(self):
        QVBoxLayout.__init__(self)
        self._teditor = QTextEdit()
        self._teditor.setMinimumWidth(500)
        self._teditor.setStyleSheet("font: 12pt \"Courier\";")
        button_layout = QHBoxLayout()
        self.addLayout(button_layout)
        self.clear_but = qmy_button(button_layout, self.clear_all, "clear")
        self.copy_but = qmy_button(button_layout, self._teditor.copy, "copy")
        qmy_button(button_layout, self._teditor.selectAll, "select all")
        qmy_button(button_layout, self._teditor.undo, "undo")
        qmy_button(button_layout, self._teditor.redo, "redo")
        search_button = qButtonWithArgumentsClass("search", self.search_for_text, {"search_text": ""})
        button_layout.addWidget(search_button)
        qmy_button(button_layout, self.save_as_html, "save notebook")
        
        self.addWidget(self._teditor)
        self._teditor.document().setUndoRedoEnabled(True)
        self.image_counter = 0
        self.image_dict = {}
        self.image_data_dict = {}
        
    def append_text(self, text):
        self._teditor.append(str(text))
        
    def search_for_text(self, search_text = " "):
        self._teditor.find(search_text)
        
    def clear_all(self):
        self._teditor.clear()
        self.image_dict = {}
        self.image_counter = 0
#        newdoc = QTextDocument()
#        self._teditor.setDocument(newdoc)
        
    def append_image(self, fig=None):
        #This assumes that an image is there waiting to be saved from matplotlib
        self.imgdata = StringIO.StringIO()
        if fig is None:
            pyplot.savefig(self.imgdata, transparent = False, format = img_format)
        else:
            fig.savefig(self.imgdata, transparent = False, format = img_format)
        self.abuffer = QBuffer()
        self.abuffer.open(QBuffer.ReadWrite)
        self.abuffer.write(self.imgdata.getvalue())
        self.abuffer.close()
        
        self.abuffer.open(QBuffer.ReadOnly)
        iReader = QImageReader(self.abuffer, img_format )
        the_image = iReader.read()
        # the_image = the_image0.scaledToWidth(figure_width)
        
        # save the image in a file
        imageFileName = "image" + str(self.image_counter) + "." + img_format
        self.image_data_dict[imageFileName] = self.imgdata
        
        self.image_counter +=1
        imageFormat = QTextImageFormat()
        imageFormat.setName(imageFileName)
        imageFormat.setWidth(image_width)
        self.image_dict[imageFileName] = the_image
        
        #insert the image in the text document
        text_doc = self._teditor.document()
        text_doc.addResource(QTextDocument.ImageResource, QUrl(imageFileName), the_image)
        cursor = self._teditor.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertImage(imageFormat)
        
    def add_image_data_resource(self, imgdata, imageFileName):
        
        self.abuffer = QBuffer()
        self.abuffer.open(QBuffer.ReadWrite)
        self.abuffer.write(imgdata.getvalue())
        self.abuffer.close()
        
        self.abuffer.open(QBuffer.ReadOnly)
        iReader = QImageReader(self.abuffer, img_format )
        the_image = iReader.read()
        # the_image = the_image0.scaledToWidth(figure_width)
        
        # save the image in a file
        # imageFileName = "image" + str(self.image_counter) + "." + img_format
        self.image_data_dict[imageFileName] = imgdata
        
        # self.image_counter +=1
        imageFormat = QTextImageFormat()
        imageFormat.setName(imageFileName)
        imageFormat.setWidth(image_width)
        self.image_dict[imageFileName] = the_image
        
        #insert the image in the text document
        text_doc = self._teditor.document()
        text_doc.addResource(QTextDocument.ImageResource, QUrl(imageFileName), the_image)
        
    
    def append_html_table_from_array(self, a, header_rows=0, precision = 3, caption = None, cmap = None):
        nrows = len(a)
        ncols = len(a[0])
        result_string = "<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n"
        if caption != None:
            result_string += "<caption>%s</caption>\n"  % caption
        r = 0
        while r < header_rows:
            result_string += "<tr>"
            for c in range(ncols):
                if a[r][c] != "":
                    # count following blank columns
                    count = 1
                    while ((c+count) < len(a[r])) and (a[r][c+count] == "") :
                        count += 1
                    val = a[r][c]
                    if (type(val) == numpy.float64) or (type(val) == float):  # @UndefinedVariable
                        if precision != 999:
                            val = round(val, precision)
                    if count > 1:
                        result_string +="<th colspan=%s>%s</th>"  % (count, val)
                    else:
                        result_string += "<th>%s</th>"  % val
            result_string +="</tr>\n"
            r += 1
        while r < nrows:
            result_string += "<tr>"
            for c in range(ncols):
                val = a[r][c]
                if (cmap == None):
                    fcolor = "#ffffff"
                elif (type(val) == int) or (type(val) == float) or (type(val) == numpy.float64):  # @UndefinedVariable
                    fcolor = cmap.color_from_val(val)
                else:
                    fcolor = "#ffffff"
      
                if (val != "") or (c == 0):
                    if (type(val) == numpy.float64) or (type(val) == float): # @UndefinedVariable
                        if precision != 999:
                            val = round(val, precision)
                    count = 1
                    while ((c+count) < len(a[r])) and (a[r][c+count] == "") :
                        count += 1
                    if count > 1:
                        result_string +="<td colspan=%s bgcolor=%s>%s</td>"  % (count, fcolor, val)
                    else:
                        result_string += "<td bgcolor=%s>%s</td>" % (fcolor, val)
            result_string +="</tr>\n"
            r += 1
        result_string += "</table>\n"
        self.append_text(result_string)
        
    def create_empty_string_array(self, rows, cols):
        table_array = []
        for r in range(rows): #@UnusedVariable
            the_row = []
            for c in range(cols): #@UnusedVariable
                the_row.append("")
            table_array.append(the_row)
        return table_array
    
    def recurse_on_dict_headers(self, sdict, r, c, sorted_headers = None):
        if ((type(sdict) != dict) and (type(sdict) != OrderedDict)):
            return c + 1
        else:
            if sorted_headers != None:
                sheaders = sorted_headers
            else:
                sheaders = sorted(sdict.keys())
            for k in sheaders:
                self.table_array[r][c] = k
                c = self.recurse_on_dict_headers(sdict[k], r + 1, c)
            return c
        
    def recurse_to_find_size(self, sdict, r, c):
        
        if ((type(sdict) != dict) and (type(sdict) != OrderedDict)):
            return r, c + 1
        else:
            rbiggest = r
            for k in sorted(sdict.keys()):
                rnew, c = self.recurse_to_find_size(sdict[k], r + 1, c)
                if rnew > rbiggest:
                    rbiggest = rnew
            return rbiggest, c
                
    def recurse_on_dict(self, sdict, r, c, sorted_headers = None):
        if ((type(sdict) != dict) and (type(sdict) != OrderedDict)):
            self.table_array[r][c] = sdict
            return c + 1
        else:
            if sorted_headers != None:
                sheaders = sorted_headers
            else:
                sheaders = sorted(sdict.keys())
            for k in sheaders:
                c = self.recurse_on_dict(sdict[k], r, c)
            return c

    def convert_structured_dicts_to_array(self, sdict, sorted_keys = None, sorted_headers = None):
        header_levels, ncols = self.recurse_to_find_size(sdict[sdict.keys()[0]], 0, 0)
        nrows = header_levels + len(sdict.keys())
        self.table_array = self.create_empty_string_array(nrows, ncols)
        self.recurse_on_dict_headers(sdict[sdict.keys()[0]], 0, 0, sorted_headers)
        if sorted_keys != None:
            key_list = sorted_keys
        else:
            key_list = sdict.keys()
        r = header_levels
        for entry in key_list:
            c = 0
            self.table_array[r][0] = entry
            self.recurse_on_dict(sdict[entry], r, c, sorted_headers = sorted_headers)
            r += 1
        return self.table_array
            
    def append_html_table_from_dicts(self, sdict, header_rows = 1, title = None, sorted_keys = None, precision = 3, cmap = None, sorted_headers = None):
        the_array = self.convert_structured_dicts_to_array(sdict, sorted_keys, sorted_headers = sorted_headers)
        self.append_html_table_from_array(the_array, header_rows, caption = title, precision = precision, cmap = cmap)
    
    def append_table(self, rows, cols, border_style = QTextFrameFormat.BorderStyle_Solid):
        tformat = QTextTableFormat()
        tformat.setBorderStyle(border_style)
        cursor= self._teditor.textCursor()
        cursor.movePosition(QTextCursor.End)
        table = cursor.insertTable(rows, cols, tformat)
        return table
    
    def fill_table_cell(self, row, col, table, text):
        cptr = table.cellAt(row, col).firstCursorPosition()
        cptr.insertText(text)
        
    def save_as_html(self):
        fname = QFileDialog.getSaveFileName()[0]
        fdirectoryname = os.path.dirname(fname)
        # fdirectoryname = QFileDialog.getExistingDirectory()
        # print fdirectoryname
        # fname = fdirectoryname + "/report.html"
        text_doc = self._teditor.document()
        f = open(fname, 'w')
        f.write(text_doc.toHtml())
        f.close()
        for imageFileName in self.image_dict.keys():
            full_image_path = fdirectoryname + "/" + imageFileName
            iWriter = QImageWriter(full_image_path, img_format)
            iWriter.write(self.image_dict[imageFileName])