Example #1
0
	def __init__(self, urls, parent=None):
		KParts.MainWindow.__init__(self, parent)
		
		QWebSettings.globalSettings().setAttribute(
			QWebSettings.DeveloperExtrasEnabled, True)
		
		self.setWindowIcon(KIcon('text-editor'))
		
		self.kate = KTextEditor.EditorChooser.editor()
		self.editor = self.kate.createDocument(self).createView(self)
		doc = self.editor.document()
		self.editor.setContextMenu(self.editor.defaultContextMenu())
		
		sizegrip = create_grip(self.editor)
		sizegrip.show() #TODO: only show on windowstate change
		
		self.renderer = Renderer(self)
		
		@doc.textChanged.connect
		def _start_markdown(doc=None, old_range=None, new_range=None):
			"""Runs the renderer if it’s not currently rendering"""
			if not self.renderer.isRunning():
				self.renderer.start()
		
		@self.renderer.finished.connect
		def _stop_markdown():
			"""
			Replaces the preview HTML with the newly rendered one
			and restores the scroll position
			"""
			url = self.editor.document().url().resolved(QUrl('.'))
			self.preview.setHtml(self.renderer.html, url) #baseurl für extenes zeug
			self.preview.page().mainFrame().setScrollPosition(self.renderer.scrollpos)
		
		self.editor.document().documentNameChanged.connect(self.refresh_document)
		
		self.guiFactory().addClient(self.editor)
		self.setCentralWidget(self.editor)
		
		self.toolbar = KToolBar(i18n('Markdowner Toolbar'), self)
		self.toolbar.setWindowTitle(self.toolbar.objectName())
		self.preview_button = self.toolbar.addAction(KIcon('document-preview'), i18n('Show Preview'))
		self.preview_button.setCheckable(True)
		
		self.preview = QWebView()
		self.preview.settings().setUserStyleSheetUrl(base64css())
		self.preview.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
		self.preview.linkClicked.connect(self.intercept_link)
		
		with self.setup_dock(self.preview, i18n('Preview'), Qt.RightDockWidgetArea) as dock:
			page = self.preview.page()
			palette = page.palette()
			palette.setBrush(QPalette.Base, Qt.transparent)
			page.setPalette(palette)
			
			self.preview.setAttribute(Qt.WA_TranslucentBackground)
			self.preview.setAttribute(Qt.WA_OpaquePaintEvent, False)
			
			dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
			dock.visibilityChanged.connect(self.preview_button.setChecked)
			self.preview_button.triggered.connect(dock.setVisible)
		
		inspector = QWebInspector()
		with self.setup_dock(inspector, i18n('Inspector'), Qt.BottomDockWidgetArea) as dock:
			inspector.setPage(self.preview.page())
			dock.hide()
			inspect_action = self.preview.page().action(QWebPage.InspectElement)
			inspect_action.triggered.connect(dock.show)
		
		if len(urls) != 0:
			self.editor.document().openUrl(urls[0])
		
		#TODO: spellcheck
		self.setAutoSaveSettings()
		self.kate.readConfig(self.autoSaveConfigGroup().config())
