Esempio n. 1
0
 def updateCheck(self):
     self.Nauti.checkGit()
     self._send('download', [("name", "0:/private/firmware_version")])
     loop = QEventLoop()
     getTimer = QTimer()
     self._reply.finished.connect(loop.quit)
     getTimer.singleShot(8000, loop.quit)
     loop.exec()
     if self._reply:
         reply_body = bytes(self._reply.readAll()).decode().strip()
         if len(reply_body)>0:
             newestVersion = CuraApplication.getInstance().getPreferences().getValue("Nautilus/configversion")
             if StrictVersion(newestVersion)>StrictVersion(reply_body):
                 #CuraApplication.getInstance().getPreferences().addPreference("Nautilus/uptodate","no")
                 self._onUpdateRequired()
                 NautilusUpdate.NautilusUpdate().thingsChanged()
             #self._testmess = Message(catalog.i18nc("@info:status","{} has firmware version: {}").format(self._name,reply_body))
             #self._testmess.show()
             else:
                 Logger.log('i', str(self._name) + " is up to date"+str(self.updateFlag))
                 #CuraApplication.getInstance().getPreferences().addPreference("Nautilus/uptodate","yes")
                 NautilusDuet.NautilusDuet().saveInstance(self._name, self._name, self._url, self._duet_password, self._http_user, self._http_password, reply_body)
                 sleep(.5)
                 NautilusUpdate.NautilusUpdate().thingsChanged()
                 if self.updateFlag == 0:
                     mess = Message(catalog.i18nc("@info:status",'Nautilus is up to date!'))
                     mess.show()
         else:
             Logger.log('i','timeout error')
             if self.updateFlag == 0:
                 self._onTimeout()
     else:
         Logger.log('i','unknown error')
Esempio n. 2
0
 def __run_js(self, script):
     loop = QEventLoop()
     self.asyncFinished.connect(loop.quit)
     self.__page.runJavaScript(script, self.__async_callback)
     loop.exec()
     print('run js finished')
     return self.__async_result
Esempio n. 3
0
 def no_blocking_execution(self):
     """Returns True if computation went through without exceptions"""
     q = QEventLoop()
     # -------- setup progress dialog -------- #
     progress_dialog = QProgressDialog(self.parent())
     progress_dialog.setLabelText(self.progress_text)
     progress_dialog.setCancelButtonText(None)
     if self.is_show_progress:
         progress_dialog.setRange(0, 100)
     else:
         progress_dialog.setRange(0, 0)
     self.progress_updated.connect(progress_dialog.setValue)
     progress_dialog.show()
     # --------------------------------------- #
     if self.parent():
         self.parent().setDisabled(True)
     progress_dialog.setDisabled(False)
     self.finished.connect(q.quit)
     # self.finished.connect(self._on_finished)
     self.start()
     q.exec(QEventLoop.ExcludeUserInputEvents)
     progress_dialog.hide()
     if self.parent():
         self.parent().setDisabled(False)
     return self.is_successful
Esempio n. 4
0
    def waitForFinishedOrInvalidated(self, timeout: int = -1):
        """Блокирует вызывающий метод на время, пока не будет завершено данное действие,
        или пока не истечет `timeout` миллисекунд.
        Если `timeout` меньше 0 (по умолчанию), то по таймеру блокировка отменяться не будет.
        """
        if self.isFinished():
            return

        event_loop = QEventLoop()
        self.invalidated.connect(event_loop.quit)
        self.finished.connect(event_loop.quit)
        self.destroyed.connect(event_loop.quit)
        if timeout >= 0:
            timer = QTimer()
            timer.setInterval(timeout)
            timer.setSingleShot(True)
            timer.timeout.connect(event_loop.quit)
            # Если блокировка отменится до истечения таймера, то при выходе из метода таймер остановится и уничтожится.
            timer.start()
        event_loop.exec()
        self.invalidated.disconnect(event_loop.quit)
        self.finished.disconnect(event_loop.quit)
        self.destroyed.disconnect(
            event_loop.quit
        )  # TODO: Не упадет ли прога здесь, если действие уже удалилось?
