class PythonEditor(QDialog): def __init__(self): super(PythonEditor, self).__init__() self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setContentsMargins(0,0,0,0) self.tab_list = TabListView() self.side_list = SideListView() self.input = Editor() self.input.setFrameShape(QFrame.NoFrame) # self.input.setLineWidth(0) # self.input.setContentsMargins(0,0,0,0) self.output = Terminal() self.output.setFrameShape(QFrame.NoFrame) # self.output.setLineWidth(0) # self.output.setContentsMargins(0,0,0,0) # dock = QDockWidget(self) # dock.setWidget self.right_widget = QWidget() # dialog.left_widget.frameGeometry() # rect = dialog.right_widget.frameGeometry() # rect.adjusted(-10,0,0,0) # dialog.right_widget.setGeometry(rect.adjusted(-5,0,0,0)) self.right_widget.setContentsMargins(0,0,0,0) self.right_widget.setLayout(QVBoxLayout(self.right_widget)) layout = self.right_widget.layout() # layout.setMargin(0) # layout.setSpacing(0) layout.setContentsMargins(1,0,1,0) layout.addWidget(self.side_list) self.left_widget = QWidget() self.left_widget.setContentsMargins(0,0,0,0) self.left_widget.setLayout(QVBoxLayout(self.left_widget)) layout = self.left_widget.layout() # layout.setMargin(0) layout.setSpacing(0) layout.setContentsMargins(0,0,0,0) layout.addWidget(self.output) layout.addWidget(self.tab_list) layout.addWidget(self.input) self.setLayout(QHBoxLayout(self)) layout = self.layout() layout.setContentsMargins(0,0,0,0) layout.addWidget(self.left_widget) layout.addWidget(self.right_widget) # layout = dialog.layout() # layout.insertStretch( -1, 1 ) layout.setSpacing(0)
def new_button(self): i = self.currentIndex() + 1 e = Editor() self.insertTab(i, e, '') b = QtWidgets.QToolButton() b.editor = e b.clicked.connect(self.close_tab) self.tabs.append(b) b.setText('x') l = QtWidgets.QLabel('Widget') self.tabs.append(l) tb = self.tabBar() tb.setTabButton(i, QtWidgets.QTabBar.RightSide, b) tb.setTabButton(i, QtWidgets.QTabBar.LeftSide, l)
""" tab = Tab() for key, value in data.items(): tab[key] = value pprint(tab.__dict__) """ tabs.setCurrentIndex(i) w = QtWidgets.QWidget() l = QtWidgets.QVBoxLayout(w) w.setLayout(l) l.addWidget(tabs) s = QtWidgets.QStackedWidget() #s.addWidget('a') #editor = PythonEditor.ui.editor.Editor() editor = Editor() editor = QtWidgets.QPlainTextEdit() @QtCore.Slot(int) def set_editor_contents(index): data = tabs.tabData(index) text = data['text'] if text is None or not text.strip(): path = data.get('path') if path is None: raise Exception('editor with no text and no path!') if not os.path.isfile(path): raise Exception('editor with no text and invalid path!') with open(path, 'r') as f:
def add_widgets(self): self.menubar = QMenuBar() file_menu = self.menubar.addMenu('&File') preview_autosave_action = QAction(self) preview_autosave_action.setText('Preview Autosave') preview_autosave_action.triggered.connect(self.preview_autosave) file_menu.addAction(preview_autosave_action) self.output = QTextEdit() self.output.setReadOnly(True) self.top_widget = QWidget() self.top_widget.setLayout(QVBoxLayout(self.top_widget)) top_layout = self.top_widget.layout() top_layout.setSpacing(0) top_layout.setContentsMargins(0, 0, 0, 0) top_layout.addWidget(self.output) self.bar = Bar() self.new_tab_button = QToolButton() self.new_tab_button.setText('+') self.combo = Combo() self.tab_widget = QWidget() self.tab_widget.setLayout(QHBoxLayout(self.tab_widget)) tab_layout = self.tab_widget.layout() tab_layout.setSpacing(0) tab_layout.setContentsMargins(0, 0, 0, 0) tab_layout.addWidget(self.bar) tab_layout.addWidget(self.new_tab_button) tab_layout.addWidget(self.combo) self.editor = Editor() self.list_view = QListView() self.editor_splitter = QSplitter(Qt.Horizontal) self.editor_splitter.addWidget(self.editor) self.editor_splitter.addWidget(self.list_view) self.editor_splitter.setStretchFactor(0, 1) self.editor_splitter.setStretchFactor(1, 0) self.bottom_widget = QWidget() self.bottom_widget.setLayout(QVBoxLayout(self.bottom_widget)) bottom_layout = self.bottom_widget.layout() bottom_layout.setSpacing(0) bottom_layout.setContentsMargins(0, 0, 0, 0) bottom_layout.addWidget(self.tab_widget) bottom_layout.addWidget(self.editor_splitter) bottom_layout.setStretchFactor(self.editor_splitter, 100) self.statusbar = StatusBar() self.splitter = QSplitter(Qt.Vertical) self.splitter.addWidget(self.top_widget) self.splitter.addWidget(self.bottom_widget) self.setLayout(QVBoxLayout(self)) main_layout = self.layout() main_layout.setSpacing(0) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(self.menubar) main_layout.addWidget(self.splitter) main_layout.addWidget(self.statusbar)
class Dialog(QWidget): def __init__(self, parent=None): super(Dialog, self).__init__(parent=parent) if parent is None: self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setWindowTitle('Python Editor') # self.setFont(QFont('Deja Sans Mono')) # FIXME: check if font exists self.setFont(QFont('Consolas')) self.add_widgets() self.load() self.connect_signals() self.restore_state() def add_widgets(self): self.menubar = QMenuBar() file_menu = self.menubar.addMenu('&File') preview_autosave_action = QAction(self) preview_autosave_action.setText('Preview Autosave') preview_autosave_action.triggered.connect(self.preview_autosave) file_menu.addAction(preview_autosave_action) self.output = QTextEdit() self.output.setReadOnly(True) self.top_widget = QWidget() self.top_widget.setLayout(QVBoxLayout(self.top_widget)) top_layout = self.top_widget.layout() top_layout.setSpacing(0) top_layout.setContentsMargins(0, 0, 0, 0) top_layout.addWidget(self.output) self.bar = Bar() self.new_tab_button = QToolButton() self.new_tab_button.setText('+') self.combo = Combo() self.tab_widget = QWidget() self.tab_widget.setLayout(QHBoxLayout(self.tab_widget)) tab_layout = self.tab_widget.layout() tab_layout.setSpacing(0) tab_layout.setContentsMargins(0, 0, 0, 0) tab_layout.addWidget(self.bar) tab_layout.addWidget(self.new_tab_button) tab_layout.addWidget(self.combo) self.editor = Editor() self.list_view = QListView() self.editor_splitter = QSplitter(Qt.Horizontal) self.editor_splitter.addWidget(self.editor) self.editor_splitter.addWidget(self.list_view) self.editor_splitter.setStretchFactor(0, 1) self.editor_splitter.setStretchFactor(1, 0) self.bottom_widget = QWidget() self.bottom_widget.setLayout(QVBoxLayout(self.bottom_widget)) bottom_layout = self.bottom_widget.layout() bottom_layout.setSpacing(0) bottom_layout.setContentsMargins(0, 0, 0, 0) bottom_layout.addWidget(self.tab_widget) bottom_layout.addWidget(self.editor_splitter) bottom_layout.setStretchFactor(self.editor_splitter, 100) self.statusbar = StatusBar() self.splitter = QSplitter(Qt.Vertical) self.splitter.addWidget(self.top_widget) self.splitter.addWidget(self.bottom_widget) self.setLayout(QVBoxLayout(self)) main_layout = self.layout() main_layout.setSpacing(0) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.addWidget(self.menubar) main_layout.addWidget(self.splitter) main_layout.addWidget(self.statusbar) def load(self): self.model = EditorModel() self.model.populate() self.combo.setModel(self.model) self.bar.setModel(self.model) self.list_view.setModel(self.model) def connect_signals(self): self.combo.currentIndexChanged.connect(self.bar.setCurrentIndex) self.bar.tab_changed.connect(self.set_editor_contents) self.bar.tab_changed.connect(self.show_tab_status) self.bar.tab_changed.connect(self.model.set_current_uid) self.bar.close_uid_signal.connect( self.model.handle_entry_remove_request) self.editor.text_changed_signal.connect(self.update_text_in_model) self.bar.tabMoved.connect(self.model.swap_rows) def restore_state(self): uid = self.model.current_uid() self.bar.set_tab_by_uid(uid) @Slot(uuid.UUID) def set_editor_contents(self, uid): self.editor.setPlainText(self.model[uid]['text']) @Slot() def update_text_in_model(self): uid = self.bar.current_uid() if not uid: return new_text = self.editor.toPlainText() # we check to see if the autosave has been reverted to its # previous state. modified = True if self.model.is_modified(uid): original_text = self.model.get_original_text(uid) if new_text == original_text: modified = False self.model.set_modified(uid, modified=modified) self.model[uid]['text'] = new_text text = self.get_path_or_name(uid) self.show_tab_status(uid) @Slot(uuid.UUID) def show_tab_status(self, uid, modified=False): text = self.get_path_or_name(uid) if self.model.is_modified(uid): text = 'Modified - %s' % text elif self.model[uid]['path'] and not self.model[uid]['saved']: # If the file was saved during the last session, # it will be set to "saved". If it was only opened, it will # also be set to saved. Only when the modified status is changed # will the save status be set to "False". text = 'File Modified - %s' % text self.statusbar.showMessage(text) def get_path_or_name(self, uid): path = self.model[uid]['path'] if path: return path return self.model[uid]['name'] @Slot() def preview_autosave(self): self.preview_editor = QPlainTextEdit() self.preview_editor.setFont(self.font()) JSONHighlighter(self.preview_editor.document()) text = self.model.to_json(indent=2) self.preview_editor.setPlainText(text) self.preview_editor.show() self.preview_editor.raise_()
def __init__(self): """ Brings together the data model (currently XMLModel), along with several views - Editor, TabView, ListView, and QDataWidgetMapper. """ super(PythonEditor, self).__init__() self.model = XMLModel() # create widgets self.tab_view = TabView() self.editor = Editor() self.editor.setFont(QFont('DejaVu Sans')) self.list_view = ListView() # self.list_view.setMaximumWidth(0) # self.list_view.resize(50, self.list_view.height()) self.listButton = QToolButton() self.listButton.setArrowType(Qt.DownArrow) self.listButton.setFixedSize(24, 24) # layout self.tab_widget = QWidget(self) tab_layout = QHBoxLayout(self.tab_widget) tab_layout.setContentsMargins(0,0,0,0) tab_layout.addWidget(self.tab_view) tab_layout.addWidget(self.listButton) self.bottom_splitter = QSplitter(Qt.Horizontal) self.bottom_splitter.addWidget(self.editor) self.bottom_splitter.addWidget(self.list_view) self.bottom_splitter.setSizes([300,20]) policy = QSizePolicy.Expanding self.bottom_splitter.setSizePolicy(policy, policy) self.terminal = terminal.Terminal() self.tabeditor = QWidget(self) bottom_layout = QVBoxLayout(self.tabeditor) bottom_layout.setContentsMargins(0,0,0,0) bottom_layout.addWidget(self.tab_widget) bottom_layout.addWidget(self.bottom_splitter) layout = QVBoxLayout(self) layout.setObjectName( 'PythonEditor_MainLayout' ) layout.setContentsMargins(0,0,0,0) layout.addWidget(self.tabeditor) self.setLayout(layout) splitter = QSplitter( Qt.Vertical ) splitter.setObjectName( 'PythonEditor_MainVerticalSplitter' ) splitter.addWidget(self.terminal) splitter.addWidget(self.tabeditor) layout.addWidget(splitter) self.splitter = splitter # act = actions.Actions( # pythoneditor=self, # editor=self.editor, # tabeditor=self.tabeditor, # terminal=self.terminal, # ) # sch = shortcuts.ShortcutHandler( # editor=self.editor, # tabeditor=self.tabeditor, # terminal=self.terminal, # ) # self.menubar = menubar.MenuBar(self) SE = shortcuteditor.ShortcutEditor self.shortcuteditor = SE( editor=self.editor, tabeditor=self.tabeditor, terminal=self.terminal ) PE = preferences.PreferencesEditor self.preferenceseditor = PE() # set model on views self.list_view.setModel(self.model) self.tab_view.setModel(self.model) # add model mapper self.mapper = QDataWidgetMapper(self) self.mapper.setModel(self.model) self.mapper.addMapping(self.editor, 1) # connect signals self.selection_model = self.list_view.selectionModel() self.selection_model.currentRowChanged.connect(self.mapper.setCurrentModelIndex) self.tab_view.currentChanged.connect(self.mapper.setCurrentIndex) self.tab_view.setSelectionModel(self.selection_model) self.editor.modificationChanged.connect(self.submit_and_refocus) self.mapper.currentIndexChanged.connect(self.tab_view.setCurrentIndex) self.mapper.currentIndexChanged.connect(self.setListIndex) self.model.row_moved.connect(self.tab_view.swap_tabs) self.listButton.clicked.connect(self.animate_listview) # get first item from model - this is where we would restore last viewed tab self.mapper.toFirst()
class PythonEditor(QWidget): def __init__(self): """ Brings together the data model (currently XMLModel), along with several views - Editor, TabView, ListView, and QDataWidgetMapper. """ super(PythonEditor, self).__init__() self.model = XMLModel() # create widgets self.tab_view = TabView() self.editor = Editor() self.editor.setFont(QFont('DejaVu Sans')) self.list_view = ListView() # self.list_view.setMaximumWidth(0) # self.list_view.resize(50, self.list_view.height()) self.listButton = QToolButton() self.listButton.setArrowType(Qt.DownArrow) self.listButton.setFixedSize(24, 24) # layout self.tab_widget = QWidget(self) tab_layout = QHBoxLayout(self.tab_widget) tab_layout.setContentsMargins(0,0,0,0) tab_layout.addWidget(self.tab_view) tab_layout.addWidget(self.listButton) self.bottom_splitter = QSplitter(Qt.Horizontal) self.bottom_splitter.addWidget(self.editor) self.bottom_splitter.addWidget(self.list_view) self.bottom_splitter.setSizes([300,20]) policy = QSizePolicy.Expanding self.bottom_splitter.setSizePolicy(policy, policy) self.terminal = terminal.Terminal() self.tabeditor = QWidget(self) bottom_layout = QVBoxLayout(self.tabeditor) bottom_layout.setContentsMargins(0,0,0,0) bottom_layout.addWidget(self.tab_widget) bottom_layout.addWidget(self.bottom_splitter) layout = QVBoxLayout(self) layout.setObjectName( 'PythonEditor_MainLayout' ) layout.setContentsMargins(0,0,0,0) layout.addWidget(self.tabeditor) self.setLayout(layout) splitter = QSplitter( Qt.Vertical ) splitter.setObjectName( 'PythonEditor_MainVerticalSplitter' ) splitter.addWidget(self.terminal) splitter.addWidget(self.tabeditor) layout.addWidget(splitter) self.splitter = splitter # act = actions.Actions( # pythoneditor=self, # editor=self.editor, # tabeditor=self.tabeditor, # terminal=self.terminal, # ) # sch = shortcuts.ShortcutHandler( # editor=self.editor, # tabeditor=self.tabeditor, # terminal=self.terminal, # ) # self.menubar = menubar.MenuBar(self) SE = shortcuteditor.ShortcutEditor self.shortcuteditor = SE( editor=self.editor, tabeditor=self.tabeditor, terminal=self.terminal ) PE = preferences.PreferencesEditor self.preferenceseditor = PE() # set model on views self.list_view.setModel(self.model) self.tab_view.setModel(self.model) # add model mapper self.mapper = QDataWidgetMapper(self) self.mapper.setModel(self.model) self.mapper.addMapping(self.editor, 1) # connect signals self.selection_model = self.list_view.selectionModel() self.selection_model.currentRowChanged.connect(self.mapper.setCurrentModelIndex) self.tab_view.currentChanged.connect(self.mapper.setCurrentIndex) self.tab_view.setSelectionModel(self.selection_model) self.editor.modificationChanged.connect(self.submit_and_refocus) self.mapper.currentIndexChanged.connect(self.tab_view.setCurrentIndex) self.mapper.currentIndexChanged.connect(self.setListIndex) self.model.row_moved.connect(self.tab_view.swap_tabs) self.listButton.clicked.connect(self.animate_listview) # get first item from model - this is where we would restore last viewed tab self.mapper.toFirst() # self.list_view.installEventFilter(self) # def eventFilter(self, obj, event): # print event.type() # return super(PythonEditor, self).eventFilter(obj, event) def animate_listview(self, start=0, end=100): anim = QPropertyAnimation( self.list_view, 'maximumWidth' ) self._anim = anim def release(): self.list_view.setMaximumWidth(2000) if self.list_view.maximumWidth() != 0: start, end = end, start self.listButton.setArrowType(Qt.DownArrow) else: self.listButton.setArrowType(Qt.RightArrow) anim.finished.connect(release) anim.setStartValue(start) anim.setEndValue(end) anim.setDuration(80) anim.start() @Slot() def submit_and_refocus(self): cursor = self.editor.textCursor() self.mapper.submit() self.editor.setTextCursor(cursor) @Slot(int) def setListIndex(self, row): index = self.model.index(row, 0) self.list_view.setCurrentIndex(index)