Example #2
0
    def create_toolbar(self):

        self.toolbar = KToolBar(self, True, True)
        self.toolbar.setIconDimensions(16)
        self.toolbar.setAllowedAreas(QtCore.Qt.BottomToolBarArea)
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.addToolBar(QtCore.Qt.BottomToolBarArea, self.toolbar)

        self.toolbar.show()
        self.action_collection = KActionCollection(self)
        self.action_collection.addAssociatedWidget(self.toolbar)

        self.clear_live_action = self.action_collection.addAction(
            "clear_live_action")
        icon = QtGui.QIcon(":texter/images/edit-clear.png")
        self.clear_live_action.setIcon(icon)
        self.clear_live_action.setIconText("clear live")
        self.clear_live_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Q)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.save_live_action = self.action_collection.addAction(
            "save_live_action")
        icon = QtGui.QIcon(":texter/images/document-new.png")
        self.save_live_action.setIcon(icon)
        self.save_live_action.setIconText("save live")
        self.save_live_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_W)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.clear_preview_action = self.action_collection.addAction(
            "clear_preview_action")
        icon = QtGui.QIcon(":texter/images/edit-clear.png")
        self.clear_preview_action.setIcon(icon)
        self.clear_preview_action.setIconText("clear preview")
        self.clear_preview_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_A)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.save_preview_action = self.action_collection.addAction(
            "save_preview_action")
        icon = QtGui.QIcon(":texter/images/document-new.png")
        self.save_preview_action.setIcon(icon)
        self.save_preview_action.setIconText("save preview")
        self.save_preview_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_S)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.publish_action = self.action_collection.addAction(
            "publish_action")
        icon = QtGui.QIcon(":texter/images/edit-copy.png")
        self.publish_action.setIcon(icon)
        self.publish_action.setIconText("publish")
        self.publish_action.setShortcutConfigurable(True)
        self.publish_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT +
                                         QtCore.Qt.Key_Return)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.toolbar.insertSeparator(self.publish_action)

        self.auto_publish_action = KToggleAction(self.action_collection)
        self.action_collection.addAction("auto publish",
                                         self.auto_publish_action)
        icon = QtGui.QIcon(":texter/images/view-refresh.png")
        self.auto_publish_action.setIcon(icon)
        self.auto_publish_action.setObjectName("auto_publish_action")
        self.auto_publish_action.setIconText("auto publish")
        self.auto_publish_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_P)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.typer_animation_action = KToggleAction(self.action_collection)
        icon = QtGui.QIcon(":texter/images/media-playback-stop.png")
        self.typer_animation_action.setIcon(icon)
        self.typer_animation_action.setIconText("animate")
        self.typer_animation_action.setObjectName("typer_animation_action")
        self.typer_animation_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_M)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))
        self.action_collection.addAction("typer_animation_action",
                                         self.typer_animation_action)

        self.text_editor_action = self.action_collection.addAction(
            "text_editor_action")
        icon = QtGui.QIcon(":texter/images/document-open-data.png")
        self.text_editor_action.setIcon(icon)
        self.text_editor_action.setIconText("edit")
        self.text_editor_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_O)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.toolbar.insertSeparator(self.text_editor_action)

        self.save_action = self.action_collection.addAction("save_action")
        icon = QtGui.QIcon(":texter/images/document-save.png")
        self.save_action.setIcon(icon)
        self.save_action.setIconText("save")
        self.save_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_S)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.streaming_action = KToggleAction(self.action_collection)
        icon = QtGui.QIcon(":texter/images/media-record.png")
        self.streaming_action.setIcon(icon)
        self.streaming_action.setIconText("stream")
        self.streaming_action.setObjectName("stream")
        self.streaming_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_1)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))
        self.action_collection.addAction("stream", self.streaming_action)

        spacer = KToolBarSpacerAction(self.action_collection)
        self.action_collection.addAction("1_spacer", spacer)

        self.previous_action = self.action_collection.addAction(
            "previous_action")
        icon = QtGui.QIcon(":texter/images/go-previous-view-page.png")
        self.previous_action.setIcon(icon)
        self.previous_action.setIconText("previous")
        self.previous_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Left)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.text_combo = KSelectAction(self.action_collection)
        self.text_combo.setEditable(False)
        icon = QtGui.QIcon(":texter/images/document-open-recent.png")
        self.text_combo.setIcon(icon)
        self.text_combo.setIconText("saved texts")
        self.text_combo.setObjectName("text_combo")
        self.action_collection.addAction("saved texts", self.text_combo)

        self.next_action = self.action_collection.addAction("next_action")
        icon = QtGui.QIcon(":texter/images/go-next-view-page.png")
        self.next_action.setIcon(icon)
        self.next_action.setIconText("next")
        self.next_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Right)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.toolbar.addSeparator()

        self.save_action.triggered.connect(self.slot_save)

        self.publish_action.triggered.connect(self.slot_publish)
        self.clear_live_action.triggered.connect(self.slot_clear_live)
        self.clear_preview_action.triggered.connect(self.slot_clear_preview)
        self.text_combo.triggered[int].connect(self.slot_load_preview_text)
        self.text_editor_action.triggered.connect(self.slot_open_dialog)
        self.save_live_action.triggered.connect(self.slot_save_live_text)
        self.save_preview_action.triggered.connect(self.slot_save_preview_text)
        self.streaming_action.triggered.connect(self.slot_toggle_streaming)
        self.auto_publish_action.toggled.connect(self.slot_auto_publish)
        self.typer_animation_action.toggled.connect(self.slot_toggle_animation)
        self.preview_size_action.triggered[QtGui.QAction].connect(
            self.slot_preview_font_size)
        self.live_size_action.triggered[QtGui.QAction].connect(
            self.slot_live_font_size)

        self.next_action.triggered.connect(self.slot_next_item)
        self.previous_action.triggered.connect(self.slot_previous_item)
        self.streaming_action.setChecked(True)