Esempio n. 5
0
    def splash_context(app=app, editor_window=editor_window):
        """
        Function context (to ensure garbage collection) for displaying the
        splash screen.
        """
        # Display a friendly "splash" icon.
        splash = AnimatedSplash(load_movie("splash_screen"))
        splash.show()
        app.processEvents()

        # Create a blocking thread upon which to run the StartupWorker and which
        # will process the events for animating the splash screen.
        initLoop = QEventLoop()
        thread = QThread()
        worker = StartupWorker()
        worker.moveToThread(thread)
        thread.started.connect(worker.run)
        worker.finished.connect(thread.quit)
        worker.finished.connect(worker.deleteLater)
        worker.display_text.connect(splash.draw_log)
        worker.failed.connect(splash.failed)
        # Stop the blocking event loop when the thread is finished.
        thread.finished.connect(initLoop.quit)
        thread.finished.connect(thread.deleteLater)
        thread.start()
        initLoop.exec()  # start processing the pending StartupWorker.
        splash.finish(editor_window)
        splash.deleteLater()
Esempio n. 6
0
 def get_body(self):
     """ Return the current DOM as HTML. """
     loop = QEventLoop()
     self.asyncFinished.connect(loop.quit)
     self.__page.toHtml(self.__async_callback)
     loop.exec()
     return self.__async_result
Esempio n. 7
0
        class Render(QWebEngineView):
            def __init__(self, url):
                QWebEngineView.__init__(self)
                self.loop = QEventLoop(
                )  #Queda en un loop hasta que acaba la carga de todas las páginas
                self.loadFinished.connect(self._loadFinished)
                self.pages = []
                self.page().profile().cookieStore().deleteAllCookies()
                self.page().profile().setPersistentCookiesPolicy(
                    QWebEngineProfile.NoPersistentCookies)
                self.load(QUrl(url))
                self.loop.exec()

            def numPages(self):
                return len(self.pages)

            def _loadFinished(self, result):
                """
                   This is an async call, you need to wait for this to be called before closing the app
                """
                self.page().toHtml(self._callable)

            def _callable(self, data):
                """
                   Se llama cada vez que una página es cargada con el html en data
                """
                time.sleep(0.25)
                self.pages.append(data)
                self.loop.quit()  #CUIDADO DEBE ESTAR EN EL ULTIMO
Esempio n. 8
0
class QSignalWait(QObject):
    """
    Class that waits for a QTSignal and returns its value
    Works only with signals with no type or type int,str,bool
    """
    def __init__(self, signal, parent=None):
        super(QSignalWait, self).__init__(parent)
        self.state = None
        self.signal = signal
        self.loop = QEventLoop()

    @pyqtSlot()
    @pyqtSlot(bool)
    @pyqtSlot(str)
    @pyqtSlot(int)
    def _quit(self, state=None):
        self.state = state
        self.loop.quit()

    def wait(self):
        """Waits for a signal to be emitted.
        """
        self.signal.connect(self._quit)
        self.loop.exec()
        self.signal.disconnect(self._quit)
        return self.state
Esempio n. 9
0
 def _loadPage(self):
     html_path = self._get_page_path()
     # QEventLoop is used to make the page loading behave syncronously
     init_loop = QEventLoop()
     self._page.loadFinished.connect(init_loop.quit)
     self._page.load(QUrl().fromLocalFile(html_path))
     init_loop.exec()
Esempio n. 10
0
    def _runAll(self):
        windowCollector = WindowCollector()
        loop = QEventLoop()

        for row in dataChangeIterator(processEventsIterator(self.model),
                                      self.model, self.model.COL_PID,
                                      self.model.COL_WID):  # type: BaseRow

            if not self._isStarting:
                return

            process = self._runProcess(row)
            self._processes.append(process)

            self.baseWindow.show()
            self.baseWindow.raise_()

            QTimer.singleShot(videoSettings.VLC_SLEEP_TIME_LLmsJJ, loop.quit)
            loop.exec()

            row.pid = process.pid
            row.wid = windowCollector.getNewWindowId()

            self.resizeAndMove(row)
            self.onPause(True, process)

        self.baseWindow.raise_()
Esempio n. 11
0
        def decorator(*args, **kwargs):
            qobj = args[0] if is_qt_method else None
            result, exception = None, None
            loop = QEventLoop()
            progress = ProgressWindow(parent=qobj,
                                      window_title=window_title,
                                      label_text=label_text)

            class Thread(QtCore.QThread):
                def run(self):
                    nonlocal result, exception
                    try:
                        result = func(*args, **kwargs)
                    except Exception as e:
                        exception = e

            task = Thread()
            task.finished.connect(progress.close)
            task.finished.connect(loop.exit)

            with disabled(qobj, enable=disable, except_objs=[progress]):
                progress.show()
                task.start()
                loop.exec()

            if exception is not None:
                raise exception

            return result
