diff --git a/app/camera/buffer.py b/app/camera/buffer.py index da88cc3..cfc2212 100644 --- a/app/camera/buffer.py +++ b/app/camera/buffer.py @@ -24,7 +24,7 @@ from PyQt5.QtGui import QBrush from PyQt5.QtGui import QColor from PyQt5.QtMultimedia import QCameraInfo, QCamera, QCameraImageCapture from PyQt5.QtMultimediaWidgets import QGraphicsVideoItem -from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView +from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QFrame from PyQt5.QtWidgets import QWidget, QVBoxLayout from core.buffer import Buffer from pathlib import Path @@ -65,13 +65,13 @@ class CameraWidget(QWidget): self.graphics_view = QGraphicsView(self.scene) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) - self.graphics_view.setFrameStyle(0) - self.graphics_view.setStyleSheet("QGraphicsView {background: transparent; border: 3px; outline: none;}") + self.graphics_view.setFrameStyle(QFrame.NoFrame) self.graphics_view.scale(-1, 1) # this make live video from camero mirror. self.video_item = QGraphicsVideoItem() self.scene.addItem(self.video_item) self.layout = QVBoxLayout(self) + self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.graphics_view) diff --git a/app/git-viewer/buffer.py b/app/git-viewer/buffer.py new file mode 100644 index 0000000..4566129 --- /dev/null +++ b/app/git-viewer/buffer.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright (C) 2018 Andy Stewart +# +# Author: Andy Stewart +# Maintainer: Andy Stewart +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from PyQt5.QtGui import QColor, QFont +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel +from core.buffer import Buffer + +from pygit2 import Repository +from pygit2 import GIT_SORT_TOPOLOGICAL, GIT_SORT_REVERSE + +from datetime import datetime + +import json + +class AppBuffer(Buffer): + def __init__(self, buffer_id, url, config_dir, arguments, emacs_var_dict, module_path): + Buffer.__init__(self, buffer_id, url, arguments, emacs_var_dict, module_path, True) + + arguments_dict = json.loads(arguments) + + self.add_widget(GitViewerWidget(buffer_id, config_dir, arguments_dict["project-root"])) + +class GitViewerWidget(QWidget): + + def __init__(self, buffer_id, config_dir, project_root): + super(GitViewerWidget, self).__init__() + + repo = Repository(project_root) + commit_size = 0 + lastest_commit = None + for commit in repo.walk(repo.head.target, GIT_SORT_TOPOLOGICAL): + commit_size += 1 + + if not lastest_commit: + lastest_commit = commit + + remote_branch_size = 0 + for branch in repo.branches.remote: + if branch != "origin/HEAD" and branch != "origin/master": + remote_branch_size += 1 + + # Change background. + self.setStyleSheet("background-color: #000000"); + + # Add main box. + main_box = QVBoxLayout() + main_box.setSpacing(0) + main_box.setContentsMargins(0, 0, 0, 0) + + self.setLayout(main_box) + + # Add repo top area. + self.repo_top_font_size = 18 + self.repo_top_area = QWidget() + self.repo_top_layout = QVBoxLayout() + self.repo_top_layout.setSpacing(0) + self.repo_top_layout.setContentsMargins(30, 30, 30, 30) + self.repo_top_area.setLayout(self.repo_top_layout) + main_box.addWidget(self.repo_top_area) + + # Add repo title. + self.repo_title = QLabel(repo.path) + self.repo_title.setStyleSheet("QLabel {color: #E98123;}") + self.repo_title.setFont(QFont('Arial', 20)) + self.repo_top_layout.addWidget(self.repo_title) + + # Add summary info. + self.repo_summary_area = QWidget() + self.repo_summary_layout = QHBoxLayout() + self.repo_summary_layout.setSpacing(30) + self.repo_summary_layout.setContentsMargins(0, 0, 0, 0) + self.repo_summary_area.setLayout(self.repo_summary_layout) + self.repo_top_layout.addWidget(self.repo_summary_area) + + # Add head info. + self.head_info = QLabel("{} {} {}".format( + repo.head.shorthand, + str(remote_branch_size) + " branches", + str(commit_size) + " commits" + )) + self.head_info.setStyleSheet("QLabel {color: #C46C1D;}") + self.head_info.setFont(QFont('Arial', self.repo_top_font_size)) + self.repo_summary_layout.addWidget(self.head_info) + + self.repo_summary_layout.addStretch(1) + + # Add lastest commit info. + self.lastest_commit_area = QWidget() + self.lastest_commit_layout = QHBoxLayout() + self.lastest_commit_layout.setSpacing(30) + self.lastest_commit_layout.setContentsMargins(0, 30, 0, 30) + self.lastest_commit_area.setLayout(self.lastest_commit_layout) + self.repo_top_layout.addWidget(self.lastest_commit_area) + + self.lastest_commit_info = QLabel("Lastest: {} {}... {} {}".format( + lastest_commit.author.name, + lastest_commit.message.split("\n")[0][:40], + lastest_commit.hex[:7], + datetime.utcfromtimestamp(lastest_commit.author.time).strftime('%Y-%m-%d %H:%M:%S'))) + self.lastest_commit_info.setStyleSheet("QLabel {color: #6C6C6C;}") + self.lastest_commit_info.setFont(QFont('Arial', self.repo_top_font_size)) + self.lastest_commit_layout.addWidget(self.lastest_commit_info) + + self.lastest_commit_layout.addStretch(1) + + # Add commit status. + + # Add commit list. + + main_box.addStretch(1) diff --git a/core/buffer.py b/core/buffer.py index 698ee95..c6d7032 100755 --- a/core/buffer.py +++ b/core/buffer.py @@ -101,7 +101,7 @@ class Buffer(QGraphicsScene): update_buffer_details = QtCore.pyqtSignal(str, str, str) open_url_in_new_tab = QtCore.pyqtSignal(str) - duplicate_page_in_new_tab = QtCore.pyqtSignal(str) + duplicate_page_in_new_tab = QtCore.pyqtSignal(str) open_url_in_background_tab = QtCore.pyqtSignal(str) translate_text = QtCore.pyqtSignal(str) input_message = QtCore.pyqtSignal(str, str, str, str, str) @@ -125,7 +125,7 @@ class Buffer(QGraphicsScene): self.module_path = module_path self.fit_to_view = fit_to_view if emacs_var_dict["eaf-emacs-theme-mode"] == "dark": - self.background_color = QColor(233, 129, 35, 255) + self.background_color = QColor(0, 0, 0, 255) else: self.background_color = QColor(255, 255, 255, 255) self.setBackgroundBrush(QBrush(self.background_color)) diff --git a/core/view.py b/core/view.py index 83be46d..9f7148b 100644 --- a/core/view.py +++ b/core/view.py @@ -22,7 +22,7 @@ from PyQt5 import QtCore from PyQt5.QtCore import Qt, QEvent, QPoint from PyQt5.QtGui import QPainter, QWindow -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGraphicsView +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGraphicsView, QFrame class View(QWidget): @@ -50,14 +50,14 @@ class View(QWidget): # Build QGraphicsView. self.layout = QVBoxLayout(self) + self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.graphics_view = QGraphicsView(buffer, self) self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.graphics_view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing) # Remove damn border from QGraphicsView. - self.graphics_view.setFrameStyle(0) - self.graphics_view.setStyleSheet("QGraphicsView {background: transparent; border: 3px; outline: none;}") + self.graphics_view.setFrameStyle(QFrame.NoFrame) self.layout.addWidget(self.graphics_view) # NOTE: show function must start before resize to trigger *first* resizeEvent after show. diff --git a/eaf.el b/eaf.el index ba32ff2..06dd111 100644 --- a/eaf.el +++ b/eaf.el @@ -955,14 +955,14 @@ Return t or nil based on the result of the call." (defun eaf-call-async (method handler &rest args) "Call EAF Python process using `dbus-call-method-asynchronously' with METHOD, HANDLER and ARGS." (apply #'dbus-call-method-asynchronously - :session ; use the session (not system) bus - "com.lazycat.eaf" ; service name - "/com/lazycat/eaf" ; path name - "com.lazycat.eaf" ; interface name - method - handler - :timeout 1000000 - args)) + :session ; use the session (not system) bus + "com.lazycat.eaf" ; service name + "/com/lazycat/eaf" ; path name + "com.lazycat.eaf" ; interface name + method + handler + :timeout 1000000 + args)) (defun eaf-get-emacs-xid (frame) "Get emacs FRAME xid." @@ -1791,7 +1791,7 @@ This function works best if paired with a fuzzy search package." (if history-file-exists (mapcar (lambda (h) (when (string-match history-pattern h) - (format "[%s] ⇰ %s" (match-string 1 h) (match-string 2 h)))) + (format "[%s] ⇰ %s" (match-string 1 h) (match-string 2 h)))) (with-temp-buffer (insert-file-contents browser-history-file-path) (split-string (buffer-string) "\n" t))) nil))) @@ -1839,6 +1839,18 @@ choose a search engine defined in `eaf-browser-search-engines'" (interactive) (eaf-open "eaf-demo" "demo")) +;;;###autoload +(defun eaf-open-git-viewer () + "Open EAF git viewer." + (interactive) + (let ((args (make-hash-table :test 'equal)) + (project (project-current)) + (project-root-dir "")) + (when project + (setq project-root-dir (expand-file-name (cdr project)))) + (puthash "project-root" project-root-dir args) + (eaf-open "eaf-git-viewer" "git-viewer" (json-encode-hash-table args) t))) + ;;;###autoload (defun eaf-open-camera () "Open EAF camera application."