Example #3
0
class Markdowner(KParts.MainWindow):
	"""Main Editor window"""
	def __init__(self, urls, parent=None):
		KParts.MainWindow.__init__(self, parent)
		
		QWebSettings.globalSettings().setAttribute(
			QWebSettings.DeveloperExtrasEnabled, True)
		
		self.setWindowIcon(KIcon('text-editor'))
		
		self.kate = KTextEditor.EditorChooser.editor()
		self.editor = self.kate.createDocument(self).createView(self)
		doc = self.editor.document()
		self.editor.setContextMenu(self.editor.defaultContextMenu())
		
		sizegrip = create_grip(self.editor)
		sizegrip.show() #TODO: only show on windowstate change
		
		self.renderer = Renderer(self)
		
		@doc.textChanged.connect
		def _start_markdown(doc=None, old_range=None, new_range=None):
			"""Runs the renderer if it’s not currently rendering"""
			if not self.renderer.isRunning():
				self.renderer.start()
		
		@self.renderer.finished.connect
		def _stop_markdown():
			"""
			Replaces the preview HTML with the newly rendered one
			and restores the scroll position
			"""
			url = self.editor.document().url().resolved(QUrl('.'))
			self.preview.setHtml(self.renderer.html, url) #baseurl für extenes zeug
			self.preview.page().mainFrame().setScrollPosition(self.renderer.scrollpos)
		
		self.editor.document().documentNameChanged.connect(self.refresh_document)
		
		self.guiFactory().addClient(self.editor)
		self.setCentralWidget(self.editor)
		
		self.toolbar = KToolBar(i18n('Markdowner Toolbar'), self)
		self.toolbar.setWindowTitle(self.toolbar.objectName())
		self.preview_button = self.toolbar.addAction(KIcon('document-preview'), i18n('Show Preview'))
		self.preview_button.setCheckable(True)
		
		self.preview = QWebView()
		self.preview.settings().setUserStyleSheetUrl(base64css())
		self.preview.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
		self.preview.linkClicked.connect(self.intercept_link)
		
		with self.setup_dock(self.preview, i18n('Preview'), Qt.RightDockWidgetArea) as dock:
			page = self.preview.page()
			palette = page.palette()
			palette.setBrush(QPalette.Base, Qt.transparent)
			page.setPalette(palette)
			
			self.preview.setAttribute(Qt.WA_TranslucentBackground)
			self.preview.setAttribute(Qt.WA_OpaquePaintEvent, False)
			
			dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
			dock.visibilityChanged.connect(self.preview_button.setChecked)
			self.preview_button.triggered.connect(dock.setVisible)
		
		inspector = QWebInspector()
		with self.setup_dock(inspector, i18n('Inspector'), Qt.BottomDockWidgetArea) as dock:
			inspector.setPage(self.preview.page())
			dock.hide()
			inspect_action = self.preview.page().action(QWebPage.InspectElement)
			inspect_action.triggered.connect(dock.show)
		
		if len(urls) != 0:
			self.editor.document().openUrl(urls[0])
		
		#TODO: spellcheck
		self.setAutoSaveSettings()
		self.kate.readConfig(self.autoSaveConfigGroup().config())
	
	@property
	def format(self):
		"""Gets the format from the corrent document’s file extension"""
		path = self.editor.document().url().path()
		ext = path[path.rfind('.') + 1:]
		return FORMATS[ext]
	
	def queryClose(self):
		"""
		Gets invoked by Qt if the window is about to be closed
		Returns True if it is allowed to close
		"""
		self.kate.writeConfig(self.autoSaveConfigGroup().config())
		
		if self.editor.document().isModified():
			ret = KMessageBox.warningYesNoCancel(self,
				i18n('Save changes to document?'))
			if ret == KMessageBox.Yes:
				return self.editor.document().documentSave()
			else:
				return ret == KMessageBox.No
		else:
			return True
	
	@Slot(QUrl)
	def intercept_link(self, url):
		"""Allows to open documents or scrolling to anchors when clicking links"""
		#reenable scrolling to anchor in document
		if url.hasFragment() and url.scheme() == 'about' and url.path() == 'blank':
			self.preview.page().currentFrame().scrollToAnchor(url.fragment())
		elif url.isRelative() and self.queryExit():
			#TODO: less hacky, extensions
			url = KUrl(self.editor.document().url().path() + url.path())
			self.editor.document().openUrl(url)
		else:
			QDesktopServices.openUrl(url)
	
	@Slot(KTextEditor.Document)
	def refresh_document(self, doc):
		"""Sets the necessary bits if a new document is loaded"""
		self.setWindowTitle('{} – {}'.format(
			doc.documentName(),
			ABOUT.programName()
		))
		doc.setMode(self.format.name)
	
	@contextmanager
	def setup_dock(self, widget, name, area):
		"""Helps to setup docks more semantically"""
		dock = QDockWidget(name, self)
		dock.setObjectName(name)
		
		yield dock
		
		self.addDockWidget(area, dock)
		dock.setWidget(widget)