Esempio n. 12
0
def get_content(url, is_json=True):

    content_requests = ""

    # Get content
    networkAccessManager = QNetworkAccessManager()
    req = QNetworkRequest(QUrl(url))

    # Set JSON headers
    if is_json:
        headers = {
            'Content-Type': 'application/json;charset=UTF-8',
            'Access-Control-Allow-Origin': '*'
        }
        req.setHeader(QNetworkRequest.ContentTypeHeader, headers)

    reply = networkAccessManager.get(req)
    event = QEventLoop()
    reply.finished.connect(event.quit)
    event.exec()

    # Capture errors
    er = reply.error()
    if er == QNetworkReply.NoError:
        bytes_string = reply.readAll()
        if is_json:
            content_requests = json.loads(str(bytes_string, 'utf-8'))
        else:
            content_requests = bytes_string.data().decode('utf8')

    return content_requests
Esempio n. 13
0
    def startGet(self, widgets=None):
        """主要用于请求图片。"""
        # currentUlr用于比较,因为是多线程,有两个线程在调用这个函数,
        # 如果两次请求是相同的url,就不会再次请求了。
        if self.currentUrl == len(self.url):
            return

        self.finished.connect(
            lambda: self.dataInResult(data, widgets, names, index, loop))

        # 进行标记,存储上一次的状态。
        self.currentUrl = len(self.url)
        # 该标记表示此函数处于工作中。
        self.picFinished = False

        try:
            cacheList = os.listdir('cache')
        except:
            os.mkdir('cache')
            cacheList = os.listdir('cache')

        # self.offset一次30,但有可能在两次都没加载完时做了两次下拉,这样剩余的url其实是60个,
        # 那么就要进行60次。
        # 应该用while 循环做成类似线程池的模式。
        # 暂时先不改了,不是最紧急的。
        for i in range(len(self.url[self.offset:])):
            index = i + self.offset
            # 检测有没有进行了缓存,有的话就不会再次请求了。
            # 歌单id + 后缀。
            # names = str(self.parent.singIds[index]) + self.url[index][self.url[index].rfind('.'):]
            names = str(self.url[index][self.url[index].rfind('/') + 1:])
            if names in cacheList:
                if widgets:
                    widgets[index].setStyleSheets(
                        "QLabel#picLabel{border-image: url(cache/%s)}" %
                        (names))
            else:
                # 没有缓存,继续进行请求并添加到缓存。
                loop = QEventLoop()
                req = QNetworkRequest(QUrl(self.url[index]))
                # 原以为不是keep-alive,抓包后发现是keep-alive。
                # 但是感觉请求的还是不快啊。
                # req.setRawHeader(QByteArray("Connection"), QByteArray('keep-alive'))
                data = self.get(req)
                loop.exec()

        # 请求完成后清理缓存,已经保存到本地。
        self.clearCache()

        # 历史遗留问题,暂时不改。
        try:
            self.finished.disconnect()
        except:
            print(1)

        self.offset += 30
        # 发出全部完成的信号。

        self.allFinished.emit()
Esempio n. 14
0
 def _loadPage(self):
     html_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                              'web', 'map.html')
     # QEventLoop is used to make the page loading behave syncronously
     init_loop = QEventLoop()
     self._page.loadFinished.connect(init_loop.quit)
     self._page.load(QUrl().fromLocalFile(html_path))
     init_loop.exec()
Esempio n. 15
0
 def left_click(self):
     """ Left clicks the current node, then waits for the page to fully load. """
     loop = QEventLoop()
     self.__parent._qt_invocation.async_js_finished.connect(loop.quit)
     self.__run_js(
         Utils.qt_js_prepare('Qt.click("{0}")').format(self.node_id))
     loop.exec()
     print('after click')
Esempio n. 16
0
 def wwwUpload(self):
     self._streamer.seek(0)
     self._posterData = QByteArray()
     self._posterData.append(self._streamer.getvalue())
     self._send('upload', [("name", "0:/www/"+self._fileName), self._timestamp()], self.onMacUploadDone(), self._posterData) #write onUpdateDone
     loop = QEventLoop()
     self._reply.finished.connect(loop.quit)
     loop.exec()
Esempio n. 17
0
    def take_screenshot(flags):
        loop = QEventLoop()
        screen_shot = Screenshot(flags)
        screen_shot.show()
        screen_shot.widget_closed.connect(loop.quit)

        loop.exec()
        img = screen_shot.target_img
        return img
