Deepin Editor 1.0 开发总结

前段时间把编辑器这个项目给接了过来,锻炼一下自己、练练手,经历了各种修修补补、增增删删的环节,刚看了一下 github,发现到如今我提交的 commit 也有 200+ 了…

《Deepin Editor 1.0 开发总结》 深度截图_选择区域_20181005232607.png

介绍

Deepin 为什么喜欢造轮子?主要是为了达到深度操作系统 用户界面 / 用户体验 大统一的目标,今年的最主要目标不是造轮子,而是往系统稳定性的方向发展,所以造轮子是副业;虽然目前深度编辑器在技术方面还秒杀不了 KDE 家的 kate 编辑器,这个后面会讲到,但是在 UI/UX 这方面我觉得可以秒杀它们。

深度编辑器定位就是简单易用、轻量级的编辑器,目标就是要替换 gedit,保持深度编辑器的 UI/UX 和深度家族整体设计语言保持一致,比如我最近一直在写博客,很多文章就是通过深度编辑器来写的;论坛里边很多用户说很少用到编辑器,也就偶尔修改配置文件和 TXT 文件的时候会用到,属于轻度使用;在编程写代码这方面环境来看,都有专属的 IDE (集成开发环境),所以用记事本来写代码的很少吧。

《Deepin Editor 1.0 开发总结》 主界面

顶部采用类似 Chrome 的标签栏设计,整体超窄边框显示,界面像深度终端那样简洁,不显示多余的东西,写作的沉浸感,带来了一种沉浸式的编辑体验。

多标签页设计支持将标签拖拽成窗口,或者将两个窗口拖拽到一个窗口里的另一个标签页。

《Deepin Editor 1.0 开发总结》 右键智能菜单

右键智能菜单足以替换传统编辑器的顶部菜单栏,右键菜单弹出时,如果文本已经有选择的区域,针对用户手动选择的文字进行:剪切、复制、粘贴、删除;如果没有选中状态,则临时高亮鼠标下的单词,针对光标下的单词进行:剪切、复制、粘贴、删除。

其他小功能

行号显示、查找关键字、替换关键字、只读模式下可以使用 Vim 快捷键进行字符移动操作,恩这些都是编辑器基本功能。

内置多套主题 UI,总有一款捕获你的心,实现一秒快速切换,适合善变的你。

在平时使用文件选择对话框来打开一些文件的时候,会出现一种重复选择目录的操作,这也是经常遇到的,因为每次打开都是选择 Home 目录里,这一个小细节我也是没办法忍的,所以实现了对上一次打开的目录进行保存,当你打开文件选择框的时候依旧是你上次打开文件夹目录。

支持默认快捷键定制。

在 Windows、MacOS、Linux 这三个不同的操作系统中,它们的换行符是不同的,Windows 是 \r\n,Linux 是 \n,MacOS是 \r,据说 MacOS 10.0 以上的版本是以 \n 为换行符,深度编辑器实现了在打开文件时候会自动侦测到文件的换行符,默认取第一行的换行符,当判断是某个操作系统时,在保存的时候会使用该换行符作为保存;保存对话框也提供了换行符的选项。

好了,非技术介绍就到这里了,下面才是主要内容。

架构设计

单进程多窗口设计理念

深度编辑器是一个单进程多窗口的应用程序,单进程多窗口就是无论打开多少个窗口,它只有一个独立的进程,没有因为创建一个新窗口就会增加一个进程,实现多窗口单进程很简单,也有很多种方式,比如深度文件管理器通过 QLocalSocket/QLocalServer 来实现;在这里深度编辑器采用 DBus 来进行进程间的通信,通过 QDBusConnection 连接到 Session Bus,并提供一个服务,如果发现已经有程序注册了该服务,那么就说明已经启动了一个进程不需要再单独启动一个进程,然后通过 QDBusInterface 访问 Service 来达到进程通信的目的。

窗口管理

既然是单进程多窗口模式,就不能在 main.cpp 里管理窗口创建/销毁了,保持 main 文件的代码简洁,所以就诞生了 StartManager 类,所有窗口创建都在这个类里边进行管理,同时把创建过的窗口指针保存在一个 QList 里。

窗口布局

《Deepin Editor 1.0 开发总结》 前端布局

