def doLayout(self, rect, testOnly): x = rect.x() y = rect.y() lineHeight = 0 for item in self.itemList: wid = item.widget() spaceX = self.spacing() + wid.style().layoutSpacing( QtWidgets.QSizePolicy.PushButton, QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Horizontal) spaceY = self.spacing() + wid.style().layoutSpacing( QtWidgets.QSizePolicy.PushButton, QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Vertical) nextX = x + item.sizeHint().width() + spaceX if nextX - spaceX > rect.right() and lineHeight > 0: x = rect.x() y = y + lineHeight + spaceY nextX = x + item.sizeHint().width() + spaceX lineHeight = 0 if not testOnly: item.setGeometry( QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint())) x = nextX lineHeight = max(lineHeight, item.sizeHint().height()) return y + lineHeight - rect.y()
def set_top_geometry(self, geometry): top = self.c.frame.top widget = getattr(top, 'leo_master', None) or top if isinstance(geometry, QtCore.QRect): widget.setGeometry(geometry) else: x, y, w, h = geometry widget.setGeometry(QtCore.QRect(x, y, w, h))
def show_tip(self, action): """show_tip - show a tooltip, calculate the box in which the pointer must stay for the tip to remain visible :Parameters: - `self`: this handle - `action`: action triggering event to display """ if action.toolTip() == action.text(): tip = "" else: tip = action.toolTip() pos = QtGui.QCursor.pos() x = pos.x() y = pos.y() rect = QtCore.QRect(x - 5, y - 5, x + 5, y + 5) QtWidgets.QToolTip.showText(pos, tip, action.parentWidget(), rect)
def show_tip(self, action): """show_tip - show a tooltip, calculate the box in which the pointer must stay for the tip to remain visible :Parameters: - `self`: this handle - `action`: action triggering event to display """ if action.toolTip() == action.text(): tip = "" else: tip = action.toolTip() pos = QtGui.QCursor.pos() x = pos.x() y = pos.y() rect = QtCore.QRect(x - 5, y - 5, x + 5, y + 5) if hasattr(action, 'parentWidget'): # 2021/07/17. parent = action.parentWidget() else: return if not parent: g.trace('===== no parent =====') return QtWidgets.QToolTip.showText(pos, tip, parent, rect)
def heightForWidth(self, width): height = self.doLayout(QtCore.QRect(0, 0, width, 0), True) return height
def __init__(self, c, title='Z-editor'): # pylint: disable=too-many-locals global TAB2SPACES super().__init__() QWidget().__init__() self.c = c self.p = c.p self.v = c.p.v self.host_id = c.p.gnx w = c.frame.body.wrapper self.host_editor = w.widget self.switching = False self.closing = False self.reloadSettings() # The rendering pane can be either a QWebView or a QTextEdit # depending on the features desired if not QWebView: # Until Qt6 has a QWebEngineView, force QTextEdit self.render_pane_type = NAV_VIEW if self.render_pane_type == NAV_VIEW: self.render_widget = QTextEdit else: self.render_widget = QWebView self.render_pane_type = BROWSER_VIEW self.editor = QTextEdit() browser = self.browser = self.render_widget() wrapper = qt_text.QTextEditWrapper(self.editor, name='zwin', c=c) c.k.completeAllBindingsForWidget(wrapper) #@+<<set stylesheet paths>> #@+node:tom.20210604170628.1: *4* <<set stylesheet paths>> self.editor_csspath = '' self.rst_csspath = '' home = g.app.loadManager.computeHomeDir() cssdir = osp_join(home, '.leo', 'css') #dict_ = g.app.loadManager.globalSettingsDict #is_dark = dict_.get_setting('color-theme-is-dark') is_dark = is_body_dark(self.c) if is_dark: self.editor_csspath = osp_join(cssdir, EDITOR_STYLESHEET_DARK_FILE) self.rst_csspath = osp_join(cssdir, RST_CUSTOM_STYLESHEET_DARK_FILE) else: self.editor_csspath = osp_join(cssdir, EDITOR_STYLESHEET_LIGHT_FILE) self.rst_csspath = osp_join(cssdir, RST_CUSTOM_STYLESHEET_LIGHT_FILE) if g.isWindows: self.editor_csspath = self.editor_csspath.replace('/', '\\') self.rst_csspath = self.rst_csspath.replace('/', '\\') else: self.editor_csspath = self.editor_csspath.replace('\\', '/') self.rst_csspath = self.rst_csspath.replace('\\', '/') #@-<<set stylesheet paths>> #@+<<set stylesheets>> #@+node:tom.20210615101103.1: *4* <<set stylesheets>> # Check if editor stylesheet file exists. If so, # we cache its contents. if exists(self.editor_csspath): with open(self.editor_csspath, encoding=ENCODING) as f: self.editor_style = f.read() else: self.editor_style = EDITOR_STYLESHEET_DARK if is_dark \ else EDITOR_STYLESHEET_LIGHT # If a stylesheet exists for RsT, we cache its contents. self.rst_stylesheet = None if exists(self.rst_csspath): with open(self.rst_csspath, encoding=ENCODING) as f: self.rst_stylesheet = f.read() else: self.rst_stylesheet = RST_STYLESHEET_DARK if is_dark \ else RST_STYLESHEET_LIGHT #@-<<set stylesheets>> #@+<<set up editor>> #@+node:tom.20210602172856.1: *4* <<set up editor>> self.doc = self.editor.document() self.editor.setWordWrapMode(WrapMode.WrapAtWordBoundaryOrAnywhere) # pylint: disable=no-member # Adjust editor stylesheet color to match body fg, bg fg, bg = get_body_colors(self.c) css = change_css_prop(self.editor_style, 'color', fg) css = change_css_prop(css, 'background', bg) self.editor_style = css self.editor.setStyleSheet(css) colorizer = leoColorizer.make_colorizer(c, self.editor) colorizer.highlighter.setDocument(self.doc) # Try to get tab width from the host's body # Used when writing edits back to host # "tabwidth" directive ought to be in first six lines lines = self.p.v.b.split('\n', 6) for line in lines: if line.startswith('@tabwidth') and line.find(' ') > 0: tabfield = line.split()[1] TAB2SPACES = abs(int(tabfield)) break # Make tabs line up with 4 spaces (at least approximately) self.editor.setTabStopDistance(TABWIDTH) if self.render_pane_type == NAV_VIEW: # Different stylesheet mechanism if we are a QTextEdit stylesheet = RST_STYLESHEET_DARK if is_dark else RST_STYLESHEET_LIGHT browser.setReadOnly(True) browser_doc = browser.document() browser_doc.setDefaultStyleSheet(stylesheet) #@-<<set up editor>> #@+<<set up render button>> #@+node:tom.20210602173354.1: *4* <<set up render button>> self.render_button = QPushButton("Rendered <--> Plain") self.render_button.clicked.connect(self.switch_and_render) b_style = RENDER_BTN_STYLESHEET_DARK if is_dark \ else RENDER_BTN_STYLESHEET_LIGHT self.render_button.setStyleSheet(b_style) #@-<<set up render button>> #@+<<build central widget>> #@+node:tom.20210528235126.1: *4* <<build central widget>> self.stacked_widget = QStackedWidget() self.stacked_widget.insertWidget(EDITOR, self.editor) self.stacked_widget.insertWidget(BROWSER, self.browser) layout = QVBoxLayout() layout.addWidget(self.render_button) layout.addWidget(self.stacked_widget) layout.setContentsMargins(0, 0, 0, 0) self.central_widget = central_widget = QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) #@-<<build central widget>> #@+<<set geometry>> #@+node:tom.20210528235451.1: *4* <<set geometry>> Y_ = Y + (len(instances) % 10) * DELTA_Y self.setGeometry(QtCore.QRect(X, Y_, W, H)) #@-<<set geometry>> #@+<<set window title>> #@+node:tom.20210531235412.1: *4* <<set window title>> # Show parent's title-->our title, our gnx ph = '' parents_ = list(c.p.parents()) if parents_: ph = parents_[0].h + '-->' self.setWindowTitle(f'{ph}{c.p.h} {c.p.gnx}') #@-<<set window title>> self.render_kind = EDITOR self.handlers = [('idle', self.update)] self._register_handlers() self.current_text = c.p.b self.editor.setPlainText(self.current_text) # Load docutils without rendering anything real # Avoids initial delay when switching to RsT the first time. if got_docutils: dummy = publish_string('dummy', writer_name='html').decode(ENCODING) self.browser.setHtml(dummy) central_widget.keyPressEvent = self.keyPressEvent self.show()