Esempio n. 18
0
 def left_click(self, x, y):
     print('start click event loop')
     loop = QEventLoop()
     pos = QPoint(x, y)
     self.__press(pos)
     QTimer.singleShot(300, lambda: self.__release(pos))
     QTimer.singleShot(800, loop.quit)
     loop.exec()
     print('end click event loop')
Esempio n. 19
0
 def fuzz(self):
     loop = QEventLoop()
     for request in self.fuzzer.requests(PAYLOADS):
         self.webView.loadFinished.connect(loop.quit)
         self.webView.load(request)
         loop.exec()
         self.webView.page().toHtml(self.detect_xss)
         if self.stopLoop:
             break
Esempio n. 20
0
    def piece_glide(self, piece, dst_index):
        piece.raise_()
        dst_square = self.findChild(QWidget, common.index_to_san[dst_index])
        self.glide = QPropertyAnimation(piece, b'pos')
        self.glide.setDuration(500)
        self.glide.setEndValue(dst_square.pos())
        self.glide.start()

        # Start local event loop, so program waits until glide is completed
        loop = QEventLoop()
        self.glide.finished.connect(loop.quit)
        loop.exec()
Esempio n. 21
0
    def macroUpload(self):
        Logger.log('i','time to upload the macro')
        #if self._stage != OutputStage.writing:
        #    return

        Logger.log("d", self._name_id + " | Uploading... | "+str(self._fileName))
        self._streamer.seek(0)
        self._posterData = QByteArray()
        self._posterData.append(self._streamer.getvalue().encode())
        self._send('upload', [("name", "0:/macros/" + self._fileName), self._timestamp()], self.onMacUploadDone(), self._posterData)
        loop = QEventLoop()
        self._reply.finished.connect(loop.quit)
        loop.exec()
Esempio n. 22
0
    def get_from_url(self, url, _token):
        """
        Get a file from given URL.

        Parameters:
            param1 (string): The url to call. Either an empty string or an url.
            This is used to make a call to a specific url.

            param2 (string): Token for the Flyfotos service. Used for getting the GetCapabilities file.


        Returns:
            (string): Returns file as string if the call was successful.

        """
        req = ""
        networkAccessManager = QNetworkAccessManager()

        if len(url) > 1:
            req = QNetworkRequest(QUrl(url))
        else:
            turl = str((tokenUrl % _token) +
                       "&request=GetCapabilities&service=WMS")
            req = QNetworkRequest(
                QUrl(turl))

        reply = networkAccessManager.get(req)
        event = QEventLoop()
        reply.finished.connect(event.quit)
        event.exec()
        er = reply.error()

        if er == QNetworkReply.NoError:
            bytes_string = reply.readAll()
            content_requests = bytes_string.data().decode('utf8')
            # Hide error message from plugin, if user's token is correct
            self.label_error_message.hide()
            if len(str(content_requests)) > 0:
                return content_requests
            else:
                self.errorBox(
                    "Something went wrong, the query content length was 0. Check if the token is correct.")
        else:
            self.errorBox(
                "Something went wrong. Check if the token is correct.")
            # Show error message label on plugin, if user's token is wrong
            self.label_error_message.show()
            self.clear_model_visible()
            self.clear_model_all()
            print(
                'http error {} - No content. Please check your token is correct'.format(er))
Esempio n. 23
0
    def send_request(self, post=None, data={}):
        loop = QEventLoop()
        self.r.setUrl(self.url)
        if post:
            encoded_data = self._urlencode_post_data(data)
            pprint(encoded_data)
            self.reply_post = self.conn.post(self.r, encoded_data)
            self.reply_post.downloadProgress.connect(self.prepare_responce)

        else:
            self.reply = self.conn.get(self.r)
            self.reply.finished.connect(self.prepare_responce)
        # return \
        loop.exec()
Esempio n. 24
0
 def __navigation_requested(self):
     print('navvvvvvvvvvvvv', self.__loading)
     if not self.__loading:
         self.__loading = True
         print('navigation event loop started')
         loop = QEventLoop()
         self.__page.loadFinished.connect(loop.quit)
         loop.exec()
         print('navigation event loop ended')
         loop_js = QEventLoop()
         self._qt_invocation.js_ready.connect(loop_js.quit)
         self.__register_js()
         loop_js.exec()
         self.__loading = False
         print('js register event loop ended')
    def download(self, url: str, path: Path):
        url = QUrl(url)
        req = QNetworkRequest(url)

        worker_loop = QEventLoop(self)
        reply = self._nam.get(req)
        reply.finished.connect(worker_loop.quit)
        reply.downloadProgress.connect(self._download_update)
        worker_loop.exec()

        qbytes = reply.readAll()  # type: QByteArray
        with path.open("wb") as file:
            file.write(qbytes.data())

        self.finished.emit()