Example #4
0
class MainWindow(KMainWindow, Ui_MainWindow, MjpegStreamingConsumerInterface):
    def __init__(self, args, parent=None):
        self.args = args
        #super(MainWindow, self).__init__()
        #PsyQtClientBase.__init__(self)
        KMainWindow.__init__(self, parent)
        self.is_streaming = False

        self.live_center_action = None
        self.preview_center_action = None
        self.live_size_action = None
        self.preview_font_action = None
        self.live_font_action = None
        self.preview_size_action = None
        self.default_size = 28
        self.default_align_text = "format_align_center"
        self.preview_actions = list()
        self.live_actions = list()
        self.current = 0
        self.model = TextModel(self)
        self.animation = TextAnimation(self)
        self.db_dirty = False
        self.is_animate = False
        self.fade_animation = None
        self.dialog = None
        self.current_object = None
        self.current_index = -1

        self.is_auto_publish = False

        self.setupUi(self)
        self.win_id = self.live_text.winId()

        self.fps = 12.5
        self.http_server = MjpegStreamingServer(
            (args.http_host, args.http_port), self, self.fps)

        self.live_text.setLineWrapMode(
            QtGui.QTextEdit.LineWrapMode(QtGui.QTextEdit.FixedPixelWidth))
        self.live_text.setLineWrapColumnOrWidth(768)

        self.font = QtGui.QFont("monospace", self.default_size)
        self.font.setStyleHint(QtGui.QFont.TypeWriter)

        self.previous_action = None
        self.next_action = None
        self.publish_action = None
        self.auto_publish_action = None
        self.save_live_action = None
        self.save_preview_action = None
        self.save_action = None
        self.dialog_widget = None
        self.action_collection = None
        self.streaming_action = None
        self.text_combo = None
        self.clear_live_action = None
        self.clear_preview_action = None
        self.toolbar = None
        self.typer_animation_action = None
        self.text_editor_action = None

        self.preview_text.setFont(self.font)
        self.preview_text.setRichTextSupport(
            KRichTextWidget.RichTextSupport(0xffffffff))
        self.preview_editor_collection = KActionCollection(self)
        self.preview_text.createActions(self.preview_editor_collection)

        self.live_text.setRichTextSupport(
            KRichTextWidget.RichTextSupport(0xffffffff))
        self.live_text.setFont(self.font)
        self.live_editor_collection = KActionCollection(self)
        self.live_text.createActions(self.live_editor_collection)
        self.filter_editor_actions()
        self.create_toolbar()
        self.slot_load()

        qtapp.focusChanged.connect(self.focusChanged)
        self.start_streaming()

        self.show()
        timer = QtCore.QTimer()
        timer.start(2000)
        timer.timeout.connect(lambda: None)

    def pubdir(self):
        return os.path.dirname(os.path.abspath(__file__))

    def getPreviewCoords(self):
        public_rect = self.preview_text.geometry()
        global_rect = QtCore.QRect(self.mapToGlobal(public_rect.topLeft()),
                                   self.mapToGlobal(public_rect.bottomRight()))
        return global_rect.x(), global_rect.y()

    def render_image(self):
        public_rect = self.live_text_rect()
        #global_rect = QtCore.QRect(self.mapToGlobal(public_rect.topLeft()), self.mapToGlobal(public_rect.bottomRight()))
        pixmap = QPixmap.grabWindow(self.win_id,
                                    public_rect.x() + 1,
                                    public_rect.y() + 1, 768, 576)
        buf = QBuffer()
        buf.open(QIODevice.WriteOnly)
        pixmap.save(buf, "JPG", 75)
        return buf.data()

    def filter_editor_actions(self):
        disabled_action_names = [
            "action_to_plain_text", "format_painter", "direction_ltr",
            "direction_rtl", "format_font_family",
            "format_text_background_color", "format_list_style",
            "format_list_indent_more", "format_list_indent_less",
            "format_text_bold", "format_text_underline",
            "format_text_strikeout", "format_text_italic",
            "format_align_right", "manage_link", "format_text_subscript",
            "format_text_superscript", "insert_horizontal_rule"
        ]

        for action in self.live_editor_collection.actions():
            text = str(action.objectName())
            if text in disabled_action_names:
                action.setVisible(False)

            if text == self.default_align_text:
                self.live_center_action = action
            elif text == "format_font_size":
                self.live_size_action = action
            elif text == "format_font_family":
                self.live_font_action = action

        for action in self.preview_editor_collection.actions():
            text = str(action.objectName())
            if text in disabled_action_names:
                action.setVisible(False)

            if text == self.default_align_text:
                self.preview_center_action = action
            elif text == "format_font_size":
                self.preview_size_action = action
            elif text == "format_font_family":
                self.preview_font_action = action

        self.slot_set_preview_defaults()
        self.slot_set_live_defaults()

    def create_toolbar(self):

        self.toolbar = KToolBar(self, True, True)
        self.toolbar.setIconDimensions(16)
        self.toolbar.setAllowedAreas(QtCore.Qt.BottomToolBarArea)
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.addToolBar(QtCore.Qt.BottomToolBarArea, self.toolbar)

        self.toolbar.show()
        self.action_collection = KActionCollection(self)
        self.action_collection.addAssociatedWidget(self.toolbar)

        self.clear_live_action = self.action_collection.addAction(
            "clear_live_action")
        icon = QtGui.QIcon(":texter/images/edit-clear.png")
        self.clear_live_action.setIcon(icon)
        self.clear_live_action.setIconText("clear live")
        self.clear_live_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Q)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.save_live_action = self.action_collection.addAction(
            "save_live_action")
        icon = QtGui.QIcon(":texter/images/document-new.png")
        self.save_live_action.setIcon(icon)
        self.save_live_action.setIconText("save live")
        self.save_live_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_W)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.clear_preview_action = self.action_collection.addAction(
            "clear_preview_action")
        icon = QtGui.QIcon(":texter/images/edit-clear.png")
        self.clear_preview_action.setIcon(icon)
        self.clear_preview_action.setIconText("clear preview")
        self.clear_preview_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_A)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.save_preview_action = self.action_collection.addAction(
            "save_preview_action")
        icon = QtGui.QIcon(":texter/images/document-new.png")
        self.save_preview_action.setIcon(icon)
        self.save_preview_action.setIconText("save preview")
        self.save_preview_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_S)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.publish_action = self.action_collection.addAction(
            "publish_action")
        icon = QtGui.QIcon(":texter/images/edit-copy.png")
        self.publish_action.setIcon(icon)
        self.publish_action.setIconText("publish")
        self.publish_action.setShortcutConfigurable(True)
        self.publish_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT +
                                         QtCore.Qt.Key_Return)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.toolbar.insertSeparator(self.publish_action)

        self.auto_publish_action = KToggleAction(self.action_collection)
        self.action_collection.addAction("auto publish",
                                         self.auto_publish_action)
        icon = QtGui.QIcon(":texter/images/view-refresh.png")
        self.auto_publish_action.setIcon(icon)
        self.auto_publish_action.setObjectName("auto_publish_action")
        self.auto_publish_action.setIconText("auto publish")
        self.auto_publish_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_P)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.typer_animation_action = KToggleAction(self.action_collection)
        icon = QtGui.QIcon(":texter/images/media-playback-stop.png")
        self.typer_animation_action.setIcon(icon)
        self.typer_animation_action.setIconText("animate")
        self.typer_animation_action.setObjectName("typer_animation_action")
        self.typer_animation_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_M)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))
        self.action_collection.addAction("typer_animation_action",
                                         self.typer_animation_action)

        self.text_editor_action = self.action_collection.addAction(
            "text_editor_action")
        icon = QtGui.QIcon(":texter/images/document-open-data.png")
        self.text_editor_action.setIcon(icon)
        self.text_editor_action.setIconText("edit")
        self.text_editor_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_O)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.toolbar.insertSeparator(self.text_editor_action)

        self.save_action = self.action_collection.addAction("save_action")
        icon = QtGui.QIcon(":texter/images/document-save.png")
        self.save_action.setIcon(icon)
        self.save_action.setIconText("save")
        self.save_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_S)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.streaming_action = KToggleAction(self.action_collection)
        icon = QtGui.QIcon(":texter/images/media-record.png")
        self.streaming_action.setIcon(icon)
        self.streaming_action.setIconText("stream")
        self.streaming_action.setObjectName("stream")
        self.streaming_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_1)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))
        self.action_collection.addAction("stream", self.streaming_action)

        spacer = KToolBarSpacerAction(self.action_collection)
        self.action_collection.addAction("1_spacer", spacer)

        self.previous_action = self.action_collection.addAction(
            "previous_action")
        icon = QtGui.QIcon(":texter/images/go-previous-view-page.png")
        self.previous_action.setIcon(icon)
        self.previous_action.setIconText("previous")
        self.previous_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Left)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.text_combo = KSelectAction(self.action_collection)
        self.text_combo.setEditable(False)
        icon = QtGui.QIcon(":texter/images/document-open-recent.png")
        self.text_combo.setIcon(icon)
        self.text_combo.setIconText("saved texts")
        self.text_combo.setObjectName("text_combo")
        self.action_collection.addAction("saved texts", self.text_combo)

        self.next_action = self.action_collection.addAction("next_action")
        icon = QtGui.QIcon(":texter/images/go-next-view-page.png")
        self.next_action.setIcon(icon)
        self.next_action.setIconText("next")
        self.next_action.setShortcut(
            KShortcut(QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_Right)),
            KAction.ShortcutTypes(KAction.ActiveShortcut
                                  | KAction.DefaultShortcut))

        self.toolbar.addSeparator()

        self.save_action.triggered.connect(self.slot_save)

        self.publish_action.triggered.connect(self.slot_publish)
        self.clear_live_action.triggered.connect(self.slot_clear_live)
        self.clear_preview_action.triggered.connect(self.slot_clear_preview)
        self.text_combo.triggered[int].connect(self.slot_load_preview_text)
        self.text_editor_action.triggered.connect(self.slot_open_dialog)
        self.save_live_action.triggered.connect(self.slot_save_live_text)
        self.save_preview_action.triggered.connect(self.slot_save_preview_text)
        self.streaming_action.triggered.connect(self.slot_toggle_streaming)
        self.auto_publish_action.toggled.connect(self.slot_auto_publish)
        self.typer_animation_action.toggled.connect(self.slot_toggle_animation)
        self.preview_size_action.triggered[QtGui.QAction].connect(
            self.slot_preview_font_size)
        self.live_size_action.triggered[QtGui.QAction].connect(
            self.slot_live_font_size)

        self.next_action.triggered.connect(self.slot_next_item)
        self.previous_action.triggered.connect(self.slot_previous_item)
        self.streaming_action.setChecked(True)

    def closeEvent(self, event):
        logger.info("closeEvent")
        if self.db_dirty:
            self.dialog = KDialog(self)
            self.dialog.setCaption("4.48 texter - text db not saved")
            label = QtGui.QLabel(
                "The Text database is not saved. Do you want to save before exit?",
                self.dialog)
            self.dialog.setMainWidget(label)
            self.dialog.setButtons(
                KDialog.ButtonCodes(KDialog.Ok | KDialog.Cancel))
            self.dialog.okClicked.connect(self.slot_save)
            self.dialog.exec_()
        event.accept()

    def live_text_rect(self):
        return self.live_text.geometry()

    def stop_streaming(self):
        self.is_streaming = False
        self.http_server.stop()

    def start_streaming(self):
        self.http_server.listen(port=self.args.http_port)
        self.is_streaming = True

    def fill_combo_box(self):
        if self.dialog is not None:
            self.dialog.deleteLater()
            self.dialog = None

        self.text_combo.clear()
        current_row = -1
        for index, list_obj in enumerate(self.model.text_db):
            preview, text = list_obj
            self.text_combo.addAction(preview)
            if list_obj == self.current_object:
                current_row = index

        if current_row == -1:
            current_row = self.current_index
            self.slot_load_preview_text(current_row)
        self.text_combo.setCurrentItem(current_row)

    def focusChanged(self, old, new):
        if new == self.preview_text:
            self.live_editor_collection.clearAssociatedWidgets()
            self.preview_editor_collection.addAssociatedWidget(self.toolbar)
        elif new == self.live_text:
            self.preview_editor_collection.clearAssociatedWidgets()
            self.live_editor_collection.addAssociatedWidget(self.toolbar)

    def slot_auto_publish(self, state):
        self.is_auto_publish = bool(state)

    def slot_toggle_animation(self, state):
        self.is_animate = bool(state)

    def slot_toggle_streaming(self):
        if self.is_streaming:
            self.stop_streaming()
        else:
            self.start_streaming()

    def slot_next_item(self):
        try:
            self.current = (self.text_combo.currentItem() + 1) % len(
                self.model.text_db)
            self.text_combo.setCurrentItem(self.current)
            self.slot_load_preview_text(self.current)
        except ZeroDivisionError:
            pass

    def slot_previous_item(self):
        try:
            self.current = (self.text_combo.currentItem() - 1) % len(
                self.model.text_db)
            self.text_combo.setCurrentItem(self.current)
            self.slot_load_preview_text(self.current)
        except ZeroDivisionError:
            pass

    def slot_publish(self):
        if self.is_animate:
            self.animation.start_animation(self.preview_text, self.live_text,
                                           0)
        else:
            self.live_text.setTextOrHtml(self.preview_text.textOrHtml())

    def slot_live_font_size(self, action):
        self.default_size = self.live_size_action.fontSize()
        self.slot_set_preview_defaults()
        self.slot_set_live_defaults()

    def slot_preview_font_size(self, action):
        self.default_size = self.preview_size_action.fontSize()
        self.slot_set_live_defaults()
        self.slot_set_preview_defaults()

    def slot_toggle_publish(self, state=None):

        if state:
            self.slot_publish()
        else:
            self.slot_clear_live()

    def slot_set_preview_defaults(self):
        self.preview_center_action.setChecked(True)
        self.preview_text.alignCenter()
        self.font.setPointSize(self.default_size)
        self.preview_text.setFontSize(self.default_size)
        self.preview_text.setFont(self.font)
        self.preview_size_action.setFontSize(self.default_size)
        self.preview_text.document().setDefaultFont(self.font)

    def slot_set_live_defaults(self):
        self.live_center_action.setChecked(True)
        self.live_text.alignCenter()
        self.live_text.setFontSize(self.default_size)
        self.live_size_action.setFontSize(self.default_size)
        self.live_text.document().setDefaultFont(self.font)

    def slot_clear_live(self):
        self.live_text.clear()
        self.slot_set_live_defaults()

    def slot_clear_preview(self):
        self.preview_text.clear()
        self.slot_set_preview_defaults()

    def slot_fade(self):
        if self.fade_animation.timer is None:
            self.fade_animation.start_animation()

    def slot_load_preview_text(self, index):
        try:
            preview, text = self.model.text_db[index]
        except IndexError:
            return
        self.preview_text.setTextOrHtml(text)
        if self.is_auto_publish:
            self.slot_publish()

    def slot_save_live_text(self):
        text = self.live_text.toHtml()
        preview = get_preview_text(unicode(self.live_text.toPlainText()))
        if not preview:
            return
        old_item = self.model.text_by_preview(preview)
        if old_item is not None:
            suffix = 1
            while 1:
                tmp_preview = "%s_%d" % (preview, suffix)
                tmp = self.model.text_by_preview(tmp_preview)
                if tmp is None:
                    preview = tmp_preview
                    break
                else:
                    suffix += 1

        self.model.text_db.append([preview, text])
        self.model.modelReset.emit()
        action = self.text_combo.addAction(preview)
        self.text_combo.setCurrentAction(action)
        self.db_dirty = True

    def slot_save_preview_text(self):
        text = self.preview_text.toHtml()
        preview = get_preview_text(unicode(self.preview_text.toPlainText()))

        if not preview:
            return
        old_item = self.model.text_by_preview(preview)
        if old_item is not None:
            ix, old_preview, old_text = old_item
            self.model.text_db[ix][1] = text
        else:
            self.model.text_db.append([preview, text])
            action = self.text_combo.addAction(preview)
            self.model.modelReset.emit()
            self.text_combo.setCurrentAction(action)
        self.db_dirty = True

    def slot_save(self):
        path = os.path.expanduser("~/.texter")
        if not os.path.isdir(path):
            os.mkdir(path)
        try:
            f = open(os.path.join(path, "texter.db"), "w")
        except IOError:
            return
        else:
            cPickle.dump(self.model.text_db, f, cPickle.HIGHEST_PROTOCOL)
        self.db_dirty = False

    def slot_open_dialog(self):
        self.current_index = self.text_combo.currentItem()
        self.current_object = self.model.text_db[self.current_index]
        if self.dialog is not None:
            self.dialog.deleteLater()
            self.dialog = None

        self.dialog = KDialog(self)
        self.dialog.setButtons(KDialog.Close)
        self.dialog_widget = EditDialog(self.dialog)
        self.dialog.setMainWidget(self.dialog_widget)
        pos_x, pos_y = self.getPreviewCoords()
        self.dialog.move(pos_x, self.pos().y())
        self.dialog.exec_()
        self.fill_combo_box()

    def slot_load(self):
        path = os.path.expanduser("~/.texter")
        if not os.path.isdir(path):
            os.mkdir(path)
        try:
            db_file = open(os.path.join(path, "texter.db"))
        except IOError:
            return

        try:
            self.model.text_db = [list(i) for i in cPickle.load(db_file)]
        except ValueError, error:
            logger.exception(error)

        self.fill_combo_box()
        self.text_combo.setCurrentItem(0)
        self.slot_load_preview_text(0)