用了差不多一年的 Qt GUI 库,对 Qt 布局也有大概的理解,其实 Qt 的布局理解起来还挺简单的,用起来确实比 Gtk+ 顺手多了;深度编辑器窗口布局大概就如上图所描述的,由于是多标签设计,Qt 提供了多页面切换布局:QStackedLayout,也有建立在 QStackedLayout 上的的便利类 QStackedWidget,主要是为了方便一些就用了 QStackedWidget,不用多 new 一个 QWidget,哈哈哈。

标签栏控件是用了 dtkwidget 里的 DTabBar,继承了 QTabBar,是 @zccrs 大神写的一个增强 QTabBar 功能的控件,所以基本用起来和 QTabBar 没多大区别,在功能上当然要比 QTabBar 强大许多,主要是满足深度编辑器的多标签设计需求:

  • 支持左右拖动(这个原生的已经支持)
  • 标签多的时候出现左右滚动箭头按钮
  • 可以支持向外 Drag and Drop 事件,以产生标签拖拽出窗口的效果
  • 新建标签栏按钮

EditWrapper 其实主要就是封装了左侧的行号控件 + Qt 编辑框控件 QPlainTextEdit,在 EditWrapper 类里做了 openFile()、saveFile() 相关操作,也就是在这个类做了打开文件、保存文件的代码,Window 类会调用到此相关的函数。

主题模块

《Deepin Editor 1.0 开发总结》 Model View 概览

把之前的 DSimpleListView 替换成了 QListView,使用 Qt 原生的 Model/View 架构,也就是模型、视图和委托,MV 架构可以将数据和界面代码分离,ThemeListModel 作为数据层,ThemeItemDelegate 是绘画代理层,ThemeListView 负责视图显示。

在创建 ThmeListModel 这个类的时候,它会自动加载所有主题资源文件,目录在 /usr/share/deepin-editor/themes ,这个是写死了路径,通过 QFileInfoList 对该目录进行遍历,加载里面所有主题文件进行数据存储,然后用背景颜色亮度进行排序。

主题文件以 .theme 为后缀,是一个以 json 为格式的文件。

编辑控件

使用的是 Qt 官方清一色的编辑控件 QPlainTextEdit,主要用于纯文本编辑和显示,因为天生缺陷,比如加载大文件的时候比较慢了,我也开始有点嫌弃它了,KDE 自己写了一套组件,完全是根据自己的标准来写的,界面显示内容全都是在一个 QAbstractScrollArea 里绘制,名叫 KTextEditor,其工程之大,真所谓鬼斧神工,是一个比 QPlainTextEdit 控件要厉害多了,大文件加载完全秒完成,而且高亮也不会卡 UI 线程。

研究了几天时间,也想过要造这个轮子,但是目前还写不出和 QPlainTextEdit 那种高度的水平,更不能说要秒杀 KTextEditor 了,那就先放一下了,这个时候想起了老王说的那句话:“很多时候技术上遇到瓶颈,千万不要放弃,先暂时放一下,灵感会随着你长时间的深入思考突然蹦出来的。”

至于为什么不用 KTextEditor ,这些依赖都不是盖的,哈哈哈。

《Deepin Editor 1.0 开发总结》 KTextEditor 依赖网

高亮实现

关于 Qt 语法高亮,Qt 官方文档有个很好的例子:Syntax Highlighter Example,QSyntaxHighlighter 允许自定义高亮规则,但是需要配合 QPlainTextEdit 来使用,如果未来自己实现一个编辑器控件的话,这个也是个问题。

《Deepin Editor 1.0 开发总结》 KSyntaxHighlighting 依赖网

使用了 KDE 的 KSyntaxHighlighting,它是一个 Qt 的高亮引擎库,在 QSyntaxHighlighter 类基础上进行开发的,Qt Creator 也在用这个库,目前支持 272 种语法高亮,也可以自己定制扩展:Working with Syntax Highlighting,这个项目几乎是 KDE 依赖最小的吧,看了一下确实只依赖了 Extra CMake Modules (ecm) …

Polkit 提权实现

待写。

最后

之前一位社区开发者 @sonichy 问我:右键打开文件的时候是怎么实现在标签页中打开呢?我大概知道是什么意思了,最近没有时间回复,在这里可以回答一下。双击打开文件的时候文件管理器会调用对应的软件,并且会加上当前打开的文件地址字符串作为参数传进来编辑器,然后使用 QDBusInterface 作为远程对象接口代理,通过 callWithArgumentList() 调用远程接口,这样就实现了不打开新窗口。

    原文作者:Rekols
    原文地址: https://www.jianshu.com/p/4ef013725392
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