Esempio n. 26
0
def run_js_code(page: QWebEnginePage, code: str) -> object:
    loop = QEventLoop()

    result_value = {'value': None}

    def _on_callback(result: object):
        result_value['value'] = result

        loop.quit()

    page.runJavaScript(code, _on_callback)

    loop.exec()

    return result_value['value']
Esempio n. 27
0
def threadExecutionDec(fun, *args, **kwargs):
    loop = QEventLoop()
    thread = QThread()
    thread.start()

    worker = Worker(fun, *args, **kwargs)
    worker.moveToThread(thread)
    worker.start.connect(worker.run)
    worker.end.connect(loop.exit)
    worker.end.connect(thread.exit)

    worker.start.emit()
    loop.exec()
    del thread

    return worker.result
Esempio n. 28
0
    def _search_cover_image(self, artist_name, album_name):
        search_widget = cover_search_widget(artist_name, album_name)
        search_widget.setWindowFlags(Qt.Tool)  # Tool window is alywas on top.
        search_widget.show()

        loop = QEventLoop()
        search_widget.canceled.connect(loop.quit)
        search_widget.finished.connect(loop.quit)
        search_widget.result.connect(self._save_searched_cover)
        self.begin_search.emit()
        search_widget.search()
        loop.exec()
        self.end_search.emit()

        if os.path.exists(self._cover_file_path):
            pixmap = QPixmap(self._cover_file_path)
            self._set_cover(pixmap)
Esempio n. 29
0
 def go_to(self, url: Union[QUrl, str]) -> bool:
     """ Goes to a given URL. """
     url = QUrl(url)
     if self.base_url:
         url = self.base_url.resolved(url)
     loop = QEventLoop()
     self.__page.loadFinished.connect(loop.exit)
     self.__page.load(url)
     return True if loop.exec() else False
Esempio n. 30
0
    def wrong_start_or_end(
            self):  # функция, выводящая ошибку, если что-то не так с секундами
        self.wrong_start.setStyleSheet(
            "color:rgb(0, 0, 0)")  # строчка становится видна
        self.wrong_start.setStyleSheet("background-color:rgb(255, 68, 68)")
        self.wrong_start.setText(
            'Введеные Вами данные не соответствуют формату. Повторите ввод')
        self.wrong_start.move(40, 235)

        loop = QEventLoop()  # создается задержка
        QTimer.singleShot(
            3000, loop.quit
        )  # первый параметр - время задержки, указывается в милисек.
        loop.exec()

        self.wrong_start.setStyleSheet(
            "color:rgb(246, 246, 246)")  # строчка перестает быть видна
        self.wrong_start.setText(
            'Введеные Вами данные не соответствуют формату. Повторите ввод')
        self.wrong_start.move(40, 235)
Esempio n. 31
0
class Ace(QWebView):
    """ Embbeded Ace javascript web editor """
    
    isReady = pyqtSignal(name='isReady')
    modificationChanged = pyqtSignal(bool)
    cursorPositionChanged = pyqtSignal(int, int, name='cursorPositionChanged')
    
    def __init__(self, file_info, parent=None):
        super(Ace, self).__init__(parent)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.parent = parent
        self.file_info = file_info
        self.language = EditorHelper.lang_from_file_info(file_info)
        self.waitForReady = False
        self.loop = QEventLoop()
        
        settings = self.settings()
        settings.setAttribute(QWebSettings.JavascriptCanAccessClipboard, True)
        settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
        self.inspector = QWebInspector(self)
        showInspectorAction = QAction('showInspector', self)
        showInspectorAction.triggered.connect(self.showInspector)
        self.addAction(showInspectorAction)
        
        self.modificationChanged.connect(self.modification_changed)
        self.main_frame().javaScriptWindowObjectCleared.connect(self.__self_js)
        pckg, file_name = 'ace_editor', 'ace_editor.html'
        resource = pkg_resources.resource_string(pckg, file_name)
        html_template = str(resource, 'utf-8')
        #insert file content
        with open(self.file_info.absoluteFilePath(), 'r') as f:
            text = f.read()
            text = html.escape(text)
            html_template = html_template.replace('{{ content }}', text)
        base_url = QUrl.fromLocalFile(os.path.dirname(__file__))
        
        self.setHtml(html_template, base_url)
        self.modified = False
        
        if not self.waitForReady:
            self.loop.exec()
    
    @pyqtSlot(str, name='test', result=str)
    @EditorHelper.json_dumps
    def test(self, prefix):
        print(prefix)
        return ['plop', 'cool', 42, {'plop':23}]
    
    def modification_changed(self, b):
        self.modified = b
    
    def save(self, parent, action=None):
        Alter.invoke_all('editor_presave', self)
        if self.modified:
            with open(self.file_info.absoluteFilePath(), 'w') as f:
                f.write(self.get_value())
            self.original_to_current_doc()
            self.modificationChanged.emit(False)
            parent.status_bar.showMessage(self.tr("Saved file."))
            Alter.invoke_all('editor_save', self)
        else :
            parent.status_bar.showMessage(self.tr("Nothing to save."))
    
    def toggle_hidden(self, parent, action=None):
        self.set_show_invisibles(action.isChecked())
    
    def toggle_soft_tabs(self, parent, action=None):
        self.set_use_soft_tabs(action.isChecked())
    
    def main_frame(self):
        """ Convinient function to get main QWebFrame """
        return self.page().mainFrame()
    
    def send_js(self, script):
        """ Convinient function to send javascript to ace editor """
        return self.main_frame().evaluateJavaScript(script)

    def __self_js(self):
        self.main_frame().addToJavaScriptWindowObject('AceEditor', self)
    
    @pyqtSlot(name='isReady')
    def editor_ready(self):
        if self.language != None:
            self.set_mode(self.language.lower())
        self.set_focus()
        if self.loop.isRunning():
            self.loop.quit()
        self.waitForReady = True
    
    def showInspector(self):
        self.dialogInspector = QDialog(self)
        self.dialogInspector.setLayout(QVBoxLayout())
        self.dialogInspector.layout().addWidget(self.inspector)
        self.dialogInspector.setModal(False)
        self.dialogInspector.show()
    
    def original_to_current_doc(self):
        self.send_js('editor.orignalToCurrentDoc()')
    
    def get_value(self):
        return self.send_js('editor.getValue()')
    
    def set_value(self, content):
        self.send_js('editor.setValue("{0}")'.format(content))
    
    def set_focus(self):
        self.send_js('editor.focus()')
    
    def insert(self, text):
        self.send_js('editor.insert("{0}")'.format(text))
    
    def set_mode(self, language):
        cmd = 'editor.getSession().setMode("ace/mode/{0}")'
        self.send_js(cmd.format(language))
    
    def set_theme(self, theme):
        self.send_js('editor.setTheme("ace/theme/{0}")'.format(theme))
    
    def get_selected_text(self):
        cmd = 'editor.session.getTextRange(editor.getSelectionRange())'
        return self.send_js(cmd)
    
    def get_cursor(self):
        cmd = 'editor.selection.getCursor()'
        return self.send_js(cmd)
    
    def got_to_line(self, line):
        cmd = 'editor.gotoLine({0})'
        self.send_js(cmd.format(line))
    
    def get_length(self):
        return self.send_js('editor.session.getLength()');
    
    def set_tab_size(self, tab_size):
        self.send_js('editor.getSession().setTabSize({0})'.format(tab_size))
    
    def get_tab_size(self):
        return self.send_js('editor.getSession().getTabSize()')
    
    def set_use_soft_tabs(self, b):
        b = 'true' if b else 'false'
        self.send_js('editor.getSession().setUseSoftTabs({0})'.format(b))
    
    def set_font_size(self, font_size):
        cmd = "document.getElementById('editor').style.fontSize='{0}px'"
        self.send_js(cmd.format(font_size))
    
    def set_use_wrap_mode(self, b):
        b = 'true' if b else 'false'
        cmd = "editor.getSession().setUseWrapMode({0})"
        self.send_js(cmd.format(b))
    
    def set_highlight_active_line(self, b):
        b = 'true' if b else 'false'
        cmd = "editor.setHighlightActiveLine({0})"
        self.send_js(cmd.format(b))
    
    def set_show_print_margin(self, b):
        b = 'true' if b else 'false'
        cmd = "editor.setShowPrintMargin({0})"
        self.send_js(cmd.format(b))
    
    def set_read_only(self, b):
        b = 'true' if b else 'false'
        self.send_js('editor.setReadOnly({0})'.format(b))
    
    def set_show_invisibles(self, b):
        b = 'true' if b else 'false'
        self.send_js('editor.setShowInvisibles({0})'.